@rebasepro/studio 0.25.0-canary.ge06257e → 0.25.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.
package/dist/index.es.js CHANGED
@@ -322,7 +322,7 @@ function SyntaxHighlightedSnippet({ baseUrl }) {
322
322
  }),
323
323
  /* @__PURE__ */ jsx("span", {
324
324
  className: tx,
325
- children: " "
325
+ children: " { collectionsDictionary, "
326
326
  }),
327
327
  /* @__PURE__ */ jsx("span", {
328
328
  className: kw,
@@ -330,7 +330,7 @@ function SyntaxHighlightedSnippet({ baseUrl }) {
330
330
  }),
331
331
  /* @__PURE__ */ jsx("span", {
332
332
  className: tx,
333
- children: " { "
333
+ children: " "
334
334
  }),
335
335
  /* @__PURE__ */ jsx("span", {
336
336
  className: typ,
@@ -411,6 +411,23 @@ function SyntaxHighlightedSnippet({ baseUrl }) {
411
411
  children: ","
412
412
  }),
413
413
  "\n",
414
+ /* @__PURE__ */ jsx("span", {
415
+ className: tx,
416
+ children: " collections"
417
+ }),
418
+ /* @__PURE__ */ jsx("span", {
419
+ className: op,
420
+ children: ": "
421
+ }),
422
+ /* @__PURE__ */ jsx("span", {
423
+ className: tx,
424
+ children: "collectionsDictionary"
425
+ }),
426
+ /* @__PURE__ */ jsx("span", {
427
+ className: op,
428
+ children: ","
429
+ }),
430
+ "\n",
414
431
  /* @__PURE__ */ jsx("span", {
415
432
  className: tx,
416
433
  children: "}"
@@ -573,10 +590,10 @@ function SyntaxHighlightedSnippet({ baseUrl }) {
573
590
  //#region src/components/RebaseStudio.tsx
574
591
  var SQLEditor = lazyChunk(() => import("./SQLEditor-Cb9TIAz6.js").then((m) => ({ default: m.SQLEditor })));
575
592
  var JSEditor = lazyChunk(() => import("./JSEditor-BgGMMbJ-.js").then((m) => ({ default: m.JSEditor })));
576
- var RLSEditor = lazyChunk(() => import("./RLSEditor-CcA5fLSF.js").then((m) => ({ default: m.RLSEditor })));
593
+ var RLSEditor = lazyChunk(() => import("./RLSEditor-BnjZEqYU.js").then((m) => ({ default: m.RLSEditor })));
577
594
  var StorageView = lazyChunk(() => import("./StorageView-CPkDKbsX.js").then((m) => ({ default: m.StorageView })));
578
595
  var CronJobsView = lazyChunk(() => import("./CronJobsView-CMNK7eWO.js").then((m) => ({ default: m.CronJobsView })));
579
- var SchemaVisualizer = lazyChunk(() => import("./SchemaVisualizer-D-rAqwul.js").then((m) => ({ default: m.SchemaVisualizer })));
596
+ var SchemaVisualizer = lazyChunk(() => import("./SchemaVisualizer-pCYQ_Ds6.js").then((m) => ({ default: m.SchemaVisualizer })));
580
597
  var BranchesView = lazyChunk(() => import("./BranchesView-BHfwGTYc.js").then((m) => ({ default: m.BranchesView })));
581
598
  var BackupsView = lazyChunk(() => import("./BackupsView-BhOHB6iP.js").then((m) => ({ default: m.BackupsView })));
582
599
  var ApiExplorer = lazyChunk(() => import("./ApiExplorer-Bzt7Ye49.js").then((m) => ({ default: m.ApiExplorer })));
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","names":[],"sources":["../src/components/StudioHomePage.tsx","../src/components/RebaseStudio.tsx"],"sourcesContent":["import type { AppView, HomePageSection, PluginGenericProps } from \"@rebasepro/cms-types\";\nimport React, { useEffect, useMemo, useState } from \"react\";\nimport { Card, cls, Container, ExpandablePanel, Typography } from \"@rebasepro/ui\";\nimport { IconForView, useApiConfig, useNavigationGroupLabel, useRebaseContext, useRebaseRegistry, useRestoreScroll, useSlot, useTranslation } from \"@rebasepro/app\";\nimport { useNavigate } from \"react-router\";\nimport { useStudioBreadcrumbs, SchemaDriftBanner } from \"@rebasepro/app\";\n\n/* ═══════════════════════════════════════════════════════════════\n Studio tool sections, derived from the registered Studio views\n ═══════════════════════════════════════════════════════════════ */\n\ninterface StudioTool {\n path: string;\n name: string;\n description: string;\n icon?: string | React.ReactNode;\n}\n\ninterface StudioSection {\n label: string;\n tools: StudioTool[];\n}\n\n/** The view metadata the cards need — not the rendered `view` itself. */\ntype StudioViewMeta = Pick<AppView, \"slug\" | \"name\" | \"group\" | \"description\" | \"icon\" | \"hideFromNavigation\">;\n\n/** Group order for the home page; unknown groups are appended in view order. */\nconst GROUP_ORDER = [\"Database\", \"Compute\", \"Storage\", \"API\", \"Access Control\"];\n\nconst UNGROUPED_LABEL = \"Tools\";\n\n/**\n * Build the home page sections from the Studio views that are actually\n * registered, so a card exists if and only if its route does. A hand-written\n * list drifts: it used to advertise Users and Roles pages that 404, while\n * omitting the Backups view that does exist.\n */\nfunction buildSections(views: StudioViewMeta[]): StudioSection[] {\n const byGroup = new Map<string, StudioTool[]>();\n\n for (const view of views) {\n if (view.hideFromNavigation) continue;\n const label = view.group ?? UNGROUPED_LABEL;\n const tools = byGroup.get(label) ?? [];\n tools.push({\n path: `/${view.slug}`,\n name: view.name,\n description: view.description ?? \"\",\n icon: view.icon\n });\n byGroup.set(label, tools);\n }\n\n const ordered = [\n ...GROUP_ORDER.filter(g => byGroup.has(g)),\n ...[...byGroup.keys()].filter(g => !GROUP_ORDER.includes(g))\n ];\n\n return ordered.map(label => ({ label,\ntools: byGroup.get(label)! }));\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 const registry = useRebaseRegistry();\n const { t } = useTranslation();\n const apiConfig = useApiConfig();\n const apiUrl = absoluteApiUrl(apiConfig?.apiUrl);\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 // The collection editor (\"schema\") is not part of `devViews` — RebaseNavigation\n // injects it when the admin enables a collection editor. Mirror that condition so\n // the card tracks the route.\n const schemaEnabled = Boolean(registry.studioConfig && registry.cmsConfig?.collectionEditor);\n\n const filteredSections = useMemo(() => {\n const views: StudioViewMeta[] = [];\n if (schemaEnabled) {\n views.push({\n slug: \"schema\",\n name: t(\"studio_tool_schema\"),\n group: \"Database\",\n icon: \"LayoutList\",\n description: t(\"studio_tool_schema_description\")\n });\n }\n views.push(...(registry.studioConfig?.devViews ?? []));\n return buildSections(views).filter(s => !hiddenGroups?.includes(s.label));\n }, [registry.studioConfig?.devViews, schemaEnabled, hiddenGroups, t]);\n\n const groupNames = useMemo(\n () => filteredSections.map(s => s.label),\n [filteredSections]\n );\n\n const { isGroupCollapsed, toggleGroupCollapsed } = useStudioCollapsedGroups(groupNames);\n // The group name is the identifier this page orders and collapses by;\n // only what the reader sees is translated.\n const groupLabel = useNavigationGroupLabel();\n\n return (\n <div ref={containerRef} className=\"py-2 overflow-auto h-full w-full bg-surface-sheet\">\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-field\"\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-surface-400 dark:text-surface-400\"\n )}\n >\n {groupLabel(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-surface-card-hover\"\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-surface-400 dark:text-surface-400\"\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-hairline bg-surface-card overflow-hidden\">\n {/* Title bar */}\n <div className=\"flex items-center justify-between px-4 py-2.5 border-b border-hairline bg-surface-sheet\">\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 baseUrl={apiUrl}/>\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-surface-400 dark:text-surface-400\"\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\n/**\n * The address the panel's API answers on, as a script would write it: absolute\n * (a same-origin panel is configured with a relative one) and without a\n * trailing slash. It is what `baseUrl` takes — the API's path is the client's.\n */\nfunction absoluteApiUrl(apiUrl: string | undefined): string {\n const page = typeof window !== \"undefined\" ? window.location.href : undefined;\n try {\n return new URL(apiUrl || \"/\", page).href.replace(/\\/+$/, \"\");\n } catch {\n return apiUrl ?? \"\";\n }\n}\n\n/** The quick-start client, pointed at `baseUrl`. */\nfunction SyntaxHighlightedSnippet({ baseUrl }: { baseUrl: string }) {\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;{baseUrl}&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, { Suspense, useLayoutEffect, useMemo } from \"react\";\nimport { useRebaseRegistryDispatch, useTranslation } from \"@rebasepro/app\";\nimport type { RebaseStudioConfig, AppView } from \"@rebasepro/cms-types\";\nimport { CircularProgressCenter, lazyChunk } 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 = lazyChunk(() => import(\"./SQLEditor/SQLEditor\").then(m => ({ default: m.SQLEditor })));\nconst JSEditor = lazyChunk(() => import(\"./JSEditor/JSEditor\").then(m => ({ default: m.JSEditor })));\nconst RLSEditor = lazyChunk(() => import(\"./RLSEditor/RLSEditor\").then(m => ({ default: m.RLSEditor })));\nconst StorageView = lazyChunk(() => import(\"./StorageView/StorageView\").then(m => ({ default: m.StorageView })));\nconst CronJobsView = lazyChunk(() => import(\"./CronJobs/CronJobsView\").then(m => ({ default: m.CronJobsView })));\nconst SchemaVisualizer = lazyChunk(() => import(\"./SchemaVisualizer/SchemaVisualizer\").then(m => ({ default: m.SchemaVisualizer })));\nconst BranchesView = lazyChunk(() => import(\"./Branches/BranchesView\").then(m => ({ default: m.BranchesView })));\nconst BackupsView = lazyChunk(() => import(\"./Backups/BackupsView\").then(m => ({ default: m.BackupsView })));\nconst ApiExplorer = lazyChunk(() => import(\"./ApiExplorer/ApiExplorer\").then(m => ({ default: m.ApiExplorer })));\nconst LogsExplorer = lazyChunk(() => import(\"./LogsExplorer/LogsExplorer\").then(m => ({ default: m.LogsExplorer })));\nconst ApiKeysView = lazyChunk(() => 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 a Studio tool, but it is not\n * registered here: it ships from the panel package because it needs the project's\n * collection source to write back to. When `<RebaseCMS collectionEditor={...}>`\n * is used, the schema view is automatically injected into Studio — no manual\n * wiring needed. Where it is mounted from is an implementation detail; it is a\n * schema-editing tool and belongs beside SQL and RLS.\n */\nconst DEFAULT_HOME_PAGE = <StudioHomePage/>;\n\nexport function RebaseStudio({ tools, homePage, devViews: extraViews }: RebaseStudioConfig) {\n const dispatch = useRebaseRegistryDispatch();\n const { t, i18n } = useTranslation();\n\n const resolvedHomePage = homePage ?? DEFAULT_HOME_PAGE;\n\n /**\n * The tool list reduced to a value, so that re-rendering the host does not\n * republish the registry.\n *\n * `tools` is an array, and callers write it inline — `tools={[...TOOLS]}`\n * in the hosted console. A fresh array every render meant a fresh\n * `devViews` every render, which meant the effect below unregistered and\n * re-registered on every render. Because each registration builds *new*\n * `<Suspense><SQLEditor/></Suspense>` elements, whatever view was on screen\n * was torn down and remounted each time: a half-typed SQL query, a storage\n * folder you had navigated into, an open policy editor — all discarded, and\n * every mount reissued the view's initial requests.\n */\n const toolsKey = tools ? tools.join(\",\") : \"\";\n\n const devViews: AppView[] = useMemo(() => {\n const views: AppView[] = [];\n const activeTools = tools ?? [\"sql\", \"js\", \"rls\", \"storage\", \"cron\", \"schema-visualizer\", \"branches\", \"backups\", \"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: t(\"studio_tool_sql\"),\ngroup: \"Database\",\nicon: \"terminal\",\ndescription: t(\"studio_tool_sql_description\"),\nview: suspense(<SQLEditor/>) });\n }\n if (activeTools.includes(\"js\")) {\n views.push({ slug: \"js\",\nname: t(\"studio_tool_js\"),\ngroup: \"Compute\",\nicon: \"code\",\ndescription: t(\"studio_tool_js_description\"),\nview: suspense(<JSEditor/>) });\n }\n if (activeTools.includes(\"rls\")) {\n views.push({ slug: \"rls\",\nname: t(\"studio_tool_rls\"),\ngroup: \"Database\",\nicon: \"ShieldCheck\",\ndescription: t(\"studio_tool_rls_description\"),\nview: suspense(<RLSEditor/>) });\n }\n if (activeTools.includes(\"storage\")) {\n views.push({ slug: \"storage\",\nname: t(\"studio_tool_storage\"),\ngroup: \"Storage\",\nicon: \"HardDrive\",\ndescription: t(\"studio_tool_storage_description\"),\nview: suspense(<StorageView/>) });\n }\n if (activeTools.includes(\"cron\")) {\n views.push({ slug: \"cron\",\nname: t(\"studio_tool_cron\"),\ngroup: \"Compute\",\nicon: \"Clock\",\ndescription: t(\"studio_tool_cron_description\"),\nview: suspense(<CronJobsView/>) });\n }\n if (activeTools.includes(\"schema-visualizer\")) {\n views.push({ slug: \"schema-visualizer\",\nname: t(\"studio_tool_schema_visualizer\"),\ngroup: \"Database\",\nicon: \"Network\",\ndescription: t(\"studio_tool_schema_visualizer_description\"),\nview: suspense(<SchemaVisualizer/>) });\n }\n if (activeTools.includes(\"branches\")) {\n views.push({ slug: \"branches\",\nname: t(\"studio_tool_branches\"),\ngroup: \"Database\",\nicon: \"GitBranch\",\ndescription: t(\"studio_tool_branches_description\"),\nview: suspense(<BranchesView/>) });\n }\n if (activeTools.includes(\"backups\")) {\n views.push({ slug: \"backups\",\nname: t(\"studio_tool_backups\"),\ngroup: \"Database\",\nicon: \"Database\",\ndescription: t(\"studio_tool_backups_description\"),\nview: suspense(<BackupsView/>) });\n }\n if (activeTools.includes(\"api\")) {\n views.push({ slug: \"api\",\nname: t(\"studio_tool_api\"),\ngroup: \"API\",\nicon: \"BookOpen\",\ndescription: t(\"studio_tool_api_description\"),\nview: suspense(<ApiExplorer/>) });\n }\n if (activeTools.includes(\"logs\")) {\n views.push({ slug: \"logs\",\nname: t(\"studio_tool_logs\"),\ngroup: \"Database\",\nicon: \"Activity\",\ndescription: t(\"studio_tool_logs_description\"),\nview: suspense(<LogsExplorer/>) });\n }\n if (activeTools.includes(\"api-keys\")) {\n views.push({ slug: \"api-keys\",\nname: t(\"studio_tool_api_keys\"),\ngroup: \"Access Control\",\nicon: \"KeyRound\",\ndescription: t(\"studio_tool_api_keys_description\"),\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 // Keyed by the tool list's *contents*; see `toolsKey`. `tools` itself is\n // read inside, and is exactly determined by the key.\n // The strings are now translated, so the active language is part of\n // what this list is.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [toolsKey, t, i18n.language]);\n\n /**\n * Your own tools, keyed the same way `tools` is and for the same reason:\n * callers write `devViews={[…]}` inline, so the array is new on every\n * render. Re-registering would tear down and remount whichever Studio view\n * was on screen — a half-typed SQL query, an open policy editor.\n *\n * The key is the identity of each view, not its element: a view's `view` is\n * resolved by the router at render time, so a fresh element for the same\n * slug is not a configuration change.\n */\n const extraViewsKey = (extraViews ?? [])\n .map((v) => `${v.slug}|${v.name}|${v.group ?? \"\"}|${v.hideFromNavigation ?? false}`)\n .join(\",\");\n const extraViewsRef = React.useRef(extraViews);\n extraViewsRef.current = extraViews;\n\n const allDevViews: AppView[] = useMemo(\n () => [...devViews, ...(extraViewsRef.current ?? [])],\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [devViews, extraViewsKey]\n );\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 // Same reasoning for `tools`: it is registered as config, but a new array\n // with the same contents must not count as a change.\n const toolsRef = React.useRef(tools);\n toolsRef.current = tools;\n\n useLayoutEffect(() => {\n dispatch.registerStudio({ tools: toolsRef.current,\nhomePage: homePageRef.current,\ndevViews: allDevViews });\n return () => dispatch.unregisterStudio();\n }, [dispatch, allDevViews]);\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 { AppView, HomePageSection, PluginGenericProps } from \"@rebasepro/cms-types\";\nimport React, { useEffect, useMemo, useState } from \"react\";\nimport { Card, cls, Container, ExpandablePanel, Typography } from \"@rebasepro/ui\";\nimport { IconForView, useApiConfig, useNavigationGroupLabel, useRebaseContext, useRebaseRegistry, useRestoreScroll, useSlot, useTranslation } from \"@rebasepro/app\";\nimport { useNavigate } from \"react-router\";\nimport { useStudioBreadcrumbs, SchemaDriftBanner } from \"@rebasepro/app\";\n\n/* ═══════════════════════════════════════════════════════════════\n Studio tool sections, derived from the registered Studio views\n ═══════════════════════════════════════════════════════════════ */\n\ninterface StudioTool {\n path: string;\n name: string;\n description: string;\n icon?: string | React.ReactNode;\n}\n\ninterface StudioSection {\n label: string;\n tools: StudioTool[];\n}\n\n/** The view metadata the cards need — not the rendered `view` itself. */\ntype StudioViewMeta = Pick<AppView, \"slug\" | \"name\" | \"group\" | \"description\" | \"icon\" | \"hideFromNavigation\">;\n\n/** Group order for the home page; unknown groups are appended in view order. */\nconst GROUP_ORDER = [\"Database\", \"Compute\", \"Storage\", \"API\", \"Access Control\"];\n\nconst UNGROUPED_LABEL = \"Tools\";\n\n/**\n * Build the home page sections from the Studio views that are actually\n * registered, so a card exists if and only if its route does. A hand-written\n * list drifts: it used to advertise Users and Roles pages that 404, while\n * omitting the Backups view that does exist.\n */\nfunction buildSections(views: StudioViewMeta[]): StudioSection[] {\n const byGroup = new Map<string, StudioTool[]>();\n\n for (const view of views) {\n if (view.hideFromNavigation) continue;\n const label = view.group ?? UNGROUPED_LABEL;\n const tools = byGroup.get(label) ?? [];\n tools.push({\n path: `/${view.slug}`,\n name: view.name,\n description: view.description ?? \"\",\n icon: view.icon\n });\n byGroup.set(label, tools);\n }\n\n const ordered = [\n ...GROUP_ORDER.filter(g => byGroup.has(g)),\n ...[...byGroup.keys()].filter(g => !GROUP_ORDER.includes(g))\n ];\n\n return ordered.map(label => ({ label,\ntools: byGroup.get(label)! }));\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 const registry = useRebaseRegistry();\n const { t } = useTranslation();\n const apiConfig = useApiConfig();\n const apiUrl = absoluteApiUrl(apiConfig?.apiUrl);\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 // The collection editor (\"schema\") is not part of `devViews` — RebaseNavigation\n // injects it when the admin enables a collection editor. Mirror that condition so\n // the card tracks the route.\n const schemaEnabled = Boolean(registry.studioConfig && registry.cmsConfig?.collectionEditor);\n\n const filteredSections = useMemo(() => {\n const views: StudioViewMeta[] = [];\n if (schemaEnabled) {\n views.push({\n slug: \"schema\",\n name: t(\"studio_tool_schema\"),\n group: \"Database\",\n icon: \"LayoutList\",\n description: t(\"studio_tool_schema_description\")\n });\n }\n views.push(...(registry.studioConfig?.devViews ?? []));\n return buildSections(views).filter(s => !hiddenGroups?.includes(s.label));\n }, [registry.studioConfig?.devViews, schemaEnabled, hiddenGroups, t]);\n\n const groupNames = useMemo(\n () => filteredSections.map(s => s.label),\n [filteredSections]\n );\n\n const { isGroupCollapsed, toggleGroupCollapsed } = useStudioCollapsedGroups(groupNames);\n // The group name is the identifier this page orders and collapses by;\n // only what the reader sees is translated.\n const groupLabel = useNavigationGroupLabel();\n\n return (\n <div ref={containerRef} className=\"py-2 overflow-auto h-full w-full bg-surface-sheet\">\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-field\"\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-surface-400 dark:text-surface-400\"\n )}\n >\n {groupLabel(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-surface-card-hover\"\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-surface-400 dark:text-surface-400\"\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-hairline bg-surface-card overflow-hidden\">\n {/* Title bar */}\n <div className=\"flex items-center justify-between px-4 py-2.5 border-b border-hairline bg-surface-sheet\">\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 baseUrl={apiUrl}/>\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-surface-400 dark:text-surface-400\"\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\n/**\n * The address the panel's API answers on, as a script would write it: absolute\n * (a same-origin panel is configured with a relative one) and without a\n * trailing slash. It is what `baseUrl` takes — the API's path is the client's.\n */\nfunction absoluteApiUrl(apiUrl: string | undefined): string {\n const page = typeof window !== \"undefined\" ? window.location.href : undefined;\n try {\n return new URL(apiUrl || \"/\", page).href.replace(/\\/+$/, \"\");\n } catch {\n return apiUrl ?? \"\";\n }\n}\n\n/** The quick-start client, pointed at `baseUrl`. */\nfunction SyntaxHighlightedSnippet({ baseUrl }: { baseUrl: string }) {\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}>{\" { collectionsDictionary, \"}</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;{baseUrl}&apos;</span>\n <span className={op}>,</span>\n {\"\\n\"}\n {/* Maps each accessor back to its slug: without it a hyphenated\n slug is not reachable from the property name, and the copied\n client 404s on that collection. */}\n <span className={tx}>{\" collections\"}</span>\n <span className={op}>: </span>\n <span className={tx}>collectionsDictionary</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, { Suspense, useLayoutEffect, useMemo } from \"react\";\nimport { useRebaseRegistryDispatch, useTranslation } from \"@rebasepro/app\";\nimport type { RebaseStudioConfig, AppView } from \"@rebasepro/cms-types\";\nimport { CircularProgressCenter, lazyChunk } 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 = lazyChunk(() => import(\"./SQLEditor/SQLEditor\").then(m => ({ default: m.SQLEditor })));\nconst JSEditor = lazyChunk(() => import(\"./JSEditor/JSEditor\").then(m => ({ default: m.JSEditor })));\nconst RLSEditor = lazyChunk(() => import(\"./RLSEditor/RLSEditor\").then(m => ({ default: m.RLSEditor })));\nconst StorageView = lazyChunk(() => import(\"./StorageView/StorageView\").then(m => ({ default: m.StorageView })));\nconst CronJobsView = lazyChunk(() => import(\"./CronJobs/CronJobsView\").then(m => ({ default: m.CronJobsView })));\nconst SchemaVisualizer = lazyChunk(() => import(\"./SchemaVisualizer/SchemaVisualizer\").then(m => ({ default: m.SchemaVisualizer })));\nconst BranchesView = lazyChunk(() => import(\"./Branches/BranchesView\").then(m => ({ default: m.BranchesView })));\nconst BackupsView = lazyChunk(() => import(\"./Backups/BackupsView\").then(m => ({ default: m.BackupsView })));\nconst ApiExplorer = lazyChunk(() => import(\"./ApiExplorer/ApiExplorer\").then(m => ({ default: m.ApiExplorer })));\nconst LogsExplorer = lazyChunk(() => import(\"./LogsExplorer/LogsExplorer\").then(m => ({ default: m.LogsExplorer })));\nconst ApiKeysView = lazyChunk(() => 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 a Studio tool, but it is not\n * registered here: it ships from the panel package because it needs the project's\n * collection source to write back to. When `<RebaseCMS collectionEditor={...}>`\n * is used, the schema view is automatically injected into Studio — no manual\n * wiring needed. Where it is mounted from is an implementation detail; it is a\n * schema-editing tool and belongs beside SQL and RLS.\n */\nconst DEFAULT_HOME_PAGE = <StudioHomePage/>;\n\nexport function RebaseStudio({ tools, homePage, devViews: extraViews }: RebaseStudioConfig) {\n const dispatch = useRebaseRegistryDispatch();\n const { t, i18n } = useTranslation();\n\n const resolvedHomePage = homePage ?? DEFAULT_HOME_PAGE;\n\n /**\n * The tool list reduced to a value, so that re-rendering the host does not\n * republish the registry.\n *\n * `tools` is an array, and callers write it inline — `tools={[...TOOLS]}`\n * in the hosted console. A fresh array every render meant a fresh\n * `devViews` every render, which meant the effect below unregistered and\n * re-registered on every render. Because each registration builds *new*\n * `<Suspense><SQLEditor/></Suspense>` elements, whatever view was on screen\n * was torn down and remounted each time: a half-typed SQL query, a storage\n * folder you had navigated into, an open policy editor — all discarded, and\n * every mount reissued the view's initial requests.\n */\n const toolsKey = tools ? tools.join(\",\") : \"\";\n\n const devViews: AppView[] = useMemo(() => {\n const views: AppView[] = [];\n const activeTools = tools ?? [\"sql\", \"js\", \"rls\", \"storage\", \"cron\", \"schema-visualizer\", \"branches\", \"backups\", \"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: t(\"studio_tool_sql\"),\ngroup: \"Database\",\nicon: \"terminal\",\ndescription: t(\"studio_tool_sql_description\"),\nview: suspense(<SQLEditor/>) });\n }\n if (activeTools.includes(\"js\")) {\n views.push({ slug: \"js\",\nname: t(\"studio_tool_js\"),\ngroup: \"Compute\",\nicon: \"code\",\ndescription: t(\"studio_tool_js_description\"),\nview: suspense(<JSEditor/>) });\n }\n if (activeTools.includes(\"rls\")) {\n views.push({ slug: \"rls\",\nname: t(\"studio_tool_rls\"),\ngroup: \"Database\",\nicon: \"ShieldCheck\",\ndescription: t(\"studio_tool_rls_description\"),\nview: suspense(<RLSEditor/>) });\n }\n if (activeTools.includes(\"storage\")) {\n views.push({ slug: \"storage\",\nname: t(\"studio_tool_storage\"),\ngroup: \"Storage\",\nicon: \"HardDrive\",\ndescription: t(\"studio_tool_storage_description\"),\nview: suspense(<StorageView/>) });\n }\n if (activeTools.includes(\"cron\")) {\n views.push({ slug: \"cron\",\nname: t(\"studio_tool_cron\"),\ngroup: \"Compute\",\nicon: \"Clock\",\ndescription: t(\"studio_tool_cron_description\"),\nview: suspense(<CronJobsView/>) });\n }\n if (activeTools.includes(\"schema-visualizer\")) {\n views.push({ slug: \"schema-visualizer\",\nname: t(\"studio_tool_schema_visualizer\"),\ngroup: \"Database\",\nicon: \"Network\",\ndescription: t(\"studio_tool_schema_visualizer_description\"),\nview: suspense(<SchemaVisualizer/>) });\n }\n if (activeTools.includes(\"branches\")) {\n views.push({ slug: \"branches\",\nname: t(\"studio_tool_branches\"),\ngroup: \"Database\",\nicon: \"GitBranch\",\ndescription: t(\"studio_tool_branches_description\"),\nview: suspense(<BranchesView/>) });\n }\n if (activeTools.includes(\"backups\")) {\n views.push({ slug: \"backups\",\nname: t(\"studio_tool_backups\"),\ngroup: \"Database\",\nicon: \"Database\",\ndescription: t(\"studio_tool_backups_description\"),\nview: suspense(<BackupsView/>) });\n }\n if (activeTools.includes(\"api\")) {\n views.push({ slug: \"api\",\nname: t(\"studio_tool_api\"),\ngroup: \"API\",\nicon: \"BookOpen\",\ndescription: t(\"studio_tool_api_description\"),\nview: suspense(<ApiExplorer/>) });\n }\n if (activeTools.includes(\"logs\")) {\n views.push({ slug: \"logs\",\nname: t(\"studio_tool_logs\"),\ngroup: \"Database\",\nicon: \"Activity\",\ndescription: t(\"studio_tool_logs_description\"),\nview: suspense(<LogsExplorer/>) });\n }\n if (activeTools.includes(\"api-keys\")) {\n views.push({ slug: \"api-keys\",\nname: t(\"studio_tool_api_keys\"),\ngroup: \"Access Control\",\nicon: \"KeyRound\",\ndescription: t(\"studio_tool_api_keys_description\"),\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 // Keyed by the tool list's *contents*; see `toolsKey`. `tools` itself is\n // read inside, and is exactly determined by the key.\n // The strings are now translated, so the active language is part of\n // what this list is.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [toolsKey, t, i18n.language]);\n\n /**\n * Your own tools, keyed the same way `tools` is and for the same reason:\n * callers write `devViews={[…]}` inline, so the array is new on every\n * render. Re-registering would tear down and remount whichever Studio view\n * was on screen — a half-typed SQL query, an open policy editor.\n *\n * The key is the identity of each view, not its element: a view's `view` is\n * resolved by the router at render time, so a fresh element for the same\n * slug is not a configuration change.\n */\n const extraViewsKey = (extraViews ?? [])\n .map((v) => `${v.slug}|${v.name}|${v.group ?? \"\"}|${v.hideFromNavigation ?? false}`)\n .join(\",\");\n const extraViewsRef = React.useRef(extraViews);\n extraViewsRef.current = extraViews;\n\n const allDevViews: AppView[] = useMemo(\n () => [...devViews, ...(extraViewsRef.current ?? [])],\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [devViews, extraViewsKey]\n );\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 // Same reasoning for `tools`: it is registered as config, but a new array\n // with the same contents must not count as a change.\n const toolsRef = React.useRef(tools);\n toolsRef.current = tools;\n\n useLayoutEffect(() => {\n dispatch.registerStudio({ tools: toolsRef.current,\nhomePage: homePageRef.current,\ndevViews: allDevViews });\n return () => dispatch.unregisterStudio();\n }, [dispatch, allDevViews]);\n\n return null;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rebasepro/studio",
3
- "version": "0.25.0-canary.ge06257e",
3
+ "version": "0.25.0",
4
4
  "description": "Rebase Studio — the SQL editor, schema visualiser, RLS policy editor and API explorer.",
5
5
  "keywords": [
6
6
  "rebase",
@@ -35,19 +35,19 @@
35
35
  "pgsql-ast-parser": "12.0.2",
36
36
  "prism-react-renderer": "^2.4.1",
37
37
  "react-dropzone": "^19.1.1",
38
- "@rebasepro/cms-types": "0.25.0-canary.ge06257e",
39
- "@rebasepro/client": "0.25.0-canary.ge06257e",
40
- "@rebasepro/app": "0.25.0-canary.ge06257e",
41
- "@rebasepro/types": "0.25.0-canary.ge06257e",
42
- "@rebasepro/ui": "0.25.0-canary.ge06257e",
43
- "@rebasepro/utils": "0.25.0-canary.ge06257e",
44
- "@rebasepro/common": "0.25.0-canary.ge06257e"
38
+ "@rebasepro/cms-types": "0.25.0",
39
+ "@rebasepro/app": "0.25.0",
40
+ "@rebasepro/common": "0.25.0",
41
+ "@rebasepro/types": "0.25.0",
42
+ "@rebasepro/utils": "0.25.0",
43
+ "@rebasepro/ui": "0.25.0",
44
+ "@rebasepro/client": "0.25.0"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "react": "^19.2.7",
48
48
  "react-dom": "^19.2.7",
49
49
  "react-router": "^8.3.0",
50
- "@rebasepro/cms": "0.25.0-canary.ge06257e"
50
+ "@rebasepro/cms": "0.25.0"
51
51
  },
52
52
  "peerDependenciesMeta": {
53
53
  "@rebasepro/cms": {