@rebasepro/studio 0.4.0 → 0.5.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 (30) hide show
  1. package/README.md +73 -140
  2. package/dist/{JSEditor-BCSoElPg.js → JSEditor-DfwRLBZg.js} +2 -2
  3. package/dist/JSEditor-DfwRLBZg.js.map +1 -0
  4. package/dist/RLSEditor-CHEExeSB.js.map +1 -1
  5. package/dist/{SQLEditor-BC0IOUQu.js → SQLEditor-CQXaI0iU.js} +2 -2
  6. package/dist/SQLEditor-CQXaI0iU.js.map +1 -0
  7. package/dist/SchemaVisualizer-BGpmzyXT.js.map +1 -1
  8. package/dist/common/src/util/permissions.d.ts +14 -6
  9. package/dist/index.es.js +2 -2
  10. package/dist/index.umd.js +2 -2
  11. package/dist/index.umd.js.map +1 -1
  12. package/dist/studio/src/components/RLSEditor/RLSEditor.d.ts +0 -6
  13. package/dist/studio/src/components/SchemaVisualizer/schema-visualizer.utils.d.ts +0 -8
  14. package/dist/studio/src/utils/pgColumnToProperty.d.ts +1 -1
  15. package/dist/types/src/types/backend.d.ts +36 -1
  16. package/dist/types/src/types/collections.d.ts +21 -1
  17. package/dist/types/src/types/properties.d.ts +0 -8
  18. package/package.json +8 -8
  19. package/src/components/JSEditor/JSEditor.tsx +1 -1
  20. package/src/components/RLSEditor/RLSEditor.tsx +1 -1
  21. package/src/components/SchemaVisualizer/schema-visualizer.utils.ts +3 -3
  22. package/src/components/SchemaVisualizer/useSchemaGraph.ts +2 -2
  23. package/src/utils/pgColumnToProperty.ts +23 -20
  24. package/src/utils/sql_utils.ts +1 -1
  25. package/dist/JSEditor-BCSoElPg.js.map +0 -1
  26. package/dist/SQLEditor-BC0IOUQu.js.map +0 -1
  27. package/dist/studio/src/components/SchemaVisualizer/index.d.ts +0 -5
  28. package/dist/studio/src/utils/entities.d.ts +0 -0
  29. package/src/components/SchemaVisualizer/index.ts +0 -5
  30. package/src/utils/entities.ts +0 -2
package/README.md CHANGED
@@ -1,159 +1,92 @@
1
- # Rebase Collection Editor Plugin
1
+ # @rebasepro/studio
2
2
 
3
- This plugin enables creating and managing Firestore collections directly from your Rebase interface. It adds a visual
4
- collection editor that allows you to create, edit, and delete collections without writing code.
3
+ Developer tools layer for Rebase provides 9 lazy-loaded tools (SQL Console, JS Console, RLS Editor, Storage, Cron Jobs, Schema Visualizer, Branches, API Explorer, Logs Explorer) plus a customizable home page.
5
4
 
6
5
  ## Installation
7
6
 
8
7
  ```bash
9
- npm install @rebasepro/collection_editor
10
- # or
11
- yarn add @rebasepro/collection_editor
8
+ pnpm add @rebasepro/studio
12
9
  ```
13
10
 
14
- For Firebase integration, also install:
15
-
16
- ```bash
17
- npm install @rebasepro/collection_editor_firebase
18
- # or
19
- yarn add @rebasepro/collection_editor_firebase
20
- ```
21
-
22
- ## Features
23
-
24
- - Create and edit collections through a visual interface
25
- - Define properties, validations, and display options
26
- - Organize collections with groups and subcollections
27
- - Merge UI-defined collections with code-defined collections
28
- - Persist collection configurations in Firestore
29
- - Control permissions for collection editing operations
30
-
31
- ## Basic Usage
32
-
33
- ```tsx
34
- import React from "react";
35
- import { RebaseCMS } from "@rebasepro/admin";
36
- import { useFirestoreCollectionsConfigController } from "@rebasepro/collection_editor_firebase";
37
-
38
- export default function App() {
39
- // Controller to save collection configs in Firestore
40
- const collectionConfigController = useFirestoreCollectionsConfigController({
41
- firebaseApp
42
- });
43
-
44
- return <RebaseCMS
45
- name={"My CMS"}
46
- authentication={myAuthenticator}
47
- firebaseConfig={firebaseConfig}
48
- collectionEditor={{
49
- collectionConfigController
50
- }}
51
- />;
52
- }
53
- ```
54
-
55
- ## Advanced Configuration
56
-
57
- You can customize collection editor behavior with these options using the `collectionEditor` prop on `RebaseCMS`:
58
-
59
- ```tsx
60
- <RebaseCMS
61
- collectionEditor={{
62
- collectionConfigController, // Required: controller that handles persistence
63
-
64
- // Define permissions for collection operations
65
- configPermissions: ({ user }) => ({
66
- createCollections: user.roles?.includes("admin") ?? false,
67
- editCollections: user.roles?.includes("admin") ?? false,
68
- deleteCollections: user.roles?.includes("admin") ?? false
69
- }),
70
-
71
- // Prevent these group names from being used
72
- reservedGroups: ["admin", "system"],
73
-
74
- // Optional custom view to add to the editor
75
- extraView: {
76
- View: MyCustomView,
77
- icon: <CustomIcon />
78
- },
79
-
80
- // Function to infer collection structure from existing data
81
- collectionInference: async ({ path }) => {
82
- // Return inferred schema based on data at path
83
- },
84
-
85
- // Function to get sample data for a collection
86
- getData: async (path, parentPaths) => {
87
- // Return sample data for the specified path
88
- },
89
-
90
- // Track collection editor events
91
- onAnalyticsEvent: (event, params) => {
92
- console.log("Collection editor event:", event, params);
93
- },
94
-
95
- // Include introduction widget when no collections exist
96
- includeIntroView: true
97
- }}
98
- />
11
+ ### Peer Dependencies
12
+
13
+ - `react` >= 19.0.0
14
+ - `react-dom` >= 19.0.0
15
+ - `react-router` ^7.0.0
16
+ - `react-router-dom` ^7.0.0
17
+ - `@rebasepro/admin` (optional)
18
+
19
+ ## What This Package Does
20
+
21
+ `@rebasepro/studio` registers a set of developer tools into the Rebase CMS. The `<RebaseStudio>` component renders nothing visible — it declaratively registers tool views into the Rebase registry. Each tool (Monaco-based editors, xyflow graph, etc.) is lazy-loaded so it stays out of the initial bundle.
22
+
23
+ ## Available Tools
24
+
25
+ | Slug | Name | Group | Description |
26
+ |---|---|---|---|
27
+ | `sql` | SQL Console | Database | Execute raw SQL queries |
28
+ | `js` | JS Console | Compute | Run JavaScript in a live sandbox |
29
+ | `rls` | RLS Policies | Database | Configure Row Level Security |
30
+ | `storage` | Storage | Storage | Browse and manage files |
31
+ | `cron` | Cron Jobs | Compute | Monitor scheduled tasks |
32
+ | `schema-visualizer` | Schema Visualizer | Database | Interactive database ERD |
33
+ | `branches` | Branches | Database | Create and manage database branches |
34
+ | `api` | API Explorer | API | Interactive API docs and testing |
35
+ | `logs` | Logs Explorer | Database | Real-time system and query logs |
36
+
37
+ All 9 tools are enabled by default. The `schema` tool (collection editor) is auto-injected by the CMS when `collectionEditor` is enabled — it is **not** registered here.
38
+
39
+ ## Key Exports
40
+
41
+ | Export | Type | Description |
42
+ |---|---|---|
43
+ | `RebaseStudio` | Component | Main entry point — registers tools into the Rebase registry |
44
+ | `StudioHomePage` | Component | Default home page with tool cards and SDK quick-start snippet |
45
+ | `StudioBridgeProvider` | Component | Re-exported from `@rebasepro/core` |
46
+ | `StudioBridgeContext` | Context | Re-exported from `@rebasepro/core` |
47
+ | `useStudioCollectionRegistry` | Hook | Access the collection registry |
48
+ | `useStudioSideEntityController` | Hook | Control the side entity panel |
49
+ | `useStudioUrlController` | Hook | URL state management |
50
+ | `useStudioNavigationState` | Hook | Navigation state |
51
+ | `useStudioBreadcrumbs` | Hook | Breadcrumb management |
52
+ | `StudioBridge` | Type | Bridge interface type |
53
+ | `BreadcrumbEntry` | Type | Single breadcrumb item |
54
+ | `BreadcrumbsController` | Type | Breadcrumb controller interface |
55
+
56
+ Individual tools (e.g. `SQLEditor`, `SchemaVisualizer`) are **not** re-exported from the barrel to preserve code splitting. Use deep imports if needed:
57
+
58
+ ```typescript
59
+ import { SQLEditor } from "@rebasepro/studio/components/SQLEditor/SQLEditor";
99
60
  ```
100
61
 
101
- ## Integration with Code-Defined Collections
102
-
103
- You can combine collections defined in code with those created in the UI:
62
+ ## Quick Start
104
63
 
105
64
  ```tsx
106
- import { mergeCollections } from "@rebasepro/admin/collection_editor";
107
-
65
+ import { RebaseStudio } from "@rebasepro/studio";
108
66
 
109
- const collectionsBuilder = useCallback(() => {
110
- // Collections defined in code
111
- const codeCollections = [productsCollection, ordersCollection];
112
-
113
- // Merge with collections from the editor UI
114
- return mergeCollections(codeCollections, collectionConfigController.collections ?? []);
115
- }, [collectionConfigController.collections]);
67
+ // Inside your Rebase app — enable all 9 tools (default)
68
+ <RebaseStudio />
116
69
 
117
- const navigationController = useBuildNavigationStateController({
118
- collections: collectionsBuilder,
119
- // Other options
120
- });
121
- ```
122
-
123
- ## Firestore Configuration Controller
124
-
125
- To persist collections in Firestore:
70
+ // Or pick specific tools
71
+ <RebaseStudio tools={["sql", "rls", "storage", "api"]} />
126
72
 
127
- ```tsx
128
- const collectionConfigController = useFirestoreCollectionsConfigController({
129
- firebaseApp,
130
-
131
- // Optional: specify where to save configs (default: "__REBASE/config/collections")
132
- configPath: "custom/config/path",
133
-
134
- // Optional: define permissions for collections
135
- permissions: ({ user }) => ({
136
- // Your permissions logic
137
- }),
138
-
139
- // Optional: custom property configurations
140
- propertyConfigs: [
141
- // Custom property types
142
- ]
143
- });
73
+ // Custom home page
74
+ <RebaseStudio homePage={<MyCustomHomePage />} />
144
75
  ```
145
76
 
146
- ## Additional Notes
147
-
148
- - Collections created through the editor are stored in Firestore and loaded dynamically
149
- - The plugin automatically adds UI elements for creating and managing collections
150
- - For a complete solution, consider using alongside other plugins like data import/export
77
+ ### StudioHomePage Props
151
78
 
152
- ## Related Plugins
79
+ | Prop | Type | Description |
80
+ |---|---|---|
81
+ | `additionalActions` | `ReactNode` | Extra actions in the top-right area |
82
+ | `additionalChildrenStart` | `ReactNode` | Content before the tool grid |
83
+ | `additionalChildrenEnd` | `ReactNode` | Content after the tool grid |
84
+ | `sections` | `HomePageSection[]` | Extra sections appended to the page |
85
+ | `hiddenGroups` | `string[]` | Groups to hide from the home page |
153
86
 
154
- Rebase offers several complementary plugins:
87
+ ## Related Packages
155
88
 
156
- - Data Import: Import data from CSV or JSON into Firestore collections
157
- - Data Export: Export collection data to CSV or JSON formats
158
- - Data Enhancement: Generate content using AI for your collections
159
- - Entity History: Track changes to your collection entities
89
+ - `@rebasepro/core` Bridge, registry, and navigation primitives
90
+ - `@rebasepro/ui` Component library used by Studio tools
91
+ - `@rebasepro/admin` The CMS layer (optional peer dep)
92
+ - `@rebasepro/types` Shared type definitions
@@ -682,7 +682,7 @@ function detectCollectionsInResult(code, resultValue, collections) {
682
682
  for (const slug of mentionedSlugs) {
683
683
  const normalised = toSnakeCase(slug);
684
684
  const col = collections.find((c2) => {
685
- const tableName = c2.table || toSnakeCase(c2.slug);
685
+ const tableName = ("table" in c2 ? c2.table : void 0) || toSnakeCase(c2.slug);
686
686
  return c2.slug === slug || tableName === normalised || toSnakeCase(c2.slug) === normalised;
687
687
  });
688
688
  if (col) {
@@ -1294,4 +1294,4 @@ function _temp(t0) {
1294
1294
  export {
1295
1295
  JSEditor
1296
1296
  };
1297
- //# sourceMappingURL=JSEditor-BCSoElPg.js.map
1297
+ //# sourceMappingURL=JSEditor-DfwRLBZg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JSEditor-DfwRLBZg.js","sources":["../src/components/JSEditor/JSMonacoEditor.tsx","../src/components/JSEditor/JSEditorSidebar.tsx","../src/components/JSEditor/JSEditor.tsx"],"sourcesContent":["\nimport React, { useRef, useEffect } from \"react\";\nimport Editor, { Monaco, OnMount } from \"@monaco-editor/react\";\nimport type { editor } from \"monaco-editor\";\nimport { cls, defaultBorderMixin, FileIcon } from \"@rebasepro/ui\";\nimport { useModeController } from \"@rebasepro/core\";\n\n/**\n * Shape of `monaco.languages.typescript` at runtime.\n * The bundled type stubs mark this API as deprecated, but it is fully functional.\n */\ninterface MonacoTypeScriptApi {\n typescriptDefaults: {\n setCompilerOptions(options: Record<string, unknown>): void;\n setDiagnosticsOptions(options: Record<string, unknown>): void;\n addExtraLib(content: string, filePath: string): void;\n };\n ScriptTarget: Record<string, number>;\n ModuleKind: Record<string, number>;\n}\n\n/** Ambient type definitions for the Rebase client SDK injected into Monaco. */\nconst REBASE_CLIENT_TYPES = `\n// ─── Rebase Client SDK Type Definitions ─────────────────────────────\n\ninterface Entity<M extends Record<string, any> = any> {\n id: string | number;\n path: string;\n values: M;\n}\n\ninterface FindParams {\n limit?: number;\n offset?: number;\n page?: number;\n where?: Record<string, string>;\n orderBy?: string;\n include?: string[];\n searchString?: string;\n}\n\ninterface FindResponse<M extends Record<string, any> = any> {\n data: Entity<M>[];\n meta: {\n total: number;\n limit: number;\n offset: number;\n hasMore: boolean;\n };\n}\n\ntype FilterOperator = \"=\" | \"!=\" | \">\" | \">=\" | \"<\" | \"<=\" | \"in\" | \"not-in\" | \"array-contains\" | \"array-contains-any\" | \"is\" | \"is_not\" | \"like\" | \"ilike\";\n\ninterface QueryBuilder<M extends Record<string, any> = any> {\n where(column: keyof M & string, operator: FilterOperator, value: any): QueryBuilder<M>;\n orderBy(column: keyof M & string, direction?: \"asc\" | \"desc\"): QueryBuilder<M>;\n limit(count: number): QueryBuilder<M>;\n offset(count: number): QueryBuilder<M>;\n search(searchString: string): QueryBuilder<M>;\n find(): Promise<FindResponse<M>>;\n findOne(): Promise<Entity<M> | undefined>;\n count(): Promise<number>;\n}\n\ninterface CollectionClient<M extends Record<string, any> = any> {\n find(params?: FindParams): Promise<FindResponse<M>>;\n findById(id: string | number): Promise<Entity<M> | undefined>;\n create(data: Partial<M>, id?: string | number): Promise<Entity<M>>;\n update(id: string | number, data: Partial<M>): Promise<Entity<M>>;\n delete(id: string | number): Promise<void>;\n where(column: keyof M & string, operator: FilterOperator, value: any): QueryBuilder<M>;\n orderBy(column: keyof M & string, direction?: \"asc\" | \"desc\"): QueryBuilder<M>;\n limit(count: number): QueryBuilder<M>;\n offset(count: number): QueryBuilder<M>;\n search(searchString: string): QueryBuilder<M>;\n listen?(params: FindParams | undefined, onUpdate: (response: FindResponse<M>) => void, onError?: (error: Error) => void): () => void;\n listenById?(id: string | number, onUpdate: (entity: Entity<M> | undefined) => void, onError?: (error: Error) => void): () => void;\n count?(params?: FindParams): Promise<number>;\n}\n\ninterface RebaseUser {\n uid: string;\n email: string | null;\n displayName: string | null;\n photoURL: string | null;\n emailVerified?: boolean;\n roles?: string[];\n providerId: string;\n isAnonymous: boolean;\n}\n\ninterface RebaseSession {\n accessToken: string;\n refreshToken: string;\n expiresAt: number;\n user: RebaseUser;\n}\n\ntype AuthChangeEvent = 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED' | 'USER_UPDATED';\n\ninterface RebaseAuth {\n signInWithEmail(email: string, password: string): Promise<{ user: RebaseUser; accessToken: string; refreshToken: string }>;\n signUp(email: string, password: string, displayName?: string): Promise<{ user: RebaseUser; accessToken: string; refreshToken: string }>;\n signInWithGoogle(idToken: string): Promise<{ user: RebaseUser; accessToken: string; refreshToken: string }>;\n signOut(): Promise<void>;\n refreshSession(): Promise<RebaseSession>;\n getUser(): Promise<RebaseUser>;\n updateUser(updates: { displayName?: string; photoURL?: string }): Promise<RebaseUser>;\n resetPasswordForEmail(email: string): Promise<{ success: boolean; message: string }>;\n resetPassword(token: string, password: string): Promise<{ success: boolean; message: string }>;\n changePassword(oldPassword: string, newPassword: string): Promise<{ success: boolean; message: string }>;\n sendVerificationEmail(): Promise<{ success: boolean; message: string }>;\n verifyEmail(token: string): Promise<{ success: boolean; message: string }>;\n getSessions(): Promise<RebaseSession[]>;\n revokeSession(sessionId: string): Promise<{ success: boolean }>;\n revokeAllSessions(): Promise<{ success: boolean }>;\n getSession(): RebaseSession | null;\n onAuthStateChange(callback: (event: AuthChangeEvent, session: RebaseSession | null) => void): () => void;\n}\n\ninterface AdminUser {\n uid: string;\n email: string;\n displayName: string | null;\n photoURL: string | null;\n provider: string;\n roles: string[];\n createdAt: string;\n updatedAt: string;\n}\n\ninterface RebaseAdmin {\n listUsers(): Promise<{ users: AdminUser[] }>;\n getUser(userId: string): Promise<{ user: AdminUser }>;\n createUser(data: { email: string; displayName?: string; password?: string; roles?: string[] }): Promise<{ user: AdminUser }>;\n updateUser(userId: string, data: { email?: string; displayName?: string; password?: string; roles?: string[] }): Promise<{ user: AdminUser }>;\n deleteUser(userId: string): Promise<{ success: boolean }>;\n bootstrap(): Promise<{ success: boolean; message: string; user: { uid: string; roles: string[] } }>;\n}\n\ninterface UploadFileProps {\n file: FileIcon;\n fileName?: string;\n path?: string;\n metadata?: Record<string, unknown>;\n bucket?: string;\n}\n\ninterface UploadFileResult {\n path: string;\n bucket?: string;\n downloadUrl?: string;\n}\n\ninterface DownloadConfig {\n url: string | null;\n fileNotFound?: boolean;\n metadata?: Record<string, unknown>;\n}\n\ninterface StorageSource {\n putObject(props: UploadFileProps): Promise<UploadFileResult>;\n getSignedUrl(pathOrUrl: string, bucket?: string): Promise<DownloadConfig>;\n getObject(path: string, bucket?: string): Promise<FileIcon | null>;\n deleteObject(path: string, bucket?: string): Promise<void>;\n listObjects(path: string, options?: { bucket?: string; maxResults?: number; pageToken?: string }): Promise<unknown>;\n}\n\ntype RebaseData = {\n /** Look up a collection by slug. */\n collection(slug: string): CollectionClient;\n} & {\n /** Dynamic collection access — e.g. client.data.authors */\n [collectionSlug: string]: CollectionClient;\n};\n\n/**\n * The Rebase client instance. Use \\`client.data\\`, \\`client.auth\\`, \\`client.admin\\`,\n * \\`client.storage\\`, and \\`client.call()\\` to interact with your Rebase backend.\n *\n * @example\n * // Query a collection\n * const result = await client.data.products.find({ limit: 10 });\n *\n * // Create a record\n * await client.data.products.create({ name: \"Camera\", price: 299 });\n *\n * // Fluent query\n * const expensive = await client.data.products.where(\"price\", \">\", 100).orderBy(\"price\", \"desc\").limit(5).find();\n *\n * // Auth\n * const session = client.auth.getSession();\n *\n * // Admin\n * const { users } = await client.admin.listUsers();\n *\n * // Custom endpoint\n * const result = await client.call(\"/my-endpoint\", { myData: 123 });\n */\ninterface RebaseClient {\n /** Data access — dynamic collection accessors */\n data: RebaseData;\n /** Authentication methods */\n auth: RebaseAuth;\n /** User/role admin methods */\n admin: RebaseAdmin;\n /** Storage operations */\n storage?: StorageSource;\n /** Call a custom server-side endpoint */\n call<T = unknown>(endpoint: string, payload?: unknown): Promise<T>;\n /** Direct collection access (shorthand) */\n [collectionSlug: string]: unknown;\n}\n\n/** The pre-configured client instance. Already authenticated with the current user session. */\ndeclare const client: RebaseClient;\n\n/** Execution context with user and collection information. */\ninterface JSEditorContext {\n /** The user the script is running as. */\n user: {\n uid: string;\n displayName: string | null;\n email: string | null;\n roles?: string[];\n } | null;\n /** Registered collections with their property names. */\n collections: Array<{\n slug: string;\n name: string;\n properties: string[];\n }>;\n}\n\n/** Execution context — contains info about the selected user and registered collections. */\ndeclare const context: JSEditorContext;\n`;\n\nexport type CollectionInfo = {\n slug: string;\n name: string;\n properties: string[];\n};\n\nexport type JSMonacoEditorProps = {\n value: string;\n onChange: (value: string | undefined) => void;\n onRun?: (selectedText?: string) => void;\n className?: string;\n readOnly?: boolean;\n autoFocus?: boolean;\n /** Collection slugs for basic autocomplete */\n collectionSlugs?: string[];\n /** Full collection info with property names for richer type generation */\n collections?: CollectionInfo[];\n};\n\nexport const JSMonacoEditor = ({\n value,\n onChange,\n onRun,\n className,\n readOnly = false,\n autoFocus = true,\n collectionSlugs = [],\n collections = []\n}: JSMonacoEditorProps) => {\n const { mode } = useModeController();\n const editorRef = useRef<editor.IStandaloneCodeEditor | null>(null);\n const monacoRef = useRef<Monaco | null>(null);\n const onRunRef = useRef(onRun);\n onRunRef.current = onRun;\n const typesRegisteredRef = useRef(false);\n\n const handleEditorOnMount: OnMount = (editorInstance, monaco) => {\n editorRef.current = editorInstance;\n monacoRef.current = monaco;\n\n // Register Cmd/Ctrl+Enter to run\n editorInstance.addAction({\n id: \"run-script\",\n label: \"Run Script\",\n keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter],\n contextMenuGroupId: \"operation\",\n contextMenuOrder: 0,\n run: () => {\n if (onRunRef.current) {\n const selection = editorInstance.getSelection();\n let selectedText: string | undefined;\n if (selection && !selection.isEmpty()) {\n selectedText = editorInstance.getModel()?.getValueInRange(selection)?.trim();\n }\n onRunRef.current(selectedText || undefined);\n }\n }\n });\n\n // Configure TypeScript/JavaScript defaults for richer completion\n if (!typesRegisteredRef.current) {\n typesRegisteredRef.current = true;\n\n // Configure TS compiler for modern JS with top-level await\n // Note: cast through `any` because the bundled type stubs mark\n // `monaco.languages.typescript` as deprecated while the runtime\n // API is fully functional.\n const ts = (monaco.languages as unknown as { typescript: MonacoTypeScriptApi }).typescript;\n ts.typescriptDefaults.setCompilerOptions({\n target: ts.ScriptTarget.ESNext,\n module: ts.ModuleKind.ESNext,\n allowJs: true,\n checkJs: false,\n strict: false,\n noEmit: true,\n allowNonTsExtensions: true\n });\n\n // Suppress diagnostics that don't apply to our script context.\n // Scripts are executed inside `new AsyncFunction(...)` at runtime,\n // so top-level `await` (1375) and `return` (1108) are valid.\n ts.typescriptDefaults.setDiagnosticsOptions({\n diagnosticCodesToIgnore: [1375, 1108]\n });\n\n // Inject the Rebase Client SDK type definitions\n ts.typescriptDefaults.addExtraLib(\n REBASE_CLIENT_TYPES,\n \"ts:rebase-client.d.ts\"\n );\n\n // Generate collection-specific types from registered collections\n if (collections.length > 0) {\n const lines: string[] = [];\n for (const col of collections) {\n // Generate a typed interface for each collection\n const ifaceName = col.slug.replace(/[^a-zA-Z0-9_]/g, \"_\");\n const propsType = col.properties.length > 0\n ? `{ ${col.properties.map(p => `${p}: any`).join(\"; \")} }`\n : \"Record<string, any>\";\n lines.push(`/** Collection: ${col.name} (${col.slug}) */`);\n lines.push(`interface ${ifaceName}_Row ${propsType}`);\n lines.push(`declare namespace client.data { const ${col.slug}: CollectionClient<${ifaceName}_Row>; }`);\n }\n ts.typescriptDefaults.addExtraLib(\n lines.join(\"\\n\"),\n \"ts:rebase-collections.d.ts\"\n );\n } else if (collectionSlugs.length > 0) {\n // Fallback: just slug names without property info\n const collectionHints = collectionSlugs.map(slug =>\n `/** Collection: ${slug} */\\ndeclare namespace client.data { const ${slug}: CollectionClient; }`\n ).join(\"\\n\");\n ts.typescriptDefaults.addExtraLib(\n collectionHints,\n \"ts:rebase-collections.d.ts\"\n );\n }\n }\n\n if (autoFocus) {\n editorInstance.focus();\n }\n };\n\n return (\n <div className={cls(\"relative w-full h-full overflow-hidden\", className)}>\n <Editor\n height=\"100%\"\n defaultLanguage=\"typescript\"\n path=\"rebase-script.ts\"\n value={value}\n onChange={onChange}\n onMount={handleEditorOnMount}\n theme={mode === \"dark\" ? \"vs-dark\" : \"vs\"}\n options={{\n minimap: { enabled: false },\n fontSize: 14,\n lineNumbers: \"on\",\n scrollBeyondLastLine: false,\n automaticLayout: true,\n readOnly,\n tabSize: 2,\n wordWrap: \"on\",\n suggestOnTriggerCharacters: true,\n quickSuggestions: true,\n parameterHints: { enabled: true }\n }}\n />\n </div>\n );\n};\n","\nimport React, { useState } from \"react\";\nimport {\n cls,\n defaultBorderMixin,\n IconButton,\n iconSize,\n PlusIcon,\n Tab,\n Tabs,\n Tooltip,\n Trash2Icon,\n Typography\n} from \"@rebasepro/ui\";\n\nexport interface JSSnippet {\n id: string;\n name: string;\n code: string;\n createdAt: number;\n isFavorite?: boolean;\n}\n\ninterface CollectionInfo {\n slug: string;\n properties: string[];\n}\n\ninterface JSEditorSidebarProps {\n collections: CollectionInfo[];\n snippets: JSSnippet[];\n history: string[];\n onSelectSnippet: (code: string) => void;\n onDeleteSnippet: (id: string) => void;\n onInsertCode: (code: string) => void;\n}\n\nconst QUICK_REFERENCE: { label: string; code: string; description: string }[] = [\n {\n label: \"Find all\",\n code: \"const result = await client.data.collection(\\\"COLLECTION\\\").find({ limit: 20 });\\nreturn result;\",\n description: \"Fetch records with pagination\"\n },\n {\n label: \"Find by ID\",\n code: \"const item = await client.data.collection(\\\"COLLECTION\\\").findById(\\\"ID\\\");\\nreturn item;\",\n description: \"Fetch a single record\"\n },\n {\n label: \"Create\",\n code: \"const created = await client.data.collection(\\\"COLLECTION\\\").create({\\n // your fields here\\n});\\nreturn created;\",\n description: \"Insert a new record\"\n },\n {\n label: \"Update\",\n code: \"const updated = await client.data.collection(\\\"COLLECTION\\\").update(\\\"ID\\\", {\\n // fields to update\\n});\\nreturn updated;\",\n description: \"Update an existing record\"\n },\n {\n label: \"Delete\",\n code: \"await client.data.collection(\\\"COLLECTION\\\").delete(\\\"ID\\\");\\nreturn { success: true };\",\n description: \"Delete a record\"\n },\n {\n label: \"Fluent query\",\n code: \"const result = await client.data.collection(\\\"COLLECTION\\\")\\n .where(\\\"field\\\", \\\">\\\", value)\\n .orderBy(\\\"field\\\", \\\"desc\\\")\\n .limit(10)\\n .find();\\nreturn result;\",\n description: \"Chained query builder\"\n },\n {\n label: \"Auth: Current session\",\n code: \"const session = client.auth.getSession();\\nreturn session;\",\n description: \"Get current auth session\"\n },\n {\n label: \"Admin: List users\",\n code: \"const { users } = await client.admin.listUsers();\\nreturn users;\",\n description: \"List all registered users\"\n },\n {\n label: \"Custom endpoint\",\n code: \"const result = await client.call(\\\"/my-endpoint\\\", { key: \\\"value\\\" });\\nreturn result;\",\n description: \"Call a custom API endpoint\"\n }\n];\n\nexport const JSEditorSidebar = ({\n collections,\n snippets,\n history,\n onSelectSnippet,\n onDeleteSnippet,\n onInsertCode\n}: JSEditorSidebarProps) => {\n const [activeTab, setActiveTab] = useState<\"collections\" | \"snippets\" | \"history\" | \"reference\">(\"collections\");\n\n return (\n <div className={cls(\"flex flex-col h-full w-full bg-white dark:bg-surface-950 border-r\", defaultBorderMixin)}>\n <Tabs value={activeTab} onValueChange={(v) => setActiveTab(v as \"collections\" | \"snippets\" | \"history\" | \"reference\")} variant=\"boxy\" className=\"border-b border-surface-200 dark:border-surface-950\">\n <Tab value=\"collections\">\n <Tooltip title=\"Browse collections\">\n <span className=\"text-xs\">Collections</span>\n </Tooltip>\n </Tab>\n <Tab value=\"reference\">\n <Tooltip title=\"SDK quick reference\">\n <span className=\"text-xs\">Reference</span>\n </Tooltip>\n </Tab>\n <Tab value=\"snippets\">\n <span className=\"text-xs\">Snippets</span>\n </Tab>\n <Tab value=\"history\">\n <span className=\"text-xs\">History</span>\n </Tab>\n </Tabs>\n\n <div className=\"flex-grow overflow-hidden relative\">\n {/* Collections browser */}\n {activeTab === \"collections\" && (\n <div className=\"flex flex-col h-full\">\n <div className={cls(\"flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]\", defaultBorderMixin)}>\n <Typography variant=\"caption\" className=\"font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark\">\n Collections\n </Typography>\n </div>\n <div className=\"flex-grow overflow-y-auto p-1 space-y-1 no-scrollbar\">\n {collections.length === 0 ? (\n <div className=\"p-4 text-center\">\n <Typography variant=\"caption\" className=\"text-text-disabled dark:text-text-disabled-dark\">\n No collections found\n </Typography>\n </div>\n ) : (\n collections.map(col => (\n <CollectionItem\n key={col.slug}\n collection={col}\n onInsertCode={onInsertCode}\n />\n ))\n )}\n </div>\n </div>\n )}\n\n {/* Quick reference */}\n {activeTab === \"reference\" && (\n <div className=\"flex flex-col h-full\">\n <div className={cls(\"flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]\", defaultBorderMixin)}>\n <Typography variant=\"caption\" className=\"font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark\">\n SDK Reference\n </Typography>\n </div>\n <div className=\"flex-grow overflow-y-auto p-2 space-y-2 no-scrollbar\">\n {QUICK_REFERENCE.map((ref, i) => (\n <div\n key={i}\n className={cls(\n \"group p-2.5 rounded-lg border hover:border-primary/40 dark:hover:border-primary/40\",\n \"bg-white dark:bg-surface-900 transition-all cursor-pointer\",\n defaultBorderMixin\n )}\n onClick={() => onInsertCode(ref.code)}\n >\n <div className=\"flex items-center justify-between mb-1\">\n <Typography variant=\"body2\" className=\"text-text-primary dark:text-text-primary-dark font-semibold text-[13px]\">\n {ref.label}\n </Typography>\n <svg className=\"w-3.5 h-3.5 text-text-disabled group-hover:text-primary transition-colors\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"/>\n </svg>\n </div>\n <Typography variant=\"caption\" className=\"text-text-disabled dark:text-text-disabled-dark text-[10px] leading-tight\">\n {ref.description}\n </Typography>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Snippets */}\n {activeTab === \"snippets\" && (() => {\n const favorites = snippets.filter(s => s.isFavorite);\n const others = snippets.filter(s => !s.isFavorite);\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className={cls(\"flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]\", defaultBorderMixin)}>\n <Typography variant=\"caption\" className=\"font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark\">Snippets</Typography>\n </div>\n <div className=\"flex-grow overflow-y-auto p-2 space-y-2 no-scrollbar\">\n {snippets.length === 0 ? (\n <div className=\"p-4 text-center\">\n <Typography variant=\"caption\" className=\"text-text-disabled dark:text-text-disabled-dark\">\n No saved snippets yet. Use the save button to store reusable code.\n </Typography>\n </div>\n ) : (\n <>\n {favorites.length > 0 && (\n <div className=\"mb-3\">\n <Typography variant=\"caption\" className=\"text-[10px] font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark mb-2 px-1 flex items-center\">\n <svg className=\"w-3 h-3 mr-1 text-amber-500\" fill=\"currentColor\" viewBox=\"0 0 20 20\"><path d=\"M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z\"/></svg>\n Favorites\n </Typography>\n <div className=\"space-y-2\">\n {favorites.map(snippet => (\n <SnippetItem key={snippet.id} snippet={snippet} onSelect={onSelectSnippet} onDelete={onDeleteSnippet}/>\n ))}\n </div>\n </div>\n )}\n {others.length > 0 && (\n <div>\n {favorites.length > 0 && (\n <Typography variant=\"caption\" className=\"text-[10px] font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark mb-2 px-1\">\n Others\n </Typography>\n )}\n <div className=\"space-y-2\">\n {others.map(snippet => (\n <SnippetItem key={snippet.id} snippet={snippet} onSelect={onSelectSnippet} onDelete={onDeleteSnippet}/>\n ))}\n </div>\n </div>\n )}\n </>\n )}\n </div>\n </div>\n );\n })()}\n\n {/* History */}\n {activeTab === \"history\" && (\n <div className=\"flex flex-col h-full\">\n <div className={cls(\"flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]\", defaultBorderMixin)}>\n <Typography variant=\"caption\" className=\"font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark\">History</Typography>\n </div>\n <div className=\"flex-grow overflow-y-auto p-1 space-y-1 no-scrollbar\">\n {history.length === 0 ? (\n <div className=\"p-4 text-center\">\n <Typography variant=\"caption\" className=\"text-text-disabled dark:text-text-disabled-dark\">\n No execution history yet\n </Typography>\n </div>\n ) : (\n [...history].reverse().map((code, i) => (\n <div\n key={i}\n className=\"p-2 py-1.5 rounded hover:bg-surface-100 dark:hover:bg-surface-950 cursor-pointer group transition-colors flex items-start\"\n onClick={() => onSelectSnippet(code)}\n >\n <svg className=\"w-3 h-3 mt-1 mr-2 text-text-disabled dark:text-text-disabled-dark group-hover:text-primary transition-colors flex-shrink-0\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z\"/>\n </svg>\n <Typography variant=\"caption\" className=\"text-text-secondary dark:text-text-secondary-dark group-hover:text-text-primary dark:group-hover:text-text-primary-dark text-[11px] line-clamp-2 leading-tight flex-grow font-mono\">\n {code.length > 120 ? code.substring(0, 120) + \"…\" : code}\n </Typography>\n </div>\n ))\n )}\n </div>\n </div>\n )}\n </div>\n </div>\n );\n};\n\n// ─── Sub-components ──────────────────────────────────────────────────\n\nfunction CollectionItem({ collection, onInsertCode }: { collection: CollectionInfo; onInsertCode: (code: string) => void }) {\n const [expanded, setExpanded] = useState(false);\n\n return (\n <div>\n <div\n className=\"flex items-center p-1 cursor-pointer hover:bg-surface-100 dark:hover:bg-surface-950 rounded transition-colors group relative\"\n onClick={() => setExpanded(!expanded)}\n >\n <svg\n className={cls(\"w-3 h-3 mr-1 transition-transform\", expanded && \"rotate-90\")}\n fill=\"currentColor\" viewBox=\"0 0 20 20\"\n >\n <path d=\"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z\"/>\n </svg>\n <svg className=\"w-3.5 h-3.5 mr-1 shrink-0 text-text-disabled dark:text-text-disabled-dark\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4\"/>\n </svg>\n <Typography variant=\"body2\" className=\"text-text-secondary dark:text-text-secondary-dark text-xs truncate flex-1 min-w-0\">\n {collection.slug}\n </Typography>\n <Tooltip title=\"Insert find() snippet\">\n <IconButton\n size=\"smallest\"\n className=\"opacity-0 group-hover:opacity-100 text-text-disabled hover:text-primary transition-all\"\n onClick={(e) => {\n e.stopPropagation();\n onInsertCode(`const result = await client.data.${collection.slug}.find({ limit: 20 });\\nreturn result;`);\n }}\n >\n <PlusIcon size={iconSize.smallest}/>\n </IconButton>\n </Tooltip>\n </div>\n {expanded && collection.properties.length > 0 && (\n <div className={cls(\"ml-5 mt-1 space-y-0.5 border-l\", defaultBorderMixin)}>\n {collection.properties.map(prop => (\n <div\n key={prop}\n className=\"flex items-center p-1 pl-2 hover:bg-surface-50 dark:hover:bg-surface-950 rounded-r cursor-pointer transition-colors group/prop relative min-h-[28px]\"\n onClick={() => onInsertCode(`\"${prop}\"`)}\n >\n <svg className=\"w-3 h-3 mr-1.5 text-text-disabled dark:text-text-disabled-dark shrink-0\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1.5} d=\"M9 4.5v15m6-15v15m-10.5-1.5h15c.621 0 1.125-.504 1.125-1.125V5.625c0-.621-.504-1.125-1.125-1.125h-15c-.621 0-1.125.504-1.125 1.125v12.75c0 .621.504 1.125 1.125 1.125Z\"/></svg>\n <Typography variant=\"caption\" className=\"text-text-primary dark:text-text-primary-dark text-[11px] truncate flex-grow font-mono\">{prop}</Typography>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction SnippetItem({ snippet, onSelect, onDelete }: { snippet: JSSnippet; onSelect: (code: string) => void; onDelete: (id: string) => void }) {\n return (\n <div\n className={cls(\"group p-2 rounded border hover:border-surface-400 dark:hover:border-surface-600 bg-white dark:bg-surface-900 transition-all cursor-pointer relative\", defaultBorderMixin)}\n onClick={() => onSelect(snippet.code)}\n >\n <Typography variant=\"body2\" className=\"text-text-primary dark:text-text-primary-dark font-medium text-[13px] truncate pr-6\">\n {snippet.name}\n </Typography>\n <Typography variant=\"caption\" className=\"text-text-secondary dark:text-text-secondary-dark text-[10px] block mt-1 truncate font-mono\">\n {snippet.code}\n </Typography>\n <IconButton\n size=\"smallest\"\n className=\"absolute right-1 top-1 opacity-0 group-hover:opacity-100 text-text-disabled hover:text-red-500 transition-opacity\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete(snippet.id);\n }}\n >\n <Trash2Icon size={iconSize.smallest}/>\n </IconButton>\n </div>\n );\n}\n","\nimport React, { useState, useEffect, useCallback, useRef, useMemo } from \"react\";\nimport { Highlight, themes } from \"prism-react-renderer\";\nimport { toSnakeCase } from \"@rebasepro/utils\";\nimport {\n Button,\n CellRendererParams,\n Chip,\n CircularProgress,\n cls,\n defaultBorderMixin,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n DownloadIcon,\n IconButton,\n iconSize,\n Menu,\n MenuIcon,\n MenuItem,\n MoreVerticalIcon,\n PencilIcon,\n PlayIcon,\n PlusIcon,\n ResizablePanels,\n SaveIcon,\n Tab,\n Tabs,\n TerminalIcon,\n TextField,\n Tooltip,\n Typography,\n VirtualTable,\n VirtualTableColumn,\n XIcon\n} from \"@rebasepro/ui\";\nimport { useStudioUrlController, useStudioCollectionRegistry, useStudioSideEntityController } from \"@rebasepro/core\";\nimport { useRebaseContext, useRebaseClient, useSnackbarController, useApiConfig, useTranslation, useModeController, ErrorView, SelectableUser, IconForView } from \"@rebasepro/core\";\nimport { EntityCollection } from \"@rebasepro/types\";\nimport { createRebaseClient } from \"@rebasepro/client\";\nimport { JSMonacoEditor } from \"./JSMonacoEditor\";\nimport { JSEditorSidebar, JSSnippet } from \"./JSEditorSidebar\";\nimport { AuthSimulationSelector } from \"../AuthSimulationSelector\";\n\n// ─── Types ───────────────────────────────────────────────────────────\n\ninterface ConsoleEntry {\n type: \"log\" | \"warn\" | \"error\" | \"info\";\n args: unknown[];\n timestamp: number;\n}\n\ninterface ExecutionResult {\n value: unknown;\n console: ConsoleEntry[];\n duration: number;\n error?: string;\n timestamp: number;\n}\n\ninterface EditorTab {\n id: string;\n name: string;\n code: string;\n}\n\n// SelectedUser is now SelectableUser from @rebasepro/core\n\n// ─── Constants ───────────────────────────────────────────────────────\n\nconst STORAGE_PREFIX = \"rebase_js_\";\nconst MAX_HISTORY = 50;\n\nconst DEFAULT_CODE = `// Available: client (RebaseClient)\n// Press Cmd+Enter (Ctrl+Enter) to run\n//\n// Examples:\n// const result = await client.data.collection(\"your_collection\").find({ limit: 10 });\n// const users = await client.admin.listUsers();\n// const session = client.auth.getSession();\n\nconst result = await client.data.collection(\"your_collection\").find({ limit: 10 });\nreturn result;\n`;\n\n// ─── Helpers ─────────────────────────────────────────────────────────\n\nfunction loadFromStorage<T>(key: string, fallback: T): T {\n try {\n const raw = localStorage.getItem(STORAGE_PREFIX + key);\n return raw ? JSON.parse(raw) : fallback;\n } catch {\n return fallback;\n }\n}\n\nfunction saveToStorage<T>(key: string, value: T) {\n try {\n localStorage.setItem(STORAGE_PREFIX + key, JSON.stringify(value));\n } catch { /* quota */ }\n}\n\nfunction formatJSON(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n}\n\n// ─── Helpers: Collection matching for JS results ────────────────────\n\ninterface MatchedJSCollection {\n collectionSlug: string;\n collection: EntityCollection;\n pkColumn: string;\n}\n\n/**\n * Given the raw SDK result, try to detect which collections are present.\n * JS SDK results typically come back as `{ data: [{ id, values }] }` or plain arrays.\n * The heuristic: if the executed code contains `collection(\"<slug>\")` or `client.data.<slug>`,\n * and the result has rows with an \"id\" column, we match those slugs.\n */\nfunction detectCollectionsInResult(\n code: string,\n resultValue: unknown,\n collections: EntityCollection[]\n): MatchedJSCollection[] {\n if (!resultValue || !collections?.length) return [];\n\n // Extract collection slugs mentioned in the code\n const mentionedSlugs = new Set<string>();\n\n // Match: collection(\"slug\") or collection('slug')\n const collectionCallRegex = /\\.collection\\([\"']([^\"']+)[\"']\\)/g;\n let m: RegExpExecArray | null;\n while ((m = collectionCallRegex.exec(code)) !== null) {\n mentionedSlugs.add(m[1]);\n }\n\n // Match: client.data.<slug>. (dot-access pattern)\n const dotAccessRegex = /client\\.data\\.([a-zA-Z_][a-zA-Z0-9_]*)\\./g;\n while ((m = dotAccessRegex.exec(code)) !== null) {\n if (![\"collection\", \"find\", \"findById\", \"create\", \"update\", \"delete\"].includes(m[1])) {\n mentionedSlugs.add(m[1]);\n }\n }\n\n if (mentionedSlugs.size === 0) return [];\n\n // Check if result has rows with an \"id\" field\n let rows: Record<string, unknown>[] = [];\n const rv = resultValue as Record<string, unknown>;\n if (rv?.data && Array.isArray(rv.data)) {\n rows = rv.data;\n } else if (Array.isArray(resultValue)) {\n rows = resultValue;\n }\n\n const hasId = rows.length > 0 && rows.some(r => r?.id != null);\n if (!hasId) return [];\n\n const matched: MatchedJSCollection[] = [];\n for (const slug of mentionedSlugs) {\n const normalised = toSnakeCase(slug);\n const col = collections.find(c => {\n const tableName = (\"table\" in c ? c.table : undefined) || toSnakeCase(c.slug);\n return c.slug === slug || tableName === normalised || toSnakeCase(c.slug) === normalised;\n });\n if (col) {\n matched.push({\n collectionSlug: col.slug,\n collection: col,\n pkColumn: \"id\"\n });\n }\n }\n\n return matched;\n}\n\n// ─── Main Component ─────────────────────────────────────────────────\n\nexport function JSEditor() {\n // Contexts\n const rebaseContext = useRebaseContext();\n const rebaseClient = useRebaseClient();\n const apiConfig = useApiConfig();\n const snackbar = useSnackbarController();\n const collectionRegistry = useStudioCollectionRegistry();\n const sideEntityController = useStudioSideEntityController();\n const { t } = useTranslation();\n\n // User management for the \"Run as\" picker\n const userManagement = rebaseContext.userManagement;\n const currentUser = rebaseContext.authController?.user;\n\n // State\n const [tabs, setTabs] = useState<EditorTab[]>(() =>\n loadFromStorage(\"tabs\", [{ id: \"1\",\nname: \"Script 1\",\ncode: DEFAULT_CODE }])\n );\n const [activeTabId, setActiveTabId] = useState<string>(() =>\n loadFromStorage(\"activeTab\", \"1\")\n );\n const [result, setResult] = useState<ExecutionResult | null>(null);\n const [isRunning, setIsRunning] = useState(false);\n const [snippets, setSnippets] = useState<JSSnippet[]>(() =>\n loadFromStorage(\"snippets\", [])\n );\n const [history, setHistory] = useState<string[]>(() =>\n loadFromStorage(\"history\", [])\n );\n const [showSaveDialog, setShowSaveDialog] = useState(false);\n const [snippetName, setSnippetName] = useState(\"\");\n const [resultView, setResultView] = useState<\"json\" | \"table\" | \"console\">(\"json\");\n\n // \"Run as\" user state — null means \"self\" (current admin)\n const [selectedUser, setSelectedUser] = useState<SelectableUser | null>(null);\n const [authMode, setAuthMode] = useState<\"jwt\" | \"none\">(\"jwt\");\n\n const [sidebarSize, setSidebarSize] = useState<number>(() => {\n try {\n const stored = localStorage.getItem(STORAGE_PREFIX + \"sidebar_size\");\n return stored ? Number(stored) : 18;\n } catch { return 18; }\n });\n const [editorHeight, setEditorHeight] = useState<number>(() => {\n try {\n const stored = localStorage.getItem(STORAGE_PREFIX + \"editor_height\");\n return stored ? Number(stored) : 55;\n } catch { return 55; }\n });\n\n // Derived\n const activeTab = tabs.find(t => t.id === activeTabId) ?? tabs[0];\n\n // Collection info for the sidebar and Monaco\n const collectionInfos = useMemo(() => {\n const collections = collectionRegistry?.collections ?? [];\n return collections.map(col => ({\n slug: col.slug,\n name: col.name,\n properties: Object.keys(col.properties ?? {})\n }));\n }, [collectionRegistry?.collections]);\n\n const collectionSlugs = useMemo(() => collectionInfos.map(c => c.slug), [collectionInfos]);\n\n // Users list for the picker — mapped to SelectableUser shape\n const users = useMemo((): SelectableUser[] => {\n const managed = (userManagement?.users ?? []).map(u => ({\n uid: u.uid,\n displayName: u.displayName,\n email: u.email,\n photoURL: u.photoURL,\n roles: u.roles\n }));\n // Ensure the current user is in the list\n if (currentUser && !managed.some(u => u.uid === currentUser.uid)) {\n managed.unshift({\n uid: currentUser.uid,\n displayName: currentUser.displayName,\n email: currentUser.email,\n photoURL: currentUser.photoURL,\n roles: currentUser.roles\n });\n }\n return managed;\n }, [userManagement?.users, currentUser]);\n\n // Current user as SelectableUser for the popover\n const currentSelectableUser = useMemo((): SelectableUser | null => {\n if (!currentUser) return null;\n return {\n uid: currentUser.uid,\n displayName: currentUser.displayName,\n email: currentUser.email,\n photoURL: currentUser.photoURL,\n roles: currentUser.roles\n };\n }, [currentUser]);\n\n // ─── Persistence ─────────────────────────────────────────────\n\n useEffect(() => { saveToStorage(\"tabs\", tabs); }, [tabs]);\n useEffect(() => { saveToStorage(\"activeTab\", activeTabId); }, [activeTabId]);\n useEffect(() => { saveToStorage(\"snippets\", snippets); }, [snippets]);\n useEffect(() => { saveToStorage(\"history\", history); }, [history]);\n\n useEffect(() => {\n try { localStorage.setItem(STORAGE_PREFIX + \"sidebar_size\", sidebarSize.toString()); } catch { /* ignore */ }\n }, [sidebarSize]);\n\n useEffect(() => {\n try { localStorage.setItem(STORAGE_PREFIX + \"editor_height\", editorHeight.toString()); } catch { /* ignore */ }\n }, [editorHeight]);\n\n // ─── Tab management ──────────────────────────────────────────\n\n const updateActiveCode = useCallback((code: string | undefined) => {\n setTabs(prev => prev.map(t => t.id === activeTabId ? { ...t,\ncode: code ?? \"\" } : t));\n }, [activeTabId]);\n\n const addTab = useCallback(() => {\n const id = String(Date.now());\n const newTab: EditorTab = { id,\nname: `Script ${tabs.length + 1}`,\ncode: DEFAULT_CODE };\n setTabs(prev => [...prev, newTab]);\n setActiveTabId(id);\n }, [tabs.length]);\n\n const closeTab = useCallback((tabId: string) => {\n setTabs(prev => {\n const filtered = prev.filter(t => t.id !== tabId);\n if (filtered.length === 0) {\n const fresh = { id: String(Date.now()),\nname: \"Script 1\",\ncode: DEFAULT_CODE };\n setActiveTabId(fresh.id);\n return [fresh];\n }\n if (activeTabId === tabId) {\n setActiveTabId(filtered[filtered.length - 1].id);\n }\n return filtered;\n });\n }, [activeTabId]);\n\n // ─── Create an authenticated client for execution ────────────\n\n const buildClient = useCallback(async () => {\n const apiUrl = apiConfig?.apiUrl;\n const getAuthToken = apiConfig?.getAuthToken;\n\n if (!apiUrl) {\n throw new Error(\"API URL not configured. Make sure apiUrl is set.\");\n }\n\n if (authMode === \"none\") {\n const client = createRebaseClient({\n baseUrl: apiUrl,\n token: undefined\n });\n return { client, isScoped: true };\n }\n\n // If not running as another user safely reuse the application's global client.\n if (!selectedUser || (currentUser && selectedUser.uid === currentUser.uid)) {\n if (!rebaseClient) {\n throw new Error(\"Application client is not initialized.\");\n }\n return { client: rebaseClient, isScoped: false };\n }\n\n // Get the current auth token\n let token: string | undefined;\n if (getAuthToken) {\n token = (await getAuthToken()) ?? undefined;\n }\n\n if (!token) {\n throw new Error(\"No auth token available. Please sign in first.\");\n }\n\n // Create a fresh 'scoped' client. This enables us to attach custom auth later for this specific execution\n // without mutating the global client.\n const client = createRebaseClient({\n baseUrl: apiUrl,\n token\n });\n\n return { client,\nisScoped: true };\n }, [apiConfig, rebaseClient, selectedUser, currentUser, authMode]);\n\n // ─── Execution engine ────────────────────────────────────────\n\n const executeCode = useCallback(async (codeOverride?: string) => {\n const code = codeOverride ?? activeTab?.code ?? \"\";\n if (!code.trim()) return;\n\n setIsRunning(true);\n setResult(null);\n\n // Add to history\n setHistory(prev => {\n const deduped = prev.filter(h => h !== code);\n return [...deduped, code].slice(-MAX_HISTORY);\n });\n\n const consoleEntries: ConsoleEntry[] = [];\n const startTime = performance.now();\n let scopedClientToCleanUp: { ws?: { disconnect(): void } } | null = null;\n\n // Capture console methods\n const originalConsole = {\n log: console.log,\n warn: console.warn,\n error: console.error,\n info: console.info\n };\n\n const captureConsole = (type: ConsoleEntry[\"type\"]) => (...args: unknown[]) => {\n consoleEntries.push({ type,\nargs,\ntimestamp: Date.now() });\n originalConsole[type](...args);\n };\n\n try {\n console.log = captureConsole(\"log\");\n console.warn = captureConsole(\"warn\");\n console.error = captureConsole(\"error\");\n console.info = captureConsole(\"info\");\n\n // Build an authenticated client\n const { client, isScoped } = await buildClient();\n if (isScoped) {\n scopedClientToCleanUp = client;\n }\n\n // Build context object with useful info about selected user\n const context = {\n user: selectedUser ?? (currentUser ? {\n uid: currentUser.uid,\n displayName: currentUser.displayName,\n email: currentUser.email,\n roles: currentUser.roles\n } : null),\n collections: collectionInfos\n };\n\n // Create async function with `client` and `context` injected\n\n const AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;\n const fn = new AsyncFunction(\"client\", \"context\", code);\n\n const value = await fn(client, context);\n const duration = performance.now() - startTime;\n\n setResult({\n value,\n console: consoleEntries,\n duration,\n timestamp: Date.now()\n });\n\n // Auto-detect best view\n const resultObj = value as Record<string, unknown> | undefined;\n if (resultObj?.data && Array.isArray(resultObj.data)) {\n setResultView(\"table\");\n } else if (consoleEntries.length > 0 && value === undefined) {\n setResultView(\"console\");\n } else {\n setResultView(\"json\");\n }\n } catch (err: unknown) {\n const duration = performance.now() - startTime;\n setResult({\n value: undefined,\n console: consoleEntries,\n duration,\n error: err instanceof Error ? err.message : String(err),\n timestamp: Date.now()\n });\n setResultView(\"json\");\n } finally {\n console.log = originalConsole.log;\n console.warn = originalConsole.warn;\n console.error = originalConsole.error;\n console.info = originalConsole.info;\n setIsRunning(false);\n\n if (scopedClientToCleanUp) {\n // Ensure we disconnect WebSockets to prevent leaking connections\n scopedClientToCleanUp.ws?.disconnect();\n }\n }\n }, [activeTab?.code, buildClient, selectedUser, currentUser, collectionInfos]);\n\n // ─── Snippet management ──────────────────────────────────────\n\n const saveSnippet = useCallback(() => {\n if (!snippetName.trim() || !activeTab?.code.trim()) return;\n const snippet: JSSnippet = {\n id: String(Date.now()),\n name: snippetName.trim(),\n code: activeTab.code,\n createdAt: Date.now()\n };\n setSnippets(prev => [snippet, ...prev]);\n setShowSaveDialog(false);\n setSnippetName(\"\");\n snackbar.open({ type: \"success\",\nmessage: \"Snippet saved\" });\n }, [snippetName, activeTab?.code, snackbar]);\n\n const deleteSnippet = useCallback((id: string) => {\n setSnippets(prev => prev.filter(s => s.id !== id));\n }, []);\n\n // ─── Export ──────────────────────────────────────────────────\n\n const exportResult = useCallback(() => {\n if (!result?.value) return;\n const blob = new Blob([formatJSON(result.value)], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `rebase-result-${Date.now()}.json`;\n a.click();\n URL.revokeObjectURL(url);\n }, [result]);\n\n // ─── Table columns for array data ────────────────────────────\n\n const tableData = useMemo(() => {\n if (!result?.value) return { columns: [] as VirtualTableColumn[],\ndata: [] as Record<string, unknown>[] };\n\n let rows: Record<string, unknown>[] = [];\n const val = result.value as Record<string, unknown>;\n if (val?.data && Array.isArray(val.data)) {\n rows = (val.data as Record<string, unknown>[]).map((entity) => ({\n id: entity.id,\n ...(entity.values as Record<string, unknown> ?? {}),\n ...(entity.values ? {} : entity)\n }));\n } else if (Array.isArray(result.value)) {\n rows = result.value;\n }\n\n if (rows.length === 0) return { columns: [] as VirtualTableColumn[],\ndata: [] as Record<string, unknown>[] };\n\n const keys = new Set<string>();\n rows.slice(0, 20).forEach(row => {\n if (row && typeof row === \"object\") {\n Object.keys(row).forEach(k => keys.add(k));\n }\n });\n\n const columns: VirtualTableColumn[] = Array.from(keys).map(key => ({\n key,\n title: key,\n width: key === \"id\" ? 100 : 200\n }));\n\n return { columns,\ndata: rows };\n }, [result]);\n\n // ─── Matched collections for entity actions ──────────────────\n\n const matchedCollections = useMemo(() => {\n if (!result?.value || result.error) return [];\n return detectCollectionsInResult(\n activeTab?.code ?? \"\",\n result.value,\n collectionRegistry?.collections ?? []\n );\n }, [result, activeTab?.code, collectionRegistry?.collections]);\n\n const getRowEntityActions = useCallback((rowData: Record<string, unknown>): { collection: MatchedJSCollection; entityId: string | number }[] => {\n if (!rowData || matchedCollections.length === 0) return [];\n return matchedCollections\n .filter(mc => rowData[mc.pkColumn] != null)\n .map(mc => ({\n collection: mc,\n entityId: rowData[mc.pkColumn] as string | number\n }));\n }, [matchedCollections]);\n\n // ─── Export handlers ─────────────────────────────────────────\n\n const handleExportCSV = useCallback(() => {\n if (tableData.data.length === 0) return;\n const headers = tableData.columns.map(c => c.key).join(\",\");\n const rows = tableData.data.map(row =>\n tableData.columns.map(c => {\n const val = row[c.key];\n const str = val === null || val === undefined ? \"\" : String(val);\n return str.includes(\",\") ? `\"${str}\"` : str;\n }).join(\",\")\n );\n const csv = [headers, ...rows].join(\"\\n\");\n const blob = new Blob([csv], { type: \"text/csv\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `js_results_${new Date().toISOString().slice(0, 19)}.csv`;\n a.click();\n URL.revokeObjectURL(url);\n }, [tableData]);\n\n const handleExportMarkdown = useCallback(() => {\n if (tableData.data.length === 0) return;\n const headers = tableData.columns.map(c => c.key);\n const headerRow = `| ${headers.join(\" | \")} |`;\n const dividerRow = `| ${headers.map(() => \"---\").join(\" | \")} |`;\n const dataRows = tableData.data.map(row =>\n `| ${headers.map(h => {\n const val = row[h];\n if (val === null || val === undefined) return \"\";\n return String(val).replace(/\\|/g, \"\\\\|\").replace(/\\n/g, \" \");\n }).join(\" | \")} |`\n );\n const markdown = [headerRow, dividerRow, ...dataRows].join(\"\\n\");\n navigator.clipboard.writeText(markdown).then(() => {\n snackbar.open({ type: \"success\",\nmessage: t(\"studio_sql_markdown_copied\") });\n }).catch(() => {\n snackbar.open({ type: \"error\",\nmessage: t(\"studio_sql_markdown_copy_failed\") });\n });\n }, [tableData, snackbar, t]);\n\n // ─── Render ──────────────────────────────────────────────────\n\n return (\n <div className=\"flex flex-col h-full w-full\">\n {/* Main content */}\n <div className=\"flex-grow overflow-hidden\">\n <ResizablePanels\n orientation=\"horizontal\"\n panelSizePercent={sidebarSize}\n onPanelSizeChange={setSidebarSize}\n minPanelSizePx={200}\n firstPanel={\n <JSEditorSidebar\n collections={collectionInfos}\n snippets={snippets}\n history={history}\n onSelectSnippet={(code) => updateActiveCode(code)}\n onDeleteSnippet={deleteSnippet}\n onInsertCode={(code) => updateActiveCode(code)}\n />\n }\n secondPanel={\n <div className=\"flex flex-col h-full overflow-hidden\">\n {/* Toolbar: matching SQL Editor layout */}\n <div className={cls(\"flex items-center justify-between pr-2 border-b bg-white dark:bg-surface-950\", defaultBorderMixin)}>\n <div className=\"flex items-center flex-grow overflow-hidden mr-4\">\n <div className=\"flex items-center no-scrollbar overflow-x-auto min-w-0\">\n <Tabs value={activeTabId} onValueChange={setActiveTabId} variant=\"boxy\" className=\"w-[unset] flex-shrink-0\" innerClassName=\"bg-white dark:bg-surface-950\">\n {tabs.map(tab => (\n <Tab key={tab.id} value={tab.id} className=\"flex items-center justify-between group max-w-[200px]\">\n <TerminalIcon size={iconSize.smallest} className=\"text-amber-500 mr-1.5 flex-shrink-0\"/>\n <span className=\"truncate\">{tab.name}</span>\n {tabs.length > 1 && (\n <IconButton\n size=\"smallest\"\n onClick={(e) => { e.stopPropagation(); closeTab(tab.id); }}\n className=\"ml-1 !p-0.5 opacity-0 group-hover:opacity-100 hover:text-red-500 transition-opacity\"\n >\n <XIcon size={iconSize.smallest}/>\n </IconButton>\n )}\n </Tab>\n ))}\n </Tabs>\n <IconButton\n size=\"small\"\n onClick={addTab}\n className=\"ml-2 flex-shrink-0\"\n >\n <PlusIcon size={iconSize.smallest}/>\n </IconButton>\n </div>\n </div>\n <div className=\"flex shrink-0 items-center justify-end gap-1.5\">\n <Tooltip title=\"SaveIcon as snippet\">\n <IconButton\n size=\"small\"\n onClick={() => {\n setSnippetName(\"\");\n setShowSaveDialog(true);\n }}\n disabled={!activeTab?.code.trim()}\n >\n <SaveIcon size={iconSize.smallest}/>\n </IconButton>\n </Tooltip>\n\n {result?.value != null && (\n <Tooltip title=\"Export result as JSON\">\n <IconButton size=\"small\" onClick={exportResult}>\n <DownloadIcon size={iconSize.smallest}/>\n </IconButton>\n </Tooltip>\n )}\n\n <Button\n size=\"small\"\n color=\"primary\"\n disabled={isRunning || !activeTab?.code.trim()}\n onClick={() => executeCode()}\n >\n {isRunning ? <CircularProgress size=\"smallest\" className=\"mr-2\"/> : <PlayIcon size={iconSize.smallest} className=\"mr-2\"/>}\n Run\n </Button>\n </div>\n </div>\n\n {/* Editor + Results split */}\n <div className=\"flex-grow overflow-hidden\">\n <ResizablePanels\n orientation=\"vertical\"\n panelSizePercent={editorHeight}\n onPanelSizeChange={setEditorHeight}\n minPanelSizePx={100}\n firstPanel={\n <div className=\"h-full w-full overflow-hidden flex flex-col\">\n {/* Auth Simulation UI */}\n <div className=\"p-2 px-3 border-b border-surface-200 dark:border-surface-950 bg-surface-50 dark:bg-surface-900 flex items-center shrink-0\">\n <AuthSimulationSelector\n authMode={authMode}\n setAuthMode={setAuthMode}\n selectedUser={selectedUser}\n setSelectedUser={setSelectedUser}\n users={users}\n loading={userManagement?.loading}\n currentUser={currentSelectableUser}\n />\n </div>\n <div className=\"flex-1 min-h-0\">\n <JSMonacoEditor\n value={activeTab?.code ?? \"\"}\n onChange={updateActiveCode}\n onRun={(selectedText) => executeCode(selectedText)}\n collectionSlugs={collectionSlugs}\n collections={collectionInfos}\n autoFocus\n />\n </div>\n </div>\n }\n secondPanel={\n <div className=\"h-full w-full flex flex-col bg-surface-50 dark:bg-surface-950 overflow-hidden min-h-0\">\n {/* Result header — matches SQL editor */}\n <div className={cls(\"p-2 px-4 bg-surface-100 dark:bg-surface-900 border-b shrink-0 flex items-center\", defaultBorderMixin)}>\n <Typography variant=\"caption\" className=\"font-bold text-text-disabled dark:text-text-disabled-dark uppercase tracking-widest text-[10px]\">\n {t(\"studio_sql_query_results\")}\n </Typography>\n\n {result && (\n <>\n <div className=\"flex-grow\"/>\n\n <Tabs value={resultView} onValueChange={(val) => setResultView(val as \"json\" | \"table\" | \"console\")} variant=\"pill\" className=\"w-[unset] mr-2\">\n <Tab value=\"json\">JSON</Tab>\n {tableData.data.length > 0 && <Tab value=\"table\">Table</Tab>}\n {result.console.length > 0 && <Tab value=\"console\">Console ({result.console.length})</Tab>}\n </Tabs>\n\n <Chip size=\"smallest\" colorScheme={result.error ? \"redDarker\" : \"greenDarker\"}>\n {result.error ? \"Error\" : `${result.duration.toFixed(0)}ms`}\n </Chip>\n </>\n )}\n </div>\n\n {/* Result content */}\n <div className=\"flex-grow flex flex-col min-h-0 overflow-hidden\">\n {isRunning && (\n <div className=\"flex-grow flex items-center justify-center\">\n <div className=\"text-center\">\n <CircularProgress size=\"medium\"/>\n <Typography variant=\"body2\" className=\"mt-4 text-text-secondary dark:text-text-secondary-dark font-mono tracking-tight animate-pulse\">\n EXECUTING SCRIPT...\n </Typography>\n </div>\n </div>\n )}\n\n {!isRunning && !result && (\n <div className=\"flex-grow flex items-center justify-center text-text-disabled dark:text-text-disabled-dark\">\n <div className=\"text-center\">\n <svg className=\"w-12 h-12 mx-auto mb-4 opacity-50\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1} d=\"M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z\"/></svg>\n <Typography variant=\"body2\">Write JavaScript and press <kbd className=\"px-1.5 py-0.5 rounded bg-surface-200 dark:bg-surface-700 text-[11px] font-mono\">⌘ Enter</kbd> to run</Typography>\n </div>\n </div>\n )}\n\n {!isRunning && result?.error && (\n <div className=\"flex-grow flex items-center justify-center p-6 overflow-auto\">\n <ErrorView\n title=\"Execution Error\"\n error={result.error}\n />\n </div>\n )}\n\n {!isRunning && result && !result.error && resultView === \"json\" && (\n <pre className=\"flex-grow overflow-auto p-4 text-[13px] font-mono leading-relaxed text-text-primary dark:text-text-primary-dark whitespace-pre-wrap break-words\">\n {result.value === undefined ? (\n <span className=\"text-text-disabled italic\">undefined (no return value)</span>\n ) : (\n <JSONHighlight value={result.value}/>\n )}\n </pre>\n )}\n\n {!isRunning && result && !result.error && resultView === \"table\" && tableData.data.length > 0 && (\n <div className=\"flex-grow flex flex-col overflow-hidden min-h-0\">\n {/* Collection badges bar — matching SQL editor */}\n {matchedCollections.length > 0 && (\n <div className={cls(\"px-4 py-1.5 border-b flex items-center gap-2 shrink-0 bg-surface-50 dark:bg-surface-900\", defaultBorderMixin)}>\n <Tooltip title={t(\"studio_sql_cms_collections_tooltip\")}>\n <Typography variant=\"caption\" className=\"text-[10px] font-bold uppercase tracking-widest text-text-disabled dark:text-text-disabled-dark mr-1 shrink-0 cursor-help\">{t(\"studio_sql_cms\")}</Typography>\n </Tooltip>\n <div className=\"flex items-center gap-1.5 overflow-x-auto no-scrollbar\">\n {matchedCollections.map(mc => (\n <Tooltip key={mc.collectionSlug} title={`${mc.collection.name} (${mc.collectionSlug})`}>\n <span className=\"inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[11px] font-medium bg-primary/10 dark:bg-primary-dark/15 text-primary dark:text-primary-dark whitespace-nowrap border border-primary/20 dark:border-primary-dark/20\">\n {typeof mc.collection.icon === \"string\" && (\n <IconForView collectionOrView={{ icon: mc.collection.icon } as never} className=\"text-[12px]\"/>\n )}\n {mc.collection.name}\n </span>\n </Tooltip>\n ))}\n </div>\n </div>\n )}\n <div className=\"flex-grow relative h-full min-h-0 min-w-0\">\n <VirtualTable\n data={tableData.data}\n columns={\n matchedCollections.length > 0\n ? [{ key: \"__entity_action__\",\ntitle: \"\",\nwidth: 36,\nsortable: false,\nresizable: false }, ...tableData.columns]\n : tableData.columns\n }\n rowHeight={32}\n headerHeight={32}\n cellRenderer={({ rowData, column, rowIndex }: CellRendererParams<Record<string, unknown>>) => {\n // Entity action column\n if (column.key === \"__entity_action__\") {\n const rowActions = getRowEntityActions(rowData ?? {});\n if (rowActions.length === 0) return <div className=\"h-full w-full\"/>;\n if (rowActions.length === 1) {\n const ra = rowActions[0];\n return (\n <div className=\"h-full flex items-center justify-center\">\n <Tooltip title={t(\"studio_sql_edit_entity\", { name: ra.collection.collection.name,\nid: String(ra.entityId) })}>\n <IconButton\n size=\"small\"\n className=\"text-surface-400 dark:text-surface-500 hover:text-surface-600 dark:hover:text-surface-300\"\n onClick={(e) => {\n e.stopPropagation();\n sideEntityController.open({\n path: ra.collection.collectionSlug,\n entityId: ra.entityId,\n collection: ra.collection.collection,\n updateUrl: false\n });\n }}\n >\n <PencilIcon size={iconSize.smallest}/>\n </IconButton>\n </Tooltip>\n </div>\n );\n }\n // Multiple matched collections\n return (\n <div className=\"h-full flex items-center justify-center\">\n <Menu\n trigger={\n <IconButton\n size={\"small\"}\n className=\"text-surface-400 dark:text-surface-500 hover:text-surface-600 dark:hover:text-surface-300\"\n onClick={(e) => e.stopPropagation()}\n >\n <MoreVerticalIcon size={iconSize.smallest}/>\n </IconButton>\n }\n >\n {rowActions.map(ra => (\n <MenuItem\n key={ra.collection.collectionSlug}\n dense\n onClick={() => {\n sideEntityController.open({\n path: ra.collection.collectionSlug,\n entityId: ra.entityId,\n collection: ra.collection.collection,\n updateUrl: false\n });\n }}\n >\n {t(\"studio_sql_edit_entity\", { name: ra.collection.collection.name,\nid: String(ra.entityId) })}\n </MenuItem>\n ))}\n </Menu>\n </div>\n );\n }\n\n // Regular data cell\n if (!rowData) return null;\n const val = rowData[column.key];\n const displayValue = typeof val === \"object\" && val !== null ? JSON.stringify(val) : String(val ?? \"\");\n return (\n <div className=\"px-4 py-1.5 h-full flex items-center whitespace-nowrap text-[13px] text-text-primary dark:text-text-primary-dark font-mono\">\n <div className=\"truncate flex-grow\" title={displayValue}>\n {displayValue === \"\" ? <span className=\"text-text-disabled dark:text-text-disabled-dark italic text-[11px]\">NULL</span> : displayValue}\n </div>\n </div>\n );\n }}\n />\n </div>\n </div>\n )}\n\n {!isRunning && result && resultView === \"console\" && (\n <div className=\"flex-grow overflow-auto p-2 space-y-1 font-mono text-[12px]\">\n {result.console.length === 0 ? (\n <Typography variant=\"caption\" className=\"text-text-disabled p-2\">No console output</Typography>\n ) : (\n result.console.map((entry, i) => (\n <div\n key={i}\n className={cls(\n \"px-2 py-1 rounded flex items-start gap-2\",\n entry.type === \"error\" && \"bg-red-50 dark:bg-red-950/30 text-red-700 dark:text-red-400\",\n entry.type === \"warn\" && \"bg-amber-50 dark:bg-amber-950/30 text-amber-700 dark:text-amber-400\",\n entry.type === \"log\" && \"text-text-primary dark:text-text-primary-dark\",\n entry.type === \"info\" && \"text-blue-700 dark:text-blue-400\"\n )}\n >\n <span className=\"text-[10px] opacity-50 flex-shrink-0 mt-0.5\">\n {entry.type === \"error\" ? \"❌\" : entry.type === \"warn\" ? \"⚠️\" : entry.type === \"info\" ? \"ℹ️\" : \"›\"}\n </span>\n <span className=\"whitespace-pre-wrap break-words\">\n {entry.args.map(a => typeof a === \"object\" ? JSON.stringify(a, null, 2) : String(a)).join(\" \")}\n </span>\n </div>\n ))\n )}\n\n {result.value !== undefined && (\n <div className={cls(\"px-2 py-1 mt-2 border-t pt-2\", defaultBorderMixin)}>\n <Typography variant=\"caption\" className=\"text-text-disabled text-[10px] uppercase tracking-wider mb-1 block\">Return Value</Typography>\n <pre className=\"text-text-primary dark:text-text-primary-dark whitespace-pre-wrap break-words text-[12px]\">\n {formatJSON(result.value)}\n </pre>\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* Footer bar — matching SQL editor */}\n {!isRunning && result && !result.error && resultView === \"table\" && tableData.data.length > 0 && (\n <div className={cls(\"p-2 px-4 border-t bg-surface-50 dark:bg-surface-900 flex justify-between items-center shrink-0\", defaultBorderMixin)}>\n <div className=\"flex space-x-4\">\n <div className=\"flex items-center text-[11px]\">\n <span className=\"font-bold text-text-disabled dark:text-text-disabled-dark mr-2 uppercase tracking-tighter\">{t(\"studio_sql_rows\")}</span>\n <span className=\"font-mono text-text-secondary dark:text-text-secondary-dark\">{tableData.data.length}</span>\n </div>\n <div className=\"flex items-center text-[11px]\">\n <span className=\"font-bold text-text-disabled dark:text-text-disabled-dark mr-2 uppercase tracking-tighter\">{t(\"studio_sql_time\")}</span>\n <span className=\"font-mono text-text-secondary dark:text-text-secondary-dark\">{result.duration.toFixed(0)}ms</span>\n </div>\n </div>\n <div className=\"flex gap-2 overflow-x-auto no-scrollbar items-center px-2\">\n <Button\n size=\"small\"\n variant=\"text\"\n className=\"text-[10px] uppercase font-bold text-text-secondary dark:text-text-secondary-dark whitespace-nowrap\"\n onClick={handleExportMarkdown}\n >\n {t(\"studio_sql_copy_markdown\")}\n </Button>\n <Button\n size=\"small\"\n variant=\"text\"\n className=\"text-[10px] uppercase font-bold text-text-secondary dark:text-text-secondary-dark whitespace-nowrap\"\n onClick={exportResult}\n >\n {t(\"studio_sql_export_json\")}\n </Button>\n <Button\n size=\"small\"\n variant=\"text\"\n className=\"text-[10px] uppercase font-bold text-text-secondary dark:text-text-secondary-dark whitespace-nowrap\"\n onClick={handleExportCSV}\n >\n {t(\"studio_sql_export_csv\")}\n </Button>\n </div>\n </div>\n )}\n </div>\n }\n />\n </div>\n </div>\n }\n />\n </div>\n\n {/* SaveIcon snippet dialog */}\n <Dialog open={showSaveDialog} onOpenChange={setShowSaveDialog}>\n <DialogTitle>SaveIcon Snippet</DialogTitle>\n <DialogContent>\n <TextField\n label=\"Snippet name\"\n value={snippetName}\n onChange={(e) => setSnippetName(e.target.value)}\n placeholder=\"e.g. List all products\"\n autoFocus\n onKeyDown={(e) => {\n if (e.key === \"Enter\") saveSnippet();\n }}\n />\n </DialogContent>\n <DialogActions>\n <Button variant=\"text\" onClick={() => setShowSaveDialog(false)}>Cancel</Button>\n <Button variant=\"filled\" color=\"primary\" onClick={saveSnippet} disabled={!snippetName.trim()}>Save</Button>\n </DialogActions>\n </Dialog>\n </div>\n );\n}\n\n// ─── JSON Syntax Highlighting ────────────────────────────────────────\n\nfunction JSONHighlight({ value }: { value: unknown }) {\n const json = formatJSON(value);\n const { mode } = useModeController();\n\n return (\n <Highlight\n theme={mode === \"dark\" ? themes.vsDark : themes.github}\n code={json}\n language=\"json\"\n >\n {({ style, tokens, getLineProps, getTokenProps }) => (\n <span style={{ ...style,\nbackgroundColor: \"transparent\" }}>\n {tokens.map((line, i) => (\n <div key={i} {...getLineProps({ line })}>\n {line.map((token, key) => (\n <span key={key} {...getTokenProps({ token })}/>\n ))}\n </div>\n ))}\n </span>\n )}\n </Highlight>\n );\n}\n"],"names":["REBASE_CLIENT_TYPES","JSMonacoEditor","value","onChange","onRun","className","readOnly","autoFocus","collectionSlugs","collections","mode","useModeController","editorRef","useRef","monacoRef","onRunRef","current","typesRegisteredRef","handleEditorOnMount","editorInstance","monaco","addAction","id","label","keybindings","KeyMod","CtrlCmd","KeyCode","Enter","contextMenuGroupId","contextMenuOrder","run","selection","getSelection","selectedText","isEmpty","getModel","getValueInRange","trim","undefined","ts","languages","typescript","typescriptDefaults","setCompilerOptions","target","ScriptTarget","ESNext","module","ModuleKind","allowJs","checkJs","strict","noEmit","allowNonTsExtensions","setDiagnosticsOptions","diagnosticCodesToIgnore","addExtraLib","length","lines","col","ifaceName","slug","replace","propsType","properties","map","p","join","push","name","collectionHints","focus","cls","minimap","enabled","fontSize","lineNumbers","scrollBeyondLastLine","automaticLayout","tabSize","wordWrap","suggestOnTriggerCharacters","quickSuggestions","parameterHints","QUICK_REFERENCE","code","description","JSEditorSidebar","snippets","history","onSelectSnippet","onDeleteSnippet","onInsertCode","activeTab","setActiveTab","useState","defaultBorderMixin","v","ref","i","favorites","filter","s","isFavorite","others","snippet","reverse","substring","CollectionItem","t0","$","_c","collection","expanded","setExpanded","t1","t2","t3","t4","Symbol","for","t5","t6","t7","t8","e","stopPropagation","t9","iconSize","smallest","t10","t11","t12","prop","t13","SnippetItem","onSelect","onDelete","STORAGE_PREFIX","DEFAULT_CODE","loadFromStorage","key","fallback","raw","localStorage","getItem","JSON","parse","saveToStorage","setItem","stringify","formatJSON","String","detectCollectionsInResult","resultValue","mentionedSlugs","Set","collectionCallRegex","m","exec","add","dotAccessRegex","includes","size","rows","rv","data","Array","isArray","hasId","some","r","matched","normalised","toSnakeCase","find","c","tableName","table","collectionSlug","pkColumn","JSEditor","rebaseContext","useRebaseContext","rebaseClient","useRebaseClient","apiConfig","useApiConfig","snackbar","useSnackbarController","collectionRegistry","useStudioCollectionRegistry","sideEntityController","useStudioSideEntityController","t","useTranslation","userManagement","currentUser","authController","user","tabs","setTabs","activeTabId","setActiveTabId","result","setResult","isRunning","setIsRunning","setSnippets","setHistory","showSaveDialog","setShowSaveDialog","snippetName","setSnippetName","resultView","setResultView","selectedUser","setSelectedUser","authMode","setAuthMode","sidebarSize","setSidebarSize","stored","Number","editorHeight","setEditorHeight","collectionInfos","useMemo","Object","keys","users","managed","u","uid","displayName","email","photoURL","roles","unshift","currentSelectableUser","useEffect","toString","updateActiveCode","useCallback","prev","addTab","Date","now","newTab","closeTab","tabId","filtered","fresh","buildClient","apiUrl","getAuthToken","Error","client","createRebaseClient","baseUrl","token","isScoped","executeCode","codeOverride","deduped","h","slice","consoleEntries","startTime","performance","scopedClientToCleanUp","originalConsole","log","console","warn","error","info","captureConsole","type","args","timestamp","context","AsyncFunction","getPrototypeOf","constructor","fn","duration","resultObj","err","message","ws","disconnect","saveSnippet","createdAt","open","deleteSnippet","exportResult","blob","Blob","url","URL","createObjectURL","a","document","createElement","href","download","click","revokeObjectURL","tableData","columns","val","entity","values","forEach","row","k","from","title","width","matchedCollections","getRowEntityActions","rowData","mc","entityId","handleExportCSV","headers","str","csv","toISOString","handleExportMarkdown","headerRow","dividerRow","dataRows","markdown","navigator","clipboard","writeText","then","catch","tab","loading","toFixed","icon","sortable","resizable","column","rowIndex","rowActions","ra","path","updateUrl","displayValue","entry","JSONHighlight","json","themes","vsDark","github","_temp","style","tokens","getLineProps","getTokenProps","backgroundColor","line"],"mappings":"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"}