@rebasepro/studio 0.7.0 → 0.9.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 (38) hide show
  1. package/README.md +1 -1
  2. package/dist/{JSEditor-DSucz6wV.js → JSEditor-Sgmw1SHC.js} +28 -32
  3. package/dist/JSEditor-Sgmw1SHC.js.map +1 -0
  4. package/dist/{RLSEditor-BM64laoW.js → RLSEditor-DPhky8XW.js} +8 -18
  5. package/dist/RLSEditor-DPhky8XW.js.map +1 -0
  6. package/dist/{SQLEditor-CuAhR-zr.js → SQLEditor-CgR2hlUI.js} +5 -5
  7. package/dist/SQLEditor-CgR2hlUI.js.map +1 -0
  8. package/dist/{SchemaVisualizer-OibKoD3g.js → SchemaVisualizer-WK4ZZR5X.js} +9 -9
  9. package/dist/SchemaVisualizer-WK4ZZR5X.js.map +1 -0
  10. package/dist/{StorageView-CvrnHmDG.js → StorageView-BMhD29YO.js} +33 -5
  11. package/dist/StorageView-BMhD29YO.js.map +1 -0
  12. package/dist/components/SchemaVisualizer/useSchemaGraph.d.ts +2 -2
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.es.js +110 -82
  15. package/dist/index.es.js.map +1 -1
  16. package/dist/index.umd.js +174 -133
  17. package/dist/index.umd.js.map +1 -1
  18. package/dist/utils/pgColumnToProperty.d.ts +3 -3
  19. package/dist/utils/sql_utils.d.ts +3 -3
  20. package/package.json +17 -17
  21. package/src/components/JSEditor/JSEditor.tsx +7 -7
  22. package/src/components/JSEditor/JSMonacoEditor.tsx +23 -27
  23. package/src/components/RLSEditor/RLSEditor.tsx +18 -31
  24. package/src/components/SQLEditor/SQLEditor.tsx +4 -4
  25. package/src/components/SchemaVisualizer/SchemaVisualizer.tsx +7 -7
  26. package/src/components/SchemaVisualizer/useSchemaGraph.ts +11 -11
  27. package/src/components/StorageView/StorageView.tsx +43 -4
  28. package/src/components/StudioHomePage.tsx +139 -84
  29. package/src/index.ts +1 -1
  30. package/src/utils/pgColumnToProperty.ts +4 -4
  31. package/src/utils/sql_utils.test.ts +6 -6
  32. package/src/utils/sql_utils.ts +3 -3
  33. package/dist/JSEditor-DSucz6wV.js.map +0 -1
  34. package/dist/RLSEditor-BM64laoW.js.map +0 -1
  35. package/dist/SQLEditor-CuAhR-zr.js.map +0 -1
  36. package/dist/SchemaVisualizer-OibKoD3g.js.map +0 -1
  37. package/dist/StorageView-CvrnHmDG.js.map +0 -1
  38. package/src/vite-env.d.ts +0 -1
package/dist/index.es.js CHANGED
@@ -1,14 +1,12 @@
1
- import { IconForView, SchemaDriftBanner, StudioBridgeContext, StudioBridgeProvider, useRebaseContext, useRebaseRegistryDispatch, useRestoreScroll, useSlot, useStudioBreadcrumbs, useStudioBreadcrumbs as useStudioBreadcrumbs$1, useStudioCollectionRegistry, useStudioNavigationState, useStudioSideEntityController, useStudioUrlController } from "@rebasepro/core";
2
- import React, { Suspense, lazy, useEffect, useLayoutEffect, useMemo } from "react";
3
- import { ArrowRightIcon, Card, CircularProgressCenter, Container, Typography, cls, iconSize } from "@rebasepro/ui";
1
+ import { IconForView, SchemaDriftBanner, StudioBridgeContext, StudioBridgeProvider, useRebaseContext, useRebaseRegistryDispatch, useRestoreScroll, useSlot, useStudioBreadcrumbs, useStudioBreadcrumbs as useStudioBreadcrumbs$1, useStudioCollectionRegistry, useStudioNavigationState, useStudioSidePanelController, useStudioUrlController } from "@rebasepro/core";
2
+ import React, { Suspense, lazy, useEffect, useLayoutEffect, useMemo, useState } from "react";
3
+ import { Card, CircularProgressCenter, Container, ExpandablePanel, Typography, cls } from "@rebasepro/ui";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  import { useNavigate } from "react-router-dom";
6
6
  //#region src/components/StudioHomePage.tsx
7
7
  var SECTIONS = [
8
8
  {
9
9
  label: "Database",
10
- dotColor: "bg-emerald-400",
11
- iconColor: "text-emerald-400",
12
10
  tools: [
13
11
  {
14
12
  path: "/schema",
@@ -50,8 +48,6 @@ var SECTIONS = [
50
48
  },
51
49
  {
52
50
  label: "Compute",
53
- dotColor: "bg-blue-400",
54
- iconColor: "text-blue-400",
55
51
  tools: [{
56
52
  path: "/js",
57
53
  name: "JS Console",
@@ -66,8 +62,6 @@ var SECTIONS = [
66
62
  },
67
63
  {
68
64
  label: "API",
69
- dotColor: "bg-violet-400",
70
- iconColor: "text-violet-400",
71
65
  tools: [{
72
66
  path: "/api",
73
67
  name: "API Explorer",
@@ -77,8 +71,6 @@ var SECTIONS = [
77
71
  },
78
72
  {
79
73
  label: "Storage",
80
- dotColor: "bg-amber-400",
81
- iconColor: "text-amber-400",
82
74
  tools: [{
83
75
  path: "/storage",
84
76
  name: "Storage",
@@ -88,8 +80,6 @@ var SECTIONS = [
88
80
  },
89
81
  {
90
82
  label: "Access Control",
91
- dotColor: "bg-rose-400",
92
- iconColor: "text-rose-400",
93
83
  tools: [
94
84
  {
95
85
  path: "/users",
@@ -112,6 +102,33 @@ var SECTIONS = [
112
102
  ]
113
103
  }
114
104
  ];
105
+ var COLLAPSED_STORAGE_KEY = "rebase-studio-home-collapsed";
106
+ function useStudioCollapsedGroups(groupNames) {
107
+ const [collapsed, setCollapsed] = useState(() => {
108
+ try {
109
+ const stored = localStorage.getItem(COLLAPSED_STORAGE_KEY);
110
+ return stored ? new Set(JSON.parse(stored)) : /* @__PURE__ */ new Set();
111
+ } catch {
112
+ return /* @__PURE__ */ new Set();
113
+ }
114
+ });
115
+ const isGroupCollapsed = (name) => collapsed.has(name);
116
+ const toggleGroupCollapsed = (name) => {
117
+ setCollapsed((prev) => {
118
+ const next = new Set(prev);
119
+ if (next.has(name)) next.delete(name);
120
+ else next.add(name);
121
+ try {
122
+ localStorage.setItem(COLLAPSED_STORAGE_KEY, JSON.stringify([...next]));
123
+ } catch {}
124
+ return next;
125
+ });
126
+ };
127
+ return {
128
+ isGroupCollapsed,
129
+ toggleGroupCollapsed
130
+ };
131
+ }
115
132
  function StudioHomePage({ additionalActions, additionalChildrenStart, additionalChildrenEnd, sections, hiddenGroups }) {
116
133
  const context = useRebaseContext();
117
134
  const breadcrumbs = useStudioBreadcrumbs$1();
@@ -121,9 +138,11 @@ function StudioHomePage({ additionalActions, additionalChildrenStart, additional
121
138
  }, [breadcrumbs.set]);
122
139
  const { containerRef } = useRestoreScroll();
123
140
  const pluginActions = useSlot("home.actions", { context });
141
+ const filteredSections = useMemo(() => SECTIONS.filter((s) => !hiddenGroups?.includes(s.label)), [hiddenGroups]);
142
+ const { isGroupCollapsed, toggleGroupCollapsed } = useStudioCollapsedGroups(useMemo(() => filteredSections.map((s) => s.label), [filteredSections]));
124
143
  return /* @__PURE__ */ jsx("div", {
125
144
  ref: containerRef,
126
- className: "py-2 overflow-auto h-full w-full",
145
+ className: "py-2 overflow-auto h-full w-full bg-surface-50 dark:bg-surface-800",
127
146
  children: /* @__PURE__ */ jsxs(Container, {
128
147
  maxWidth: "6xl",
129
148
  children: [
@@ -136,68 +155,77 @@ function StudioHomePage({ additionalActions, additionalChildrenStart, additional
136
155
  children: [additionalActions, pluginActions]
137
156
  }),
138
157
  additionalChildrenStart,
139
- /* @__PURE__ */ jsx("div", {
140
- className: "flex flex-col gap-8 pt-2",
141
- children: SECTIONS.map((section) => /* @__PURE__ */ jsxs("section", {
142
- "aria-label": section.label,
143
- children: [/* @__PURE__ */ jsx(Typography, {
144
- variant: "caption",
145
- component: "h2",
146
- color: "secondary",
147
- className: "py-2 font-medium uppercase text-sm text-surface-600 dark:text-surface-400",
148
- children: section.label
149
- }), /* @__PURE__ */ jsx("div", {
150
- className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3 mt-2",
151
- children: section.tools.map((tool) => /* @__PURE__ */ jsx(Card, {
152
- onClick: () => {
153
- navigate(tool.path);
154
- context.analyticsController?.onAnalyticsEvent?.("home_navigate_to_view", { path: tool.path });
155
- },
156
- className: cls("h-full px-4 py-2.5 cursor-pointer transition-all duration-200 ease-in-out", "hover:-translate-y-0.5 hover:shadow-md hover:shadow-primary/5"),
157
- children: /* @__PURE__ */ jsxs("div", {
158
- className: "flex flex-col items-start h-full",
159
- children: [/* @__PURE__ */ jsxs("div", {
160
- className: "grow w-full",
161
- children: [
162
- /* @__PURE__ */ jsx("div", {
163
- className: cls("h-6 flex items-center", section.iconColor),
164
- children: /* @__PURE__ */ jsx(IconForView, {
165
- collectionOrView: {
166
- slug: tool.path,
167
- name: tool.name,
168
- icon: tool.icon
169
- },
170
- size: "small"
171
- })
172
- }),
173
- /* @__PURE__ */ jsx(Typography, {
174
- gutterBottom: true,
175
- variant: "subtitle1",
176
- className: "mt-1 font-semibold",
177
- component: "h2",
178
- children: tool.name
179
- }),
180
- /* @__PURE__ */ jsx(Typography, {
181
- variant: "caption",
182
- color: "secondary",
183
- component: "div",
184
- children: tool.description
185
- })
186
- ]
187
- }), /* @__PURE__ */ jsx("div", {
188
- style: { alignSelf: "flex-end" },
189
- children: /* @__PURE__ */ jsx("div", {
190
- className: "p-2",
191
- children: /* @__PURE__ */ jsx(ArrowRightIcon, {
192
- className: "text-primary",
193
- size: iconSize.small
194
- })
158
+ filteredSections.map((section) => {
159
+ const sectionCollapsed = isGroupCollapsed(section.label);
160
+ return /* @__PURE__ */ jsx("div", {
161
+ className: "my-10",
162
+ children: /* @__PURE__ */ jsx(ExpandablePanel, {
163
+ invisible: true,
164
+ expanded: !sectionCollapsed,
165
+ onExpandedChange: (open) => {
166
+ if (open !== !sectionCollapsed) toggleGroupCollapsed(section.label);
167
+ },
168
+ className: "mt-6",
169
+ titleClassName: cls("min-h-0 p-0 border-none", "rounded flex items-center justify-between w-full", "hover:bg-transparent", "cursor-pointer select-none", sectionCollapsed && "bg-surface-100 dark:bg-surface-900/50"),
170
+ innerClassName: "mt-4 pt-0",
171
+ title: /* @__PURE__ */ jsx(Typography, {
172
+ variant: "caption",
173
+ component: "h2",
174
+ color: "secondary",
175
+ className: cls("px-4 py-1 rounded", "font-medium text-[10px] uppercase tracking-[0.08em] text-primary/50 dark:text-primary/70"),
176
+ children: section.label
177
+ }),
178
+ children: /* @__PURE__ */ jsx("div", {
179
+ className: "mt-4 pt-0",
180
+ children: /* @__PURE__ */ jsx("div", {
181
+ className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",
182
+ children: section.tools.map((tool) => /* @__PURE__ */ jsx(Card, {
183
+ onClick: () => {
184
+ navigate(tool.path);
185
+ context.analyticsController?.onAnalyticsEvent?.("home_navigate_to_view", { path: tool.path });
186
+ },
187
+ className: cls("group h-full p-4 cursor-pointer transition-colors duration-150 ease-in-out", "hover:bg-primary/5 dark:hover:bg-primary/5"),
188
+ children: /* @__PURE__ */ jsxs("div", {
189
+ className: "flex flex-col h-full",
190
+ children: [
191
+ /* @__PURE__ */ jsx("div", {
192
+ className: "flex items-center w-full justify-between mb-1",
193
+ children: /* @__PURE__ */ jsxs("div", {
194
+ className: "flex items-center gap-3",
195
+ children: [/* @__PURE__ */ jsx("div", {
196
+ className: "flex items-center justify-center w-5 h-5 text-surface-400 dark:text-surface-500 transition-colors duration-150 group-hover:text-primary dark:group-hover:text-primary",
197
+ children: /* @__PURE__ */ jsx(IconForView, {
198
+ collectionOrView: {
199
+ slug: tool.path,
200
+ name: tool.name,
201
+ icon: tool.icon
202
+ },
203
+ size: "small"
204
+ })
205
+ }), /* @__PURE__ */ jsx(Typography, {
206
+ variant: "subtitle1",
207
+ component: "h2",
208
+ children: tool.name
209
+ })]
210
+ })
211
+ }),
212
+ /* @__PURE__ */ jsx("div", {
213
+ className: "pl-8",
214
+ children: tool.description && /* @__PURE__ */ jsx(Typography, {
215
+ variant: "caption",
216
+ color: "secondary",
217
+ component: "div",
218
+ children: tool.description
219
+ })
220
+ }),
221
+ /* @__PURE__ */ jsx("div", { className: "grow" })
222
+ ]
195
223
  })
196
- })]
224
+ }, tool.path))
197
225
  })
198
- }, tool.path))
199
- })]
200
- }, section.label))
226
+ })
227
+ })
228
+ }, section.label);
201
229
  }),
202
230
  /* @__PURE__ */ jsxs("div", {
203
231
  className: "mt-10 mb-6",
@@ -208,7 +236,7 @@ function StudioHomePage({ additionalActions, additionalChildrenStart, additional
208
236
  variant: "caption",
209
237
  component: "h2",
210
238
  color: "secondary",
211
- className: "py-2 font-medium uppercase text-sm text-surface-600 dark:text-surface-400",
239
+ className: cls("px-4 py-1 rounded", "font-medium text-[10px] uppercase tracking-[0.08em] text-primary/50 dark:text-primary/70"),
212
240
  children: "Quick Start"
213
241
  })
214
242
  }),
@@ -261,7 +289,7 @@ function StudioHomePage({ additionalActions, additionalChildrenStart, additional
261
289
  variant: "caption",
262
290
  component: "h2",
263
291
  color: "secondary",
264
- className: "p-4 py-2 rounded font-medium uppercase text-sm text-surface-600 dark:text-surface-400",
292
+ className: cls("px-4 py-1 rounded", "font-medium text-[10px] uppercase tracking-[0.08em] text-primary/50 dark:text-primary/70"),
265
293
  children: s.title
266
294
  }), /* @__PURE__ */ jsx("div", {
267
295
  className: "mt-4",
@@ -568,12 +596,12 @@ function SyntaxHighlightedSnippet() {
568
596
  }
569
597
  //#endregion
570
598
  //#region src/components/RebaseStudio.tsx
571
- var SQLEditor = lazy(() => import("./SQLEditor-CuAhR-zr.js").then((m) => ({ default: m.SQLEditor })));
572
- var JSEditor = lazy(() => import("./JSEditor-DSucz6wV.js").then((m) => ({ default: m.JSEditor })));
573
- var RLSEditor = lazy(() => import("./RLSEditor-BM64laoW.js").then((m) => ({ default: m.RLSEditor })));
574
- var StorageView = lazy(() => import("./StorageView-CvrnHmDG.js").then((m) => ({ default: m.StorageView })));
599
+ var SQLEditor = lazy(() => import("./SQLEditor-CgR2hlUI.js").then((m) => ({ default: m.SQLEditor })));
600
+ var JSEditor = lazy(() => import("./JSEditor-Sgmw1SHC.js").then((m) => ({ default: m.JSEditor })));
601
+ var RLSEditor = lazy(() => import("./RLSEditor-DPhky8XW.js").then((m) => ({ default: m.RLSEditor })));
602
+ var StorageView = lazy(() => import("./StorageView-BMhD29YO.js").then((m) => ({ default: m.StorageView })));
575
603
  var CronJobsView = lazy(() => import("./CronJobsView-4gdtJvoe.js").then((m) => ({ default: m.CronJobsView })));
576
- var SchemaVisualizer = lazy(() => import("./SchemaVisualizer-OibKoD3g.js").then((m) => ({ default: m.SchemaVisualizer })));
604
+ var SchemaVisualizer = lazy(() => import("./SchemaVisualizer-WK4ZZR5X.js").then((m) => ({ default: m.SchemaVisualizer })));
577
605
  var BranchesView = lazy(() => import("./BranchesView-Dlg78EQ8.js").then((m) => ({ default: m.BranchesView })));
578
606
  var ApiExplorer = lazy(() => import("./ApiExplorer-CdIwR9Ga.js").then((m) => ({ default: m.ApiExplorer })));
579
607
  var LogsExplorer = lazy(() => import("./LogsExplorer-J4xfsuv3.js").then((m) => ({ default: m.LogsExplorer })));
@@ -707,6 +735,6 @@ function RebaseStudio({ tools, homePage }) {
707
735
  return null;
708
736
  }
709
737
  //#endregion
710
- export { RebaseStudio, StudioBridgeContext, StudioBridgeProvider, StudioHomePage, useStudioBreadcrumbs, useStudioCollectionRegistry, useStudioNavigationState, useStudioSideEntityController, useStudioUrlController };
738
+ export { RebaseStudio, StudioBridgeContext, StudioBridgeProvider, StudioHomePage, useStudioBreadcrumbs, useStudioCollectionRegistry, useStudioNavigationState, useStudioSidePanelController, useStudioUrlController };
711
739
 
712
740
  //# sourceMappingURL=index.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","names":[],"sources":["../src/components/StudioHomePage.tsx","../src/components/RebaseStudio.tsx"],"sourcesContent":["import type { HomePageSection, PluginGenericProps } from \"@rebasepro/types\";\nimport React, { useEffect } from \"react\";\nimport { Card, cls, Container, Typography } from \"@rebasepro/ui\";\nimport { ArrowRightIcon, iconSize } from \"@rebasepro/ui\";\nimport { IconForView, useRebaseContext, useRestoreScroll, useSlot } from \"@rebasepro/core\";\nimport { useNavigate } from \"react-router-dom\";\nimport { useStudioBreadcrumbs, SchemaDriftBanner } from \"@rebasepro/core\";\n\n/* ═══════════════════════════════════════════════════════════════\n Static studio tool definitions\n ═══════════════════════════════════════════════════════════════ */\n\ninterface StudioTool {\n path: string;\n name: string;\n description: string;\n icon: string;\n}\n\ninterface StudioSection {\n label: string;\n dotColor: string;\n iconColor: string;\n tools: StudioTool[];\n}\n\nconst SECTIONS: StudioSection[] = [\n {\n label: \"Database\",\n dotColor: \"bg-emerald-400\",\n iconColor: \"text-emerald-400\",\n tools: [\n { path: \"/schema\",\nname: \"Collections\",\ndescription: \"Define and manage your data model and collection schemas\",\nicon: \"LayoutList\" },\n { path: \"/schema-visualizer\",\nname: \"Schema Visualizer\",\ndescription: \"Interactive ERD showing tables, columns, and relationships\",\nicon: \"Network\" },\n { path: \"/sql\",\nname: \"SQL Console\",\ndescription: \"Execute raw SQL queries directly against your database\",\nicon: \"terminal\" },\n { path: \"/branches\",\nname: \"Branches\",\ndescription: \"Create and manage isolated database copies for development\",\nicon: \"GitBranch\" },\n { path: \"/rls\",\nname: \"RLS Policies\",\ndescription: \"Configure Row Level Security for fine-grained data access\",\nicon: \"ShieldCheck\" },\n { path: \"/logs\",\nname: \"Logs Explorer\",\ndescription: \"Real-time system, query, and authentication logs\",\nicon: \"Activity\" }\n ]\n },\n {\n label: \"Compute\",\n dotColor: \"bg-blue-400\",\n iconColor: \"text-blue-400\",\n tools: [\n { path: \"/js\",\nname: \"JS Console\",\ndescription: \"Run JavaScript with the Rebase SDK in a live sandbox\",\nicon: \"code\" },\n { path: \"/cron\",\nname: \"Cron Jobs\",\ndescription: \"Monitor and manage scheduled background tasks\",\nicon: \"Clock\" }\n ]\n },\n {\n label: \"API\",\n dotColor: \"bg-violet-400\",\n iconColor: \"text-violet-400\",\n tools: [\n { path: \"/api\",\nname: \"API Explorer\",\ndescription: \"Interactive API documentation with live request testing\",\nicon: \"BookOpen\" }\n ]\n },\n {\n label: \"Storage\",\n dotColor: \"bg-amber-400\",\n iconColor: \"text-amber-400\",\n tools: [\n { path: \"/storage\",\nname: \"Storage\",\ndescription: \"Browse, upload, and manage files in your storage bucket\",\nicon: \"HardDrive\" }\n ]\n },\n {\n label: \"Access Control\",\n dotColor: \"bg-rose-400\",\n iconColor: \"text-rose-400\",\n tools: [\n { path: \"/users\",\nname: \"Users\",\ndescription: \"Manage developers and assign roles in your workspace\",\nicon: \"group\" },\n { path: \"/roles\",\nname: \"Roles\",\ndescription: \"Create and configure fine-grained access permissions\",\nicon: \"ShieldEllipsis\" },\n { path: \"/api-keys\",\nname: \"API Keys\",\ndescription: \"Create and manage scoped keys for machine-to-machine access\",\nicon: \"KeyRound\" }\n ]\n }\n];\n\n/* ═══════════════════════════════════════════════════════════════ */\n\nexport function StudioHomePage({\n additionalActions,\n additionalChildrenStart,\n additionalChildrenEnd,\n sections,\n hiddenGroups\n}: {\n additionalActions?: React.ReactNode;\n additionalChildrenStart?: React.ReactNode;\n additionalChildrenEnd?: React.ReactNode;\n sections?: HomePageSection[];\n hiddenGroups?: string[];\n}) {\n const context = useRebaseContext();\n const breadcrumbs = useStudioBreadcrumbs();\n const navigate = useNavigate();\n\n useEffect(() => {\n breadcrumbs.set({ breadcrumbs: [] });\n }, [breadcrumbs.set]);\n\n const { containerRef } = useRestoreScroll();\n\n const sectionProps: PluginGenericProps = { context };\n\n const pluginActions = useSlot(\"home.actions\", sectionProps);\n\n return (\n <div ref={containerRef} className=\"py-2 overflow-auto h-full w-full\">\n <Container maxWidth=\"6xl\">\n <div className=\"mb-4 flex flex-col gap-2\">\n <SchemaDriftBanner />\n </div>\n\n {(additionalActions || pluginActions) && (\n <div className=\"w-full sticky py-4 transition-all duration-400 ease-in-out top-0 z-10 flex flex-row gap-4 justify-end\">\n {additionalActions}\n {pluginActions}\n </div>\n )}\n\n {additionalChildrenStart}\n\n {/* ── Tool sections ── */}\n <div className=\"flex flex-col gap-8 pt-2\">\n {SECTIONS.map((section) => (\n <section key={section.label} aria-label={section.label}>\n {/* Section header */}\n <Typography\n variant=\"caption\"\n component=\"h2\"\n color=\"secondary\"\n className=\"py-2 font-medium uppercase text-sm text-surface-600 dark:text-surface-400\"\n >\n {section.label}\n </Typography>\n\n {/* Card grid */}\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3 mt-2\">\n {section.tools.map((tool) => (\n <Card\n key={tool.path}\n onClick={() => {\n navigate(tool.path);\n context.analyticsController?.onAnalyticsEvent?.(\n \"home_navigate_to_view\",\n { path: tool.path }\n );\n }}\n className={cls(\n \"h-full px-4 py-2.5 cursor-pointer transition-all duration-200 ease-in-out\",\n \"hover:-translate-y-0.5 hover:shadow-md hover:shadow-primary/5\"\n )}\n >\n <div className=\"flex flex-col items-start h-full\">\n <div className=\"grow w-full\">\n {/* Icon */}\n <div className={cls(\"h-6 flex items-center\", section.iconColor)}>\n <IconForView\n collectionOrView={{ slug: tool.path,\nname: tool.name,\nicon: tool.icon }}\n size=\"small\"\n />\n </div>\n\n {/* Title */}\n <Typography\n gutterBottom\n variant=\"subtitle1\"\n className=\"mt-1 font-semibold\"\n component=\"h2\"\n >\n {tool.name}\n </Typography>\n\n {/* Description */}\n <Typography variant=\"caption\" color=\"secondary\" component=\"div\">\n {tool.description}\n </Typography>\n </div>\n\n {/* Arrow */}\n <div style={{ alignSelf: \"flex-end\" }}>\n <div className=\"p-2\">\n <ArrowRightIcon className=\"text-primary\" size={iconSize.small}/>\n </div>\n </div>\n </div>\n </Card>\n ))}\n </div>\n </section>\n ))}\n </div>\n\n {/* ── SDK Quick Start ── */}\n <div className=\"mt-10 mb-6\">\n <div className=\"flex items-center mb-1\">\n <Typography\n variant=\"caption\"\n component=\"h2\"\n color=\"secondary\"\n className=\"py-2 font-medium uppercase text-sm text-surface-600 dark:text-surface-400\"\n >\n Quick Start\n </Typography>\n </div>\n\n <Typography variant=\"body2\" color=\"secondary\" className=\"mb-4 max-w-2xl\">\n Generate a fully-typed SDK from your collections with{\" \"}\n <code className=\"text-emerald-400 font-mono text-xs bg-emerald-400/10 px-1.5 py-0.5 rounded\">\n npx rebase generate-sdk\n </code>\n {\" \"}and start querying your data with full TypeScript autocompletion.\n </Typography>\n\n <div className=\"rounded-lg border border-surface-200/40 dark:border-surface-700/40 bg-white dark:bg-surface-950 overflow-hidden\">\n {/* Title bar */}\n <div className=\"flex items-center justify-between px-4 py-2.5 border-b border-surface-200/40 dark:border-surface-700/40 bg-surface-50 dark:bg-surface-900/80\">\n <div className=\"flex items-center gap-2.5\">\n <div className=\"flex gap-1.5\">\n <span className=\"w-2.5 h-2.5 rounded-full bg-red-400/60\"/>\n <span className=\"w-2.5 h-2.5 rounded-full bg-amber-400/60\"/>\n <span className=\"w-2.5 h-2.5 rounded-full bg-emerald-400/60\"/>\n </div>\n <span className=\"text-xs font-mono text-surface-400 dark:text-surface-500 ml-1\">\n app.ts\n </span>\n </div>\n <span className=\"text-xs font-mono text-surface-400 dark:text-surface-500\">\n TypeScript\n </span>\n </div>\n\n {/* Syntax-highlighted code */}\n <div className=\"px-5 py-4 overflow-x-auto text-[13px] leading-6 font-mono\">\n <SyntaxHighlightedSnippet/>\n </div>\n </div>\n </div>\n\n {/* ── Extra sections from props ── */}\n {sections?.map((s) => (\n <div key={s.key} className=\"my-10\">\n <Typography\n variant=\"caption\"\n component=\"h2\"\n color=\"secondary\"\n className=\"p-4 py-2 rounded font-medium uppercase text-sm text-surface-600 dark:text-surface-400\"\n >\n {s.title}\n </Typography>\n <div className=\"mt-4\">{s.children}</div>\n </div>\n ))}\n\n {additionalChildrenEnd}\n </Container>\n </div>\n );\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Hand-crafted syntax-highlighted code snippet.\n Uses inline spans with Tailwind color classes to avoid\n pulling in a syntax highlighting library.\n ═══════════════════════════════════════════════════════════════ */\n\nfunction SyntaxHighlightedSnippet() {\n const kw = \"text-violet-600 dark:text-violet-400\"; // keywords\n const str = \"text-emerald-600 dark:text-emerald-400\"; // strings\n const typ = \"text-amber-600 dark:text-amber-300\"; // types\n const fn = \"text-blue-600 dark:text-blue-400\"; // functions\n const cm = \"text-surface-500 dark:text-surface-400 italic\"; // comments\n const op = \"text-surface-500 dark:text-surface-400\"; // operators / punctuation\n const tx = \"text-surface-950 dark:text-surface-200\"; // plain text\n\n return (\n <pre className=\"m-0 whitespace-pre\">\n <span className={kw}>import</span>\n <span className={tx}>{\" { \"}</span>\n <span className={fn}>createRebaseClient</span>\n <span className={tx}>{\" } \"}</span>\n <span className={kw}>from</span>\n <span className={tx}> </span>\n <span className={str}>&apos;@rebasepro/client&apos;</span>\n <span className={op}>;</span>\n {\"\\n\"}\n\n <span className={kw}>import</span>\n <span className={tx}> </span>\n <span className={kw}>type</span>\n <span className={tx}>{\" { \"}</span>\n <span className={typ}>Database</span>\n <span className={tx}>{\" } \"}</span>\n <span className={kw}>from</span>\n <span className={tx}> </span>\n <span className={str}>&apos;./database.types&apos;</span>\n <span className={op}>;</span>\n {\"\\n\\n\"}\n\n <span className={kw}>const</span>\n <span className={tx}> rebase </span>\n <span className={op}>= </span>\n <span className={fn}>createRebaseClient</span>\n <span className={op}>{\"<\"}</span>\n <span className={typ}>Database</span>\n <span className={op}>{\">(\"}</span>\n <span className={tx}>{\"{\"}</span>\n {\"\\n\"}\n <span className={tx}>{\" baseUrl\"}</span>\n <span className={op}>: </span>\n <span className={str}>&apos;http://localhost:3001&apos;</span>\n <span className={op}>,</span>\n {\"\\n\"}\n <span className={tx}>{\"}\"}</span>\n <span className={op}>);</span>\n {\"\\n\\n\"}\n\n <span className={cm}>{\"// Fully typed — autocompletion for tables and columns\"}</span>\n {\"\\n\"}\n <span className={kw}>const</span>\n <span className={tx}>{\" { \"}</span>\n <span className={tx}>data</span>\n <span className={op}>: </span>\n <span className={tx}>users</span>\n <span className={tx}>{\" } \"}</span>\n <span className={op}>= </span>\n <span className={kw}>await</span>\n <span className={tx}> rebase</span>\n <span className={op}>.</span>\n <span className={tx}>data</span>\n <span className={op}>.</span>\n <span className={tx}>users</span>\n <span className={op}>.</span>\n <span className={fn}>find</span>\n <span className={op}>();</span>\n {\"\\n\"}\n\n <span className={kw}>const</span>\n <span className={tx}>{\" { \"}</span>\n <span className={tx}>data</span>\n <span className={op}>: </span>\n <span className={tx}>posts</span>\n <span className={tx}>{\" } \"}</span>\n <span className={op}>= </span>\n <span className={kw}>await</span>\n <span className={tx}> rebase</span>\n <span className={op}>.</span>\n <span className={tx}>data</span>\n <span className={op}>.</span>\n <span className={fn}>collection</span>\n <span className={op}>(</span>\n <span className={str}>&apos;posts&apos;</span>\n <span className={op}>)</span>\n <span className={op}>.</span>\n <span className={fn}>find</span>\n <span className={op}>();</span>\n </pre>\n );\n}\n","import React, { lazy, Suspense, useLayoutEffect, useMemo } from \"react\";\nimport { useRebaseRegistryDispatch } from \"@rebasepro/core\";\nimport type { RebaseStudioConfig, AppView } from \"@rebasepro/types\";\nimport { CircularProgressCenter } from \"@rebasepro/ui\";\n\n// Lazy-loaded studio tools — each fetched only when its route is visited.\n// This keeps Monaco, @xyflow/react, dagre, pgsql-ast-parser etc. out of the initial bundle.\nconst SQLEditor = lazy(() => import(\"./SQLEditor/SQLEditor\").then(m => ({ default: m.SQLEditor })));\nconst JSEditor = lazy(() => import(\"./JSEditor/JSEditor\").then(m => ({ default: m.JSEditor })));\nconst RLSEditor = lazy(() => import(\"./RLSEditor/RLSEditor\").then(m => ({ default: m.RLSEditor })));\nconst StorageView = lazy(() => import(\"./StorageView/StorageView\").then(m => ({ default: m.StorageView })));\nconst CronJobsView = lazy(() => import(\"./CronJobs/CronJobsView\").then(m => ({ default: m.CronJobsView })));\nconst SchemaVisualizer = lazy(() => import(\"./SchemaVisualizer/SchemaVisualizer\").then(m => ({ default: m.SchemaVisualizer })));\nconst BranchesView = lazy(() => import(\"./Branches/BranchesView\").then(m => ({ default: m.BranchesView })));\nconst ApiExplorer = lazy(() => import(\"./ApiExplorer/ApiExplorer\").then(m => ({ default: m.ApiExplorer })));\nconst LogsExplorer = lazy(() => import(\"./LogsExplorer/LogsExplorer\").then(m => ({ default: m.LogsExplorer })));\nconst ApiKeysView = lazy(() => import(\"./ApiKeys/ApiKeysView\").then(m => ({ default: m.ApiKeysView })));\n\nimport { StudioHomePage } from \"./StudioHomePage\";\n\n/**\n * Declarative component to configure the Studio in Rebase.\n * Renders nothing — purely registers config into the RebaseRegistry.\n *\n * The \"schema\" tool (collection editor view) is now a built-in CMS feature.\n * When `<RebaseCMS collectionEditor={...}>` is used, the schema view is\n * automatically injected into Studio — no manual wiring needed.\n */\nconst DEFAULT_HOME_PAGE = <StudioHomePage/>;\n\nexport function RebaseStudio({ tools, homePage }: RebaseStudioConfig) {\n const dispatch = useRebaseRegistryDispatch();\n\n const resolvedHomePage = homePage ?? DEFAULT_HOME_PAGE;\n\n const devViews: AppView[] = useMemo(() => {\n const views: AppView[] = [];\n const activeTools = tools ?? [\"sql\", \"js\", \"rls\", \"storage\", \"cron\", \"schema-visualizer\", \"branches\", \"api\", \"logs\", \"api-keys\"];\n const suspense = (el: React.ReactNode) => <Suspense fallback={<CircularProgressCenter/>}>{el}</Suspense>;\n\n if (activeTools.includes(\"sql\")) {\n views.push({ slug: \"sql\",\nname: \"SQL Console\",\ngroup: \"Database\",\nicon: \"terminal\",\ndescription: \"Execute SQL queries\",\nview: suspense(<SQLEditor/>) });\n }\n if (activeTools.includes(\"js\")) {\n views.push({ slug: \"js\",\nname: \"JS Console\",\ngroup: \"Compute\",\nicon: \"code\",\ndescription: \"Execute JavaScript\",\nview: suspense(<JSEditor/>) });\n }\n if (activeTools.includes(\"rls\")) {\n views.push({ slug: \"rls\",\nname: \"RLS Policies\",\ngroup: \"Database\",\nicon: \"ShieldCheck\",\ndescription: \"Row Level Security\",\nview: suspense(<RLSEditor/>) });\n }\n if (activeTools.includes(\"storage\")) {\n views.push({ slug: \"storage\",\nname: \"Storage\",\ngroup: \"Storage\",\nicon: \"HardDrive\",\ndescription: \"Manage storage files\",\nview: suspense(<StorageView/>) });\n }\n if (activeTools.includes(\"cron\")) {\n views.push({ slug: \"cron\",\nname: \"Cron Jobs\",\ngroup: \"Compute\",\nicon: \"Clock\",\ndescription: \"Manage scheduled tasks\",\nview: suspense(<CronJobsView/>) });\n }\n if (activeTools.includes(\"schema-visualizer\")) {\n views.push({ slug: \"schema-visualizer\",\nname: \"Schema Visualizer\",\ngroup: \"Database\",\nicon: \"Network\",\ndescription: \"Interactive database ERD\",\nview: suspense(<SchemaVisualizer/>) });\n }\n if (activeTools.includes(\"branches\")) {\n views.push({ slug: \"branches\",\nname: \"Branches\",\ngroup: \"Database\",\nicon: \"GitBranch\",\ndescription: \"Create and manage database branches\",\nview: suspense(<BranchesView/>) });\n }\n if (activeTools.includes(\"api\")) {\n views.push({ slug: \"api\",\nname: \"API Explorer\",\ngroup: \"API\",\nicon: \"BookOpen\",\ndescription: \"Interactive API documentation and testing\",\nview: suspense(<ApiExplorer/>) });\n }\n if (activeTools.includes(\"logs\")) {\n views.push({ slug: \"logs\",\nname: \"Logs Explorer\",\ngroup: \"Database\",\nicon: \"Activity\",\ndescription: \"Real-time system and query logs\",\nview: suspense(<LogsExplorer/>) });\n }\n if (activeTools.includes(\"api-keys\")) {\n views.push({ slug: \"api-keys\",\nname: \"API Keys\",\ngroup: \"Access Control\",\nicon: \"KeyRound\",\ndescription: \"Create and manage scoped API keys\",\nview: suspense(<ApiKeysView/>) });\n }\n // Note: \"schema\" tool is auto-injected by RebaseShell when collectionEditor is enabled.\n // It is NOT registered here anymore.\n return views;\n }, [tools]);\n\n // Use a ref for homePage so it never destabilizes the effect.\n // homePage is a React element — its identity doesn't matter for registration.\n const homePageRef = React.useRef(resolvedHomePage);\n homePageRef.current = resolvedHomePage;\n\n useLayoutEffect(() => {\n dispatch.registerStudio({ tools,\nhomePage: homePageRef.current,\ndevViews });\n return () => dispatch.unregisterStudio();\n }, [dispatch, tools, devViews]);\n\n return null;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","names":[],"sources":["../src/components/StudioHomePage.tsx","../src/components/RebaseStudio.tsx"],"sourcesContent":["import type { HomePageSection, PluginGenericProps } from \"@rebasepro/types\";\nimport React, { useEffect, useMemo, useState } from \"react\";\nimport { Card, cls, Container, ExpandablePanel, Typography } from \"@rebasepro/ui\";\nimport { IconForView, useRebaseContext, useRestoreScroll, useSlot } from \"@rebasepro/core\";\nimport { useNavigate } from \"react-router-dom\";\nimport { useStudioBreadcrumbs, SchemaDriftBanner } from \"@rebasepro/core\";\n\n/* ═══════════════════════════════════════════════════════════════\n Static studio tool definitions\n ═══════════════════════════════════════════════════════════════ */\n\ninterface StudioTool {\n path: string;\n name: string;\n description: string;\n icon: string;\n}\n\ninterface StudioSection {\n label: string;\n tools: StudioTool[];\n}\n\nconst SECTIONS: StudioSection[] = [\n {\n label: \"Database\",\n tools: [\n { path: \"/schema\",\nname: \"Collections\",\ndescription: \"Define and manage your data model and collection schemas\",\nicon: \"LayoutList\" },\n { path: \"/schema-visualizer\",\nname: \"Schema Visualizer\",\ndescription: \"Interactive ERD showing tables, columns, and relationships\",\nicon: \"Network\" },\n { path: \"/sql\",\nname: \"SQL Console\",\ndescription: \"Execute raw SQL queries directly against your database\",\nicon: \"terminal\" },\n { path: \"/branches\",\nname: \"Branches\",\ndescription: \"Create and manage isolated database copies for development\",\nicon: \"GitBranch\" },\n { path: \"/rls\",\nname: \"RLS Policies\",\ndescription: \"Configure Row Level Security for fine-grained data access\",\nicon: \"ShieldCheck\" },\n { path: \"/logs\",\nname: \"Logs Explorer\",\ndescription: \"Real-time system, query, and authentication logs\",\nicon: \"Activity\" }\n ]\n },\n {\n label: \"Compute\",\n tools: [\n { path: \"/js\",\nname: \"JS Console\",\ndescription: \"Run JavaScript with the Rebase SDK in a live sandbox\",\nicon: \"code\" },\n { path: \"/cron\",\nname: \"Cron Jobs\",\ndescription: \"Monitor and manage scheduled background tasks\",\nicon: \"Clock\" }\n ]\n },\n {\n label: \"API\",\n tools: [\n { path: \"/api\",\nname: \"API Explorer\",\ndescription: \"Interactive API documentation with live request testing\",\nicon: \"BookOpen\" }\n ]\n },\n {\n label: \"Storage\",\n tools: [\n { path: \"/storage\",\nname: \"Storage\",\ndescription: \"Browse, upload, and manage files in your storage bucket\",\nicon: \"HardDrive\" }\n ]\n },\n {\n label: \"Access Control\",\n tools: [\n { path: \"/users\",\nname: \"Users\",\ndescription: \"Manage developers and assign roles in your workspace\",\nicon: \"group\" },\n { path: \"/roles\",\nname: \"Roles\",\ndescription: \"Create and configure fine-grained access permissions\",\nicon: \"ShieldEllipsis\" },\n { path: \"/api-keys\",\nname: \"API Keys\",\ndescription: \"Create and manage scoped keys for machine-to-machine access\",\nicon: \"KeyRound\" }\n ]\n }\n];\n\n/* ═══════════════════════════════════════════════════════════════ */\n\nconst COLLAPSED_STORAGE_KEY = \"rebase-studio-home-collapsed\";\n\nfunction useStudioCollapsedGroups(groupNames: string[]) {\n const [collapsed, setCollapsed] = useState<Set<string>>(() => {\n try {\n const stored = localStorage.getItem(COLLAPSED_STORAGE_KEY);\n return stored ? new Set(JSON.parse(stored)) : new Set<string>();\n } catch {\n return new Set<string>();\n }\n });\n\n const isGroupCollapsed = (name: string) => collapsed.has(name);\n\n const toggleGroupCollapsed = (name: string) => {\n setCollapsed(prev => {\n const next = new Set(prev);\n if (next.has(name)) {\n next.delete(name);\n } else {\n next.add(name);\n }\n try {\n localStorage.setItem(COLLAPSED_STORAGE_KEY, JSON.stringify([...next]));\n } catch { /* noop */ }\n return next;\n });\n };\n\n return { isGroupCollapsed, toggleGroupCollapsed };\n}\n\nexport function StudioHomePage({\n additionalActions,\n additionalChildrenStart,\n additionalChildrenEnd,\n sections,\n hiddenGroups\n}: {\n additionalActions?: React.ReactNode;\n additionalChildrenStart?: React.ReactNode;\n additionalChildrenEnd?: React.ReactNode;\n sections?: HomePageSection[];\n hiddenGroups?: string[];\n}) {\n const context = useRebaseContext();\n const breadcrumbs = useStudioBreadcrumbs();\n const navigate = useNavigate();\n\n useEffect(() => {\n breadcrumbs.set({ breadcrumbs: [] });\n }, [breadcrumbs.set]);\n\n const { containerRef } = useRestoreScroll();\n\n const sectionProps: PluginGenericProps = { context };\n\n const pluginActions = useSlot(\"home.actions\", sectionProps);\n\n const filteredSections = useMemo(\n () => SECTIONS.filter(s => !hiddenGroups?.includes(s.label)),\n [hiddenGroups]\n );\n\n const groupNames = useMemo(\n () => filteredSections.map(s => s.label),\n [filteredSections]\n );\n\n const { isGroupCollapsed, toggleGroupCollapsed } = useStudioCollapsedGroups(groupNames);\n\n return (\n <div ref={containerRef} className=\"py-2 overflow-auto h-full w-full bg-surface-50 dark:bg-surface-800\">\n <Container maxWidth=\"6xl\">\n <div className=\"mb-4 flex flex-col gap-2\">\n <SchemaDriftBanner />\n </div>\n\n {(additionalActions || pluginActions) && (\n <div className=\"w-full sticky py-4 transition-all duration-400 ease-in-out top-0 z-10 flex flex-row gap-4 justify-end\">\n {additionalActions}\n {pluginActions}\n </div>\n )}\n\n {additionalChildrenStart}\n\n {/* ── Tool sections ── */}\n {filteredSections.map((section) => {\n const sectionCollapsed = isGroupCollapsed(section.label);\n\n return (\n <div key={section.label} className=\"my-10\">\n <ExpandablePanel\n invisible\n expanded={!sectionCollapsed}\n onExpandedChange={(open) => {\n if (open !== !sectionCollapsed) {\n toggleGroupCollapsed(section.label);\n }\n }}\n className=\"mt-6\"\n titleClassName={cls(\n \"min-h-0 p-0 border-none\",\n \"rounded flex items-center justify-between w-full\",\n \"hover:bg-transparent\",\n \"cursor-pointer select-none\",\n sectionCollapsed && \"bg-surface-100 dark:bg-surface-900/50\"\n )}\n innerClassName=\"mt-4 pt-0\"\n title={\n <Typography\n variant=\"caption\"\n component=\"h2\"\n color=\"secondary\"\n className={cls(\n \"px-4 py-1 rounded\",\n \"font-medium text-[10px] uppercase tracking-[0.08em] text-primary/50 dark:text-primary/70\"\n )}\n >\n {section.label}\n </Typography>\n }\n >\n <div className=\"mt-4 pt-0\">\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {section.tools.map((tool) => (\n <Card\n key={tool.path}\n onClick={() => {\n navigate(tool.path);\n context.analyticsController?.onAnalyticsEvent?.(\n \"home_navigate_to_view\",\n { path: tool.path }\n );\n }}\n className={cls(\n \"group h-full p-4 cursor-pointer transition-colors duration-150 ease-in-out\",\n \"hover:bg-primary/5 dark:hover:bg-primary/5\"\n )}\n >\n <div className=\"flex flex-col h-full\">\n {/* Header: icon + title */}\n <div className=\"flex items-center w-full justify-between mb-1\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center justify-center w-5 h-5 text-surface-400 dark:text-surface-500 transition-colors duration-150 group-hover:text-primary dark:group-hover:text-primary\">\n <IconForView\n collectionOrView={{ slug: tool.path, name: tool.name, icon: tool.icon }}\n size=\"small\"\n />\n </div>\n <Typography variant=\"subtitle1\" component=\"h2\">\n {tool.name}\n </Typography>\n </div>\n </div>\n\n {/* Description indented to align with title */}\n <div className=\"pl-8\">\n {tool.description && (\n <Typography variant=\"caption\" color=\"secondary\" component=\"div\">\n {tool.description}\n </Typography>\n )}\n </div>\n\n {/* Spacer */}\n <div className=\"grow\"/>\n </div>\n </Card>\n ))}\n </div>\n </div>\n </ExpandablePanel>\n </div>\n );\n })}\n\n {/* ── SDK Quick Start ── */}\n <div className=\"mt-10 mb-6\">\n <div className=\"flex items-center mb-1\">\n <Typography\n variant=\"caption\"\n component=\"h2\"\n color=\"secondary\"\n className={cls(\n \"px-4 py-1 rounded\",\n \"font-medium text-[10px] uppercase tracking-[0.08em] text-primary/50 dark:text-primary/70\"\n )}\n >\n Quick Start\n </Typography>\n </div>\n\n <Typography variant=\"body2\" color=\"secondary\" className=\"mb-4 max-w-2xl\">\n Generate a fully-typed SDK from your collections with{\" \"}\n <code className=\"text-emerald-400 font-mono text-xs bg-emerald-400/10 px-1.5 py-0.5 rounded\">\n npx rebase generate-sdk\n </code>\n {\" \"}and start querying your data with full TypeScript autocompletion.\n </Typography>\n\n <div className=\"rounded-lg border border-surface-200/40 dark:border-surface-700/40 bg-white dark:bg-surface-950 overflow-hidden\">\n {/* Title bar */}\n <div className=\"flex items-center justify-between px-4 py-2.5 border-b border-surface-200/40 dark:border-surface-700/40 bg-surface-50 dark:bg-surface-900/80\">\n <div className=\"flex items-center gap-2.5\">\n <div className=\"flex gap-1.5\">\n <span className=\"w-2.5 h-2.5 rounded-full bg-red-400/60\"/>\n <span className=\"w-2.5 h-2.5 rounded-full bg-amber-400/60\"/>\n <span className=\"w-2.5 h-2.5 rounded-full bg-emerald-400/60\"/>\n </div>\n <span className=\"text-xs font-mono text-surface-400 dark:text-surface-500 ml-1\">\n app.ts\n </span>\n </div>\n <span className=\"text-xs font-mono text-surface-400 dark:text-surface-500\">\n TypeScript\n </span>\n </div>\n\n {/* Syntax-highlighted code */}\n <div className=\"px-5 py-4 overflow-x-auto text-[13px] leading-6 font-mono\">\n <SyntaxHighlightedSnippet/>\n </div>\n </div>\n </div>\n\n {/* ── Extra sections from props ── */}\n {sections?.map((s) => (\n <div key={s.key} className=\"my-10\">\n <Typography\n variant=\"caption\"\n component=\"h2\"\n color=\"secondary\"\n className={cls(\n \"px-4 py-1 rounded\",\n \"font-medium text-[10px] uppercase tracking-[0.08em] text-primary/50 dark:text-primary/70\"\n )}\n >\n {s.title}\n </Typography>\n <div className=\"mt-4\">{s.children}</div>\n </div>\n ))}\n\n {additionalChildrenEnd}\n </Container>\n </div>\n );\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Hand-crafted syntax-highlighted code snippet.\n Uses inline spans with Tailwind color classes to avoid\n pulling in a syntax highlighting library.\n ═══════════════════════════════════════════════════════════════ */\n\nfunction SyntaxHighlightedSnippet() {\n const kw = \"text-violet-600 dark:text-violet-400\"; // keywords\n const str = \"text-emerald-600 dark:text-emerald-400\"; // strings\n const typ = \"text-amber-600 dark:text-amber-300\"; // types\n const fn = \"text-blue-600 dark:text-blue-400\"; // functions\n const cm = \"text-surface-500 dark:text-surface-400 italic\"; // comments\n const op = \"text-surface-500 dark:text-surface-400\"; // operators / punctuation\n const tx = \"text-surface-950 dark:text-surface-200\"; // plain text\n\n return (\n <pre className=\"m-0 whitespace-pre\">\n <span className={kw}>import</span>\n <span className={tx}>{\" { \"}</span>\n <span className={fn}>createRebaseClient</span>\n <span className={tx}>{\" } \"}</span>\n <span className={kw}>from</span>\n <span className={tx}> </span>\n <span className={str}>&apos;@rebasepro/client&apos;</span>\n <span className={op}>;</span>\n {\"\\n\"}\n\n <span className={kw}>import</span>\n <span className={tx}> </span>\n <span className={kw}>type</span>\n <span className={tx}>{\" { \"}</span>\n <span className={typ}>Database</span>\n <span className={tx}>{\" } \"}</span>\n <span className={kw}>from</span>\n <span className={tx}> </span>\n <span className={str}>&apos;./database.types&apos;</span>\n <span className={op}>;</span>\n {\"\\n\\n\"}\n\n <span className={kw}>const</span>\n <span className={tx}> rebase </span>\n <span className={op}>= </span>\n <span className={fn}>createRebaseClient</span>\n <span className={op}>{\"<\"}</span>\n <span className={typ}>Database</span>\n <span className={op}>{\">(\"}</span>\n <span className={tx}>{\"{\"}</span>\n {\"\\n\"}\n <span className={tx}>{\" baseUrl\"}</span>\n <span className={op}>: </span>\n <span className={str}>&apos;http://localhost:3001&apos;</span>\n <span className={op}>,</span>\n {\"\\n\"}\n <span className={tx}>{\"}\"}</span>\n <span className={op}>);</span>\n {\"\\n\\n\"}\n\n <span className={cm}>{\"// Fully typed — autocompletion for tables and columns\"}</span>\n {\"\\n\"}\n <span className={kw}>const</span>\n <span className={tx}>{\" { \"}</span>\n <span className={tx}>data</span>\n <span className={op}>: </span>\n <span className={tx}>users</span>\n <span className={tx}>{\" } \"}</span>\n <span className={op}>= </span>\n <span className={kw}>await</span>\n <span className={tx}> rebase</span>\n <span className={op}>.</span>\n <span className={tx}>data</span>\n <span className={op}>.</span>\n <span className={tx}>users</span>\n <span className={op}>.</span>\n <span className={fn}>find</span>\n <span className={op}>();</span>\n {\"\\n\"}\n\n <span className={kw}>const</span>\n <span className={tx}>{\" { \"}</span>\n <span className={tx}>data</span>\n <span className={op}>: </span>\n <span className={tx}>posts</span>\n <span className={tx}>{\" } \"}</span>\n <span className={op}>= </span>\n <span className={kw}>await</span>\n <span className={tx}> rebase</span>\n <span className={op}>.</span>\n <span className={tx}>data</span>\n <span className={op}>.</span>\n <span className={fn}>collection</span>\n <span className={op}>(</span>\n <span className={str}>&apos;posts&apos;</span>\n <span className={op}>)</span>\n <span className={op}>.</span>\n <span className={fn}>find</span>\n <span className={op}>();</span>\n </pre>\n );\n}\n","import React, { lazy, Suspense, useLayoutEffect, useMemo } from \"react\";\nimport { useRebaseRegistryDispatch } from \"@rebasepro/core\";\nimport type { RebaseStudioConfig, AppView } from \"@rebasepro/types\";\nimport { CircularProgressCenter } from \"@rebasepro/ui\";\n\n// Lazy-loaded studio tools — each fetched only when its route is visited.\n// This keeps Monaco, @xyflow/react, dagre, pgsql-ast-parser etc. out of the initial bundle.\nconst SQLEditor = lazy(() => import(\"./SQLEditor/SQLEditor\").then(m => ({ default: m.SQLEditor })));\nconst JSEditor = lazy(() => import(\"./JSEditor/JSEditor\").then(m => ({ default: m.JSEditor })));\nconst RLSEditor = lazy(() => import(\"./RLSEditor/RLSEditor\").then(m => ({ default: m.RLSEditor })));\nconst StorageView = lazy(() => import(\"./StorageView/StorageView\").then(m => ({ default: m.StorageView })));\nconst CronJobsView = lazy(() => import(\"./CronJobs/CronJobsView\").then(m => ({ default: m.CronJobsView })));\nconst SchemaVisualizer = lazy(() => import(\"./SchemaVisualizer/SchemaVisualizer\").then(m => ({ default: m.SchemaVisualizer })));\nconst BranchesView = lazy(() => import(\"./Branches/BranchesView\").then(m => ({ default: m.BranchesView })));\nconst ApiExplorer = lazy(() => import(\"./ApiExplorer/ApiExplorer\").then(m => ({ default: m.ApiExplorer })));\nconst LogsExplorer = lazy(() => import(\"./LogsExplorer/LogsExplorer\").then(m => ({ default: m.LogsExplorer })));\nconst ApiKeysView = lazy(() => import(\"./ApiKeys/ApiKeysView\").then(m => ({ default: m.ApiKeysView })));\n\nimport { StudioHomePage } from \"./StudioHomePage\";\n\n/**\n * Declarative component to configure the Studio in Rebase.\n * Renders nothing — purely registers config into the RebaseRegistry.\n *\n * The \"schema\" tool (collection editor view) is now a built-in CMS feature.\n * When `<RebaseCMS collectionEditor={...}>` is used, the schema view is\n * automatically injected into Studio — no manual wiring needed.\n */\nconst DEFAULT_HOME_PAGE = <StudioHomePage/>;\n\nexport function RebaseStudio({ tools, homePage }: RebaseStudioConfig) {\n const dispatch = useRebaseRegistryDispatch();\n\n const resolvedHomePage = homePage ?? DEFAULT_HOME_PAGE;\n\n const devViews: AppView[] = useMemo(() => {\n const views: AppView[] = [];\n const activeTools = tools ?? [\"sql\", \"js\", \"rls\", \"storage\", \"cron\", \"schema-visualizer\", \"branches\", \"api\", \"logs\", \"api-keys\"];\n const suspense = (el: React.ReactNode) => <Suspense fallback={<CircularProgressCenter/>}>{el}</Suspense>;\n\n if (activeTools.includes(\"sql\")) {\n views.push({ slug: \"sql\",\nname: \"SQL Console\",\ngroup: \"Database\",\nicon: \"terminal\",\ndescription: \"Execute SQL queries\",\nview: suspense(<SQLEditor/>) });\n }\n if (activeTools.includes(\"js\")) {\n views.push({ slug: \"js\",\nname: \"JS Console\",\ngroup: \"Compute\",\nicon: \"code\",\ndescription: \"Execute JavaScript\",\nview: suspense(<JSEditor/>) });\n }\n if (activeTools.includes(\"rls\")) {\n views.push({ slug: \"rls\",\nname: \"RLS Policies\",\ngroup: \"Database\",\nicon: \"ShieldCheck\",\ndescription: \"Row Level Security\",\nview: suspense(<RLSEditor/>) });\n }\n if (activeTools.includes(\"storage\")) {\n views.push({ slug: \"storage\",\nname: \"Storage\",\ngroup: \"Storage\",\nicon: \"HardDrive\",\ndescription: \"Manage storage files\",\nview: suspense(<StorageView/>) });\n }\n if (activeTools.includes(\"cron\")) {\n views.push({ slug: \"cron\",\nname: \"Cron Jobs\",\ngroup: \"Compute\",\nicon: \"Clock\",\ndescription: \"Manage scheduled tasks\",\nview: suspense(<CronJobsView/>) });\n }\n if (activeTools.includes(\"schema-visualizer\")) {\n views.push({ slug: \"schema-visualizer\",\nname: \"Schema Visualizer\",\ngroup: \"Database\",\nicon: \"Network\",\ndescription: \"Interactive database ERD\",\nview: suspense(<SchemaVisualizer/>) });\n }\n if (activeTools.includes(\"branches\")) {\n views.push({ slug: \"branches\",\nname: \"Branches\",\ngroup: \"Database\",\nicon: \"GitBranch\",\ndescription: \"Create and manage database branches\",\nview: suspense(<BranchesView/>) });\n }\n if (activeTools.includes(\"api\")) {\n views.push({ slug: \"api\",\nname: \"API Explorer\",\ngroup: \"API\",\nicon: \"BookOpen\",\ndescription: \"Interactive API documentation and testing\",\nview: suspense(<ApiExplorer/>) });\n }\n if (activeTools.includes(\"logs\")) {\n views.push({ slug: \"logs\",\nname: \"Logs Explorer\",\ngroup: \"Database\",\nicon: \"Activity\",\ndescription: \"Real-time system and query logs\",\nview: suspense(<LogsExplorer/>) });\n }\n if (activeTools.includes(\"api-keys\")) {\n views.push({ slug: \"api-keys\",\nname: \"API Keys\",\ngroup: \"Access Control\",\nicon: \"KeyRound\",\ndescription: \"Create and manage scoped API keys\",\nview: suspense(<ApiKeysView/>) });\n }\n // Note: \"schema\" tool is auto-injected by RebaseShell when collectionEditor is enabled.\n // It is NOT registered here anymore.\n return views;\n }, [tools]);\n\n // Use a ref for homePage so it never destabilizes the effect.\n // homePage is a React element — its identity doesn't matter for registration.\n const homePageRef = React.useRef(resolvedHomePage);\n homePageRef.current = resolvedHomePage;\n\n useLayoutEffect(() => {\n dispatch.registerStudio({ tools,\nhomePage: homePageRef.current,\ndevViews });\n return () => dispatch.unregisterStudio();\n }, [dispatch, tools, devViews]);\n\n return null;\n}\n"],"mappings":"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"}