@rebasepro/studio 0.2.3 → 0.2.5
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/{ApiExplorer-BmcdhAX0.js → ApiExplorer-CGHEF1uL.js} +4 -4
- package/dist/ApiExplorer-CGHEF1uL.js.map +1 -0
- package/dist/{CronJobsView-CNfz0etw.js → CronJobsView-3PM_qR8v.js} +20 -3
- package/dist/CronJobsView-3PM_qR8v.js.map +1 -0
- package/dist/{JSEditor-Ch8z8lJ4.js → JSEditor-BCSoElPg.js} +26 -36
- package/dist/JSEditor-BCSoElPg.js.map +1 -0
- package/dist/LogsExplorer-_4sZadKn.js +162 -0
- package/dist/LogsExplorer-_4sZadKn.js.map +1 -0
- package/dist/{SQLEditor-BELYJQRP.js → SQLEditor-BC0IOUQu.js} +4 -4
- package/dist/SQLEditor-BC0IOUQu.js.map +1 -0
- package/dist/common/src/collections/default-collections.d.ts +9 -0
- package/dist/common/src/collections/index.d.ts +1 -0
- package/dist/common/src/util/permissions.d.ts +1 -0
- package/dist/core/src/components/LoginView/LoginView.d.ts +25 -1
- package/dist/core/src/components/common/types.d.ts +10 -7
- package/dist/core/src/components/common/useDebouncedData.d.ts +1 -1
- package/dist/core/src/core/RebaseProps.d.ts +13 -2
- package/dist/core/src/core/RebaseRouter.d.ts +1 -1
- package/dist/core/src/hooks/data/useCollectionFetch.d.ts +12 -1
- package/dist/core/src/hooks/index.d.ts +0 -1
- package/dist/core/src/util/entity_cache.d.ts +0 -5
- package/dist/core/src/util/index.d.ts +0 -2
- package/dist/core/src/util/useStorageUploadController.d.ts +2 -2
- package/dist/formex/src/utils.d.ts +2 -2
- package/dist/index.es.js +23 -5
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +228 -44
- package/dist/index.umd.js.map +1 -1
- package/dist/studio/src/components/ApiExplorer/parseSpec.d.ts +1 -1
- package/dist/studio/src/components/ApiExplorer/types.d.ts +3 -3
- package/dist/studio/src/components/LogsExplorer/LogsExplorer.d.ts +1 -0
- package/dist/types/src/controllers/auth.d.ts +4 -26
- package/dist/types/src/controllers/client.d.ts +25 -43
- package/dist/types/src/controllers/collection_registry.d.ts +1 -1
- package/dist/types/src/controllers/data.d.ts +4 -0
- package/dist/types/src/controllers/data_driver.d.ts +23 -0
- package/dist/types/src/controllers/registry.d.ts +5 -4
- package/dist/types/src/rebase_context.d.ts +1 -1
- package/dist/types/src/types/auth_adapter.d.ts +5 -60
- package/dist/types/src/types/backend.d.ts +2 -2
- package/dist/types/src/types/backend_hooks.d.ts +2 -17
- package/dist/types/src/types/collections.d.ts +0 -4
- package/dist/types/src/types/component_ref.d.ts +1 -1
- package/dist/types/src/types/cron.d.ts +1 -1
- package/dist/types/src/types/entity_views.d.ts +1 -0
- package/dist/types/src/types/export_import.d.ts +1 -1
- package/dist/types/src/types/formex.d.ts +2 -2
- package/dist/types/src/types/properties.d.ts +9 -7
- package/dist/types/src/types/translations.d.ts +28 -12
- package/dist/types/src/types/user_management_delegate.d.ts +22 -57
- package/dist/types/src/users/index.d.ts +0 -1
- package/dist/types/src/users/user.d.ts +0 -1
- package/dist/ui/src/components/Button.d.ts +2 -2
- package/dist/ui/src/components/ErrorBoundary.d.ts +25 -3
- package/dist/ui/src/components/VirtualTable/VirtualTable.d.ts +1 -1
- package/dist/ui/src/components/VirtualTable/VirtualTableCell.d.ts +6 -6
- package/dist/ui/src/components/VirtualTable/VirtualTableHeader.d.ts +8 -8
- package/dist/ui/src/components/VirtualTable/VirtualTableHeaderRow.d.ts +1 -1
- package/dist/ui/src/components/VirtualTable/VirtualTableProps.d.ts +11 -11
- package/dist/ui/src/components/VirtualTable/VirtualTableRow.d.ts +1 -1
- package/dist/ui/src/components/VirtualTable/types.d.ts +9 -9
- package/dist/ui/src/hooks/useDebounceCallback.d.ts +1 -1
- package/dist/ui/src/util/debounce.d.ts +1 -1
- package/package.json +8 -8
- package/src/components/ApiExplorer/ApiExplorer.tsx +2 -2
- package/src/components/ApiExplorer/EndpointDetail.tsx +1 -1
- package/src/components/ApiExplorer/TryItPanel.tsx +5 -5
- package/src/components/ApiExplorer/parseSpec.ts +3 -3
- package/src/components/ApiExplorer/types.ts +3 -3
- package/src/components/CronJobs/CronJobsView.tsx +27 -2
- package/src/components/JSEditor/JSEditor.tsx +21 -18
- package/src/components/JSEditor/JSMonacoEditor.tsx +6 -19
- package/src/components/LogsExplorer/LogsExplorer.tsx +224 -0
- package/src/components/RebaseStudio.tsx +10 -1
- package/src/components/SQLEditor/SQLEditor.tsx +28 -7
- package/src/components/StudioHomePage.tsx +2 -1
- package/src/utils/parseSpec.test.ts +274 -0
- package/src/utils/pgColumnToProperty.test.ts +1 -0
- package/src/utils/pgColumnToProperty.ts +35 -4
- package/dist/ApiExplorer-BmcdhAX0.js.map +0 -1
- package/dist/CronJobsView-CNfz0etw.js.map +0 -1
- package/dist/JSEditor-Ch8z8lJ4.js.map +0 -1
- package/dist/SQLEditor-BELYJQRP.js.map +0 -1
- package/dist/core/src/hooks/useValidateAuthenticator.d.ts +0 -21
- package/dist/core/src/util/icon_synonyms.d.ts +0 -1
- package/dist/core/src/util/useTraceUpdate.d.ts +0 -2
- package/dist/types/src/users/roles.d.ts +0 -22
package/dist/index.umd.js
CHANGED
|
@@ -31,6 +31,11 @@
|
|
|
31
31
|
name: "RLS Policies",
|
|
32
32
|
description: "Configure Row Level Security for fine-grained data access",
|
|
33
33
|
icon: "ShieldCheck"
|
|
34
|
+
}, {
|
|
35
|
+
path: "/logs",
|
|
36
|
+
name: "Logs Explorer",
|
|
37
|
+
description: "Real-time system, query, and authentication logs",
|
|
38
|
+
icon: "Activity"
|
|
34
39
|
}]
|
|
35
40
|
}, {
|
|
36
41
|
label: "Compute",
|
|
@@ -611,6 +616,9 @@
|
|
|
611
616
|
const ApiExplorer$2 = React.lazy(() => Promise.resolve().then(() => ApiExplorer$1).then((m) => ({
|
|
612
617
|
default: m.ApiExplorer
|
|
613
618
|
})));
|
|
619
|
+
const LogsExplorer$2 = React.lazy(() => Promise.resolve().then(() => LogsExplorer$1).then((m) => ({
|
|
620
|
+
default: m.LogsExplorer
|
|
621
|
+
})));
|
|
614
622
|
const DEFAULT_HOME_PAGE = /* @__PURE__ */ jsxRuntime.jsx(StudioHomePage, {});
|
|
615
623
|
function RebaseStudio({
|
|
616
624
|
tools,
|
|
@@ -620,7 +628,7 @@
|
|
|
620
628
|
const resolvedHomePage = homePage ?? DEFAULT_HOME_PAGE;
|
|
621
629
|
const devViews = React.useMemo(() => {
|
|
622
630
|
const views = [];
|
|
623
|
-
const activeTools = tools ?? ["sql", "js", "rls", "storage", "cron", "schema-visualizer", "branches", "api"];
|
|
631
|
+
const activeTools = tools ?? ["sql", "js", "rls", "storage", "cron", "schema-visualizer", "branches", "api", "logs"];
|
|
624
632
|
const suspense = (el) => /* @__PURE__ */ jsxRuntime.jsx(React.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(ui.CircularProgressCenter, {}), children: el });
|
|
625
633
|
if (activeTools.includes("sql")) {
|
|
626
634
|
views.push({
|
|
@@ -702,6 +710,16 @@
|
|
|
702
710
|
view: suspense(/* @__PURE__ */ jsxRuntime.jsx(ApiExplorer$2, {}))
|
|
703
711
|
});
|
|
704
712
|
}
|
|
713
|
+
if (activeTools.includes("logs")) {
|
|
714
|
+
views.push({
|
|
715
|
+
slug: "logs",
|
|
716
|
+
name: "Logs Explorer",
|
|
717
|
+
group: "Database",
|
|
718
|
+
icon: "Activity",
|
|
719
|
+
description: "Real-time system and query logs",
|
|
720
|
+
view: suspense(/* @__PURE__ */ jsxRuntime.jsx(LogsExplorer$2, {}))
|
|
721
|
+
});
|
|
722
|
+
}
|
|
705
723
|
return views;
|
|
706
724
|
}, [tools]);
|
|
707
725
|
const homePageRef = React.useRef(resolvedHomePage);
|
|
@@ -2469,7 +2487,7 @@ WHERE id = ?;`);
|
|
|
2469
2487
|
rowIndex: rowIndex_1
|
|
2470
2488
|
}) => {
|
|
2471
2489
|
if (column_0.key === "__cms_action__") {
|
|
2472
|
-
const rowActions = getRowEntityActions(rowData_2);
|
|
2490
|
+
const rowActions = getRowEntityActions(rowData_2 ?? {});
|
|
2473
2491
|
if (rowActions.length === 0) {
|
|
2474
2492
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-full" });
|
|
2475
2493
|
}
|
|
@@ -2504,9 +2522,9 @@ WHERE id = ?;`);
|
|
|
2504
2522
|
const value = rowData_2 ? rowData_2[column_0.key] : null;
|
|
2505
2523
|
const displayValue = typeof value === "object" && value !== null ? JSON.stringify(value) : String(value ?? "");
|
|
2506
2524
|
if (isEditing) {
|
|
2507
|
-
return /* @__PURE__ */ jsxRuntime.jsx(FixedEditorOverlay, { displayValue, onSave: (val_2) => handleCellSave(val_2, rowData_2, column_0.key, rowIndex_1), onCancel: () => setEditingCell(null) });
|
|
2525
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FixedEditorOverlay, { displayValue, onSave: (val_2) => handleCellSave(val_2, rowData_2 ?? {}, column_0.key, rowIndex_1), onCancel: () => setEditingCell(null) });
|
|
2508
2526
|
}
|
|
2509
|
-
return /* @__PURE__ */ jsxRuntime.jsx("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 cursor-text group/cell", onDoubleClick: () => handleDoubleClick(rowIndex_1, column_0.key, displayValue, rowData_2), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate flex-grow", title: displayValue, children: displayValue === "" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-text-disabled dark:text-text-disabled-dark italic text-[11px]", children: "NULL" }) : displayValue }) });
|
|
2527
|
+
return /* @__PURE__ */ jsxRuntime.jsx("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 cursor-text group/cell", onDoubleClick: () => handleDoubleClick(rowIndex_1, column_0.key, displayValue, rowData_2 ?? {}), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate flex-grow", title: displayValue, children: displayValue === "" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-text-disabled dark:text-text-disabled-dark italic text-[11px]", children: "NULL" }) : displayValue }) });
|
|
2510
2528
|
} }) }),
|
|
2511
2529
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls("p-2 px-4 border-t bg-surface-50 dark:bg-surface-900 flex justify-between items-center shrink-0", ui.defaultBorderMixin), children: [
|
|
2512
2530
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex space-x-4", children: [
|
|
@@ -2747,7 +2765,7 @@ interface RebaseAuth {
|
|
|
2747
2765
|
changePassword(oldPassword: string, newPassword: string): Promise<{ success: boolean; message: string }>;
|
|
2748
2766
|
sendVerificationEmail(): Promise<{ success: boolean; message: string }>;
|
|
2749
2767
|
verifyEmail(token: string): Promise<{ success: boolean; message: string }>;
|
|
2750
|
-
getSessions(): Promise<
|
|
2768
|
+
getSessions(): Promise<RebaseSession[]>;
|
|
2751
2769
|
revokeSession(sessionId: string): Promise<{ success: boolean }>;
|
|
2752
2770
|
revokeAllSessions(): Promise<{ success: boolean }>;
|
|
2753
2771
|
getSession(): RebaseSession | null;
|
|
@@ -2765,25 +2783,12 @@ interface AdminUser {
|
|
|
2765
2783
|
updatedAt: string;
|
|
2766
2784
|
}
|
|
2767
2785
|
|
|
2768
|
-
interface RebaseRole {
|
|
2769
|
-
id: string;
|
|
2770
|
-
name: string;
|
|
2771
|
-
isAdmin: boolean;
|
|
2772
|
-
defaultPermissions: Record<string, any> | null;
|
|
2773
|
-
config: Record<string, any> | null;
|
|
2774
|
-
}
|
|
2775
|
-
|
|
2776
2786
|
interface RebaseAdmin {
|
|
2777
2787
|
listUsers(): Promise<{ users: AdminUser[] }>;
|
|
2778
2788
|
getUser(userId: string): Promise<{ user: AdminUser }>;
|
|
2779
2789
|
createUser(data: { email: string; displayName?: string; password?: string; roles?: string[] }): Promise<{ user: AdminUser }>;
|
|
2780
2790
|
updateUser(userId: string, data: { email?: string; displayName?: string; password?: string; roles?: string[] }): Promise<{ user: AdminUser }>;
|
|
2781
2791
|
deleteUser(userId: string): Promise<{ success: boolean }>;
|
|
2782
|
-
listRoles(): Promise<{ roles: RebaseRole[] }>;
|
|
2783
|
-
getRole(roleId: string): Promise<{ role: RebaseRole }>;
|
|
2784
|
-
createRole(data: { id: string; name: string; isAdmin?: boolean; defaultPermissions?: any; config?: any }): Promise<{ role: RebaseRole }>;
|
|
2785
|
-
updateRole(roleId: string, data: { name?: string; isAdmin?: boolean; defaultPermissions?: any; config?: any }): Promise<{ role: RebaseRole }>;
|
|
2786
|
-
deleteRole(roleId: string): Promise<{ success: boolean }>;
|
|
2787
2792
|
bootstrap(): Promise<{ success: boolean; message: string; user: { uid: string; roles: string[] } }>;
|
|
2788
2793
|
}
|
|
2789
2794
|
|
|
@@ -2791,7 +2796,7 @@ interface UploadFileProps {
|
|
|
2791
2796
|
file: FileIcon;
|
|
2792
2797
|
fileName?: string;
|
|
2793
2798
|
path?: string;
|
|
2794
|
-
metadata?: Record<string,
|
|
2799
|
+
metadata?: Record<string, unknown>;
|
|
2795
2800
|
bucket?: string;
|
|
2796
2801
|
}
|
|
2797
2802
|
|
|
@@ -2804,7 +2809,7 @@ interface UploadFileResult {
|
|
|
2804
2809
|
interface DownloadConfig {
|
|
2805
2810
|
url: string | null;
|
|
2806
2811
|
fileNotFound?: boolean;
|
|
2807
|
-
metadata?:
|
|
2812
|
+
metadata?: Record<string, unknown>;
|
|
2808
2813
|
}
|
|
2809
2814
|
|
|
2810
2815
|
interface StorageSource {
|
|
@@ -2812,7 +2817,7 @@ interface StorageSource {
|
|
|
2812
2817
|
getSignedUrl(pathOrUrl: string, bucket?: string): Promise<DownloadConfig>;
|
|
2813
2818
|
getObject(path: string, bucket?: string): Promise<FileIcon | null>;
|
|
2814
2819
|
deleteObject(path: string, bucket?: string): Promise<void>;
|
|
2815
|
-
listObjects(path: string, options?: { bucket?: string; maxResults?: number; pageToken?: string }): Promise<
|
|
2820
|
+
listObjects(path: string, options?: { bucket?: string; maxResults?: number; pageToken?: string }): Promise<unknown>;
|
|
2816
2821
|
}
|
|
2817
2822
|
|
|
2818
2823
|
type RebaseData = {
|
|
@@ -2856,9 +2861,9 @@ interface RebaseClient {
|
|
|
2856
2861
|
/** Storage operations */
|
|
2857
2862
|
storage?: StorageSource;
|
|
2858
2863
|
/** Call a custom server-side endpoint */
|
|
2859
|
-
call<T =
|
|
2864
|
+
call<T = unknown>(endpoint: string, payload?: unknown): Promise<T>;
|
|
2860
2865
|
/** Direct collection access (shorthand) */
|
|
2861
|
-
[collectionSlug: string]:
|
|
2866
|
+
[collectionSlug: string]: unknown;
|
|
2862
2867
|
}
|
|
2863
2868
|
|
|
2864
2869
|
/** The pre-configured client instance. Already authenticated with the current user session. */
|
|
@@ -3428,8 +3433,9 @@ return result;
|
|
|
3428
3433
|
}
|
|
3429
3434
|
if (mentionedSlugs.size === 0) return [];
|
|
3430
3435
|
let rows = [];
|
|
3431
|
-
|
|
3432
|
-
|
|
3436
|
+
const rv = resultValue;
|
|
3437
|
+
if (rv?.data && Array.isArray(rv.data)) {
|
|
3438
|
+
rows = rv.data;
|
|
3433
3439
|
} else if (Array.isArray(resultValue)) {
|
|
3434
3440
|
rows = resultValue;
|
|
3435
3441
|
}
|
|
@@ -3691,7 +3697,8 @@ return result;
|
|
|
3691
3697
|
duration: duration_0,
|
|
3692
3698
|
timestamp: Date.now()
|
|
3693
3699
|
});
|
|
3694
|
-
|
|
3700
|
+
const resultObj = value;
|
|
3701
|
+
if (resultObj?.data && Array.isArray(resultObj.data)) {
|
|
3695
3702
|
setResultView("table");
|
|
3696
3703
|
} else if (consoleEntries.length > 0 && value === void 0) {
|
|
3697
3704
|
setResultView("console");
|
|
@@ -3756,10 +3763,11 @@ return result;
|
|
|
3756
3763
|
data: []
|
|
3757
3764
|
};
|
|
3758
3765
|
let rows = [];
|
|
3759
|
-
|
|
3760
|
-
|
|
3766
|
+
const val = result.value;
|
|
3767
|
+
if (val?.data && Array.isArray(val.data)) {
|
|
3768
|
+
rows = val.data.map((entity) => ({
|
|
3761
3769
|
id: entity.id,
|
|
3762
|
-
...entity.values,
|
|
3770
|
+
...entity.values ?? {},
|
|
3763
3771
|
...entity.values ? {} : entity
|
|
3764
3772
|
}));
|
|
3765
3773
|
} else if (Array.isArray(result.value)) {
|
|
@@ -3800,8 +3808,8 @@ return result;
|
|
|
3800
3808
|
if (tableData.data.length === 0) return;
|
|
3801
3809
|
const headers = tableData.columns.map((c_0) => c_0.key).join(",");
|
|
3802
3810
|
const rows_0 = tableData.data.map((row_0) => tableData.columns.map((c_1) => {
|
|
3803
|
-
const
|
|
3804
|
-
const str =
|
|
3811
|
+
const val_0 = row_0[c_1.key];
|
|
3812
|
+
const str = val_0 === null || val_0 === void 0 ? "" : String(val_0);
|
|
3805
3813
|
return str.includes(",") ? `"${str}"` : str;
|
|
3806
3814
|
}).join(","));
|
|
3807
3815
|
const csv = [headers, ...rows_0].join("\n");
|
|
@@ -3821,9 +3829,9 @@ return result;
|
|
|
3821
3829
|
const headerRow = `| ${headers_0.join(" | ")} |`;
|
|
3822
3830
|
const dividerRow = `| ${headers_0.map(() => "---").join(" | ")} |`;
|
|
3823
3831
|
const dataRows = tableData.data.map((row_1) => `| ${headers_0.map((h_0) => {
|
|
3824
|
-
const
|
|
3825
|
-
if (
|
|
3826
|
-
return String(
|
|
3832
|
+
const val_1 = row_1[h_0];
|
|
3833
|
+
if (val_1 === null || val_1 === void 0) return "";
|
|
3834
|
+
return String(val_1).replace(/\|/g, "\\|").replace(/\n/g, " ");
|
|
3827
3835
|
}).join(" | ")} |`);
|
|
3828
3836
|
const markdown = [headerRow, dividerRow, ...dataRows].join("\n");
|
|
3829
3837
|
navigator.clipboard.writeText(markdown).then(() => {
|
|
@@ -3857,7 +3865,7 @@ return result;
|
|
|
3857
3865
|
setSnippetName("");
|
|
3858
3866
|
setShowSaveDialog(true);
|
|
3859
3867
|
}, disabled: !activeTab?.code.trim(), children: /* @__PURE__ */ jsxRuntime.jsx(ui.SaveIcon, { size: ui.iconSize.smallest }) }) }),
|
|
3860
|
-
result?.value && /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Export result as JSON", children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "small", onClick: exportResult, children: /* @__PURE__ */ jsxRuntime.jsx(ui.DownloadIcon, { size: ui.iconSize.smallest }) }) }),
|
|
3868
|
+
result?.value != null && /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Export result as JSON", children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "small", onClick: exportResult, children: /* @__PURE__ */ jsxRuntime.jsx(ui.DownloadIcon, { size: ui.iconSize.smallest }) }) }),
|
|
3861
3869
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", color: "primary", disabled: isRunning || !activeTab?.code.trim(), onClick: () => executeCode(), children: [
|
|
3862
3870
|
isRunning ? /* @__PURE__ */ jsxRuntime.jsx(ui.CircularProgress, { size: "smallest", className: "mr-2" }) : /* @__PURE__ */ jsxRuntime.jsx(ui.PlayIcon, { size: ui.iconSize.smallest, className: "mr-2" }),
|
|
3863
3871
|
"Run"
|
|
@@ -3872,7 +3880,7 @@ return result;
|
|
|
3872
3880
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "caption", className: "font-bold text-text-disabled dark:text-text-disabled-dark uppercase tracking-widest text-[10px]", children: t("studio_sql_query_results") }),
|
|
3873
3881
|
result && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3874
3882
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-grow" }),
|
|
3875
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Tabs, { value: resultView, onValueChange: (
|
|
3883
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Tabs, { value: resultView, onValueChange: (val_2) => setResultView(val_2), variant: "pill", className: "w-[unset] mr-2", children: [
|
|
3876
3884
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Tab, { value: "json", children: "JSON" }),
|
|
3877
3885
|
tableData.data.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Tab, { value: "table", children: "Table" }),
|
|
3878
3886
|
result.console.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(ui.Tab, { value: "console", children: [
|
|
@@ -3921,7 +3929,7 @@ return result;
|
|
|
3921
3929
|
rowIndex
|
|
3922
3930
|
}) => {
|
|
3923
3931
|
if (column.key === "__entity_action__") {
|
|
3924
|
-
const rowActions = getRowEntityActions(rowData_0);
|
|
3932
|
+
const rowActions = getRowEntityActions(rowData_0 ?? {});
|
|
3925
3933
|
if (rowActions.length === 0) return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-full" });
|
|
3926
3934
|
if (rowActions.length === 1) {
|
|
3927
3935
|
const ra = rowActions[0];
|
|
@@ -3951,8 +3959,8 @@ return result;
|
|
|
3951
3959
|
}) }, ra_0.collection.collectionSlug)) }) });
|
|
3952
3960
|
}
|
|
3953
3961
|
if (!rowData_0) return null;
|
|
3954
|
-
const
|
|
3955
|
-
const displayValue = typeof
|
|
3962
|
+
const val_3 = rowData_0[column.key];
|
|
3963
|
+
const displayValue = typeof val_3 === "object" && val_3 !== null ? JSON.stringify(val_3) : String(val_3 ?? "");
|
|
3956
3964
|
return /* @__PURE__ */ jsxRuntime.jsx("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", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate flex-grow", title: displayValue, children: displayValue === "" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-text-disabled dark:text-text-disabled-dark italic text-[11px]", children: "NULL" }) : displayValue }) });
|
|
3957
3965
|
} }) })
|
|
3958
3966
|
] }),
|
|
@@ -6842,10 +6850,27 @@ return result;
|
|
|
6842
6850
|
}
|
|
6843
6851
|
}
|
|
6844
6852
|
load();
|
|
6845
|
-
|
|
6853
|
+
let timeoutId = null;
|
|
6854
|
+
const scheduleNext = () => {
|
|
6855
|
+
if (cancelled) return;
|
|
6856
|
+
timeoutId = setTimeout(async () => {
|
|
6857
|
+
if (document.visibilityState === "visible") {
|
|
6858
|
+
await load();
|
|
6859
|
+
}
|
|
6860
|
+
scheduleNext();
|
|
6861
|
+
}, 15e3);
|
|
6862
|
+
};
|
|
6863
|
+
scheduleNext();
|
|
6864
|
+
const handleVisibility = () => {
|
|
6865
|
+
if (document.visibilityState === "visible") {
|
|
6866
|
+
load();
|
|
6867
|
+
}
|
|
6868
|
+
};
|
|
6869
|
+
document.addEventListener("visibilitychange", handleVisibility);
|
|
6846
6870
|
return () => {
|
|
6847
6871
|
cancelled = true;
|
|
6848
|
-
|
|
6872
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
6873
|
+
document.removeEventListener("visibilitychange", handleVisibility);
|
|
6849
6874
|
};
|
|
6850
6875
|
}, []);
|
|
6851
6876
|
React.useEffect(() => {
|
|
@@ -9138,7 +9163,7 @@ return result;
|
|
|
9138
9163
|
try {
|
|
9139
9164
|
JSON.parse(body);
|
|
9140
9165
|
} catch (err) {
|
|
9141
|
-
setValidationError(`Invalid JSON: ${err.message}`);
|
|
9166
|
+
setValidationError(`Invalid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
9142
9167
|
return;
|
|
9143
9168
|
}
|
|
9144
9169
|
}
|
|
@@ -9183,7 +9208,7 @@ return result;
|
|
|
9183
9208
|
setResponse({
|
|
9184
9209
|
status: 0,
|
|
9185
9210
|
statusText: "Network Error",
|
|
9186
|
-
body: err_0.message
|
|
9211
|
+
body: err_0 instanceof Error ? err_0.message : "Request failed",
|
|
9187
9212
|
time: Math.round(performance.now() - start)
|
|
9188
9213
|
});
|
|
9189
9214
|
} finally {
|
|
@@ -9511,7 +9536,7 @@ return result;
|
|
|
9511
9536
|
}
|
|
9512
9537
|
} catch (err) {
|
|
9513
9538
|
if (!cancelled) {
|
|
9514
|
-
setError(err.message
|
|
9539
|
+
setError(err instanceof Error ? err.message : "Failed to load API spec");
|
|
9515
9540
|
setLoading(false);
|
|
9516
9541
|
}
|
|
9517
9542
|
}
|
|
@@ -9617,6 +9642,165 @@ return result;
|
|
|
9617
9642
|
__proto__: null,
|
|
9618
9643
|
ApiExplorer
|
|
9619
9644
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
9645
|
+
const LEVEL_COLORS = {
|
|
9646
|
+
debug: "#6c7086",
|
|
9647
|
+
info: "#89b4fa",
|
|
9648
|
+
warn: "#f9e2af",
|
|
9649
|
+
error: "#f38ba8"
|
|
9650
|
+
};
|
|
9651
|
+
const SOURCE_COLORS = {
|
|
9652
|
+
api: "#74c7ec",
|
|
9653
|
+
auth: "#cba6f7",
|
|
9654
|
+
storage: "#a6e3a1",
|
|
9655
|
+
realtime: "#fab387",
|
|
9656
|
+
system: "#6c7086"
|
|
9657
|
+
};
|
|
9658
|
+
function LogsExplorer() {
|
|
9659
|
+
const [logs, setLogs] = React.useState([]);
|
|
9660
|
+
const [level, setLevel] = React.useState("");
|
|
9661
|
+
const [source, setSource] = React.useState("");
|
|
9662
|
+
const [search, setSearch] = React.useState("");
|
|
9663
|
+
const [autoScroll, setAutoScroll] = React.useState(true);
|
|
9664
|
+
const containerRef = React.useRef(null);
|
|
9665
|
+
const fetchLogs = React.useCallback(async () => {
|
|
9666
|
+
try {
|
|
9667
|
+
const params = new URLSearchParams();
|
|
9668
|
+
if (level) params.set("level", level);
|
|
9669
|
+
if (source) params.set("source", source);
|
|
9670
|
+
if (search) params.set("search", search);
|
|
9671
|
+
params.set("limit", "200");
|
|
9672
|
+
const resp = await fetch(`/api/logs?${params}`);
|
|
9673
|
+
if (resp.ok) {
|
|
9674
|
+
const data = await resp.json();
|
|
9675
|
+
setLogs(data.entries || []);
|
|
9676
|
+
}
|
|
9677
|
+
} catch {
|
|
9678
|
+
}
|
|
9679
|
+
}, [level, source, search]);
|
|
9680
|
+
React.useEffect(() => {
|
|
9681
|
+
let timeoutId = null;
|
|
9682
|
+
let cancelled = false;
|
|
9683
|
+
fetchLogs();
|
|
9684
|
+
const scheduleNext = () => {
|
|
9685
|
+
if (cancelled) return;
|
|
9686
|
+
timeoutId = setTimeout(async () => {
|
|
9687
|
+
if (document.visibilityState === "visible") {
|
|
9688
|
+
await fetchLogs();
|
|
9689
|
+
}
|
|
9690
|
+
scheduleNext();
|
|
9691
|
+
}, 3e3);
|
|
9692
|
+
};
|
|
9693
|
+
scheduleNext();
|
|
9694
|
+
const handleVisibility = () => {
|
|
9695
|
+
if (document.visibilityState === "visible") {
|
|
9696
|
+
fetchLogs();
|
|
9697
|
+
}
|
|
9698
|
+
};
|
|
9699
|
+
document.addEventListener("visibilitychange", handleVisibility);
|
|
9700
|
+
return () => {
|
|
9701
|
+
cancelled = true;
|
|
9702
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
9703
|
+
document.removeEventListener("visibilitychange", handleVisibility);
|
|
9704
|
+
};
|
|
9705
|
+
}, [fetchLogs]);
|
|
9706
|
+
React.useEffect(() => {
|
|
9707
|
+
if (autoScroll && containerRef.current) {
|
|
9708
|
+
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
9709
|
+
}
|
|
9710
|
+
}, [logs, autoScroll]);
|
|
9711
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
|
|
9712
|
+
display: "flex",
|
|
9713
|
+
flexDirection: "column",
|
|
9714
|
+
height: "calc(100vh - 64px)",
|
|
9715
|
+
background: "#1e1e2e",
|
|
9716
|
+
color: "#cdd6f4"
|
|
9717
|
+
}, children: [
|
|
9718
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
|
|
9719
|
+
display: "flex",
|
|
9720
|
+
gap: 8,
|
|
9721
|
+
padding: "8px 16px",
|
|
9722
|
+
borderBottom: "1px solid #313244",
|
|
9723
|
+
alignItems: "center",
|
|
9724
|
+
flexWrap: "wrap"
|
|
9725
|
+
}, children: [
|
|
9726
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { value: level, onValueChange: setLevel, size: "small", placeholder: "All Levels", children: [
|
|
9727
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "", children: "All Levels" }),
|
|
9728
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "debug", children: "Debug" }),
|
|
9729
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "info", children: "Info" }),
|
|
9730
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "warn", children: "Warn" }),
|
|
9731
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "error", children: "Error" })
|
|
9732
|
+
] }),
|
|
9733
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { value: source, onValueChange: setSource, size: "small", placeholder: "All Sources", children: [
|
|
9734
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "", children: "All Sources" }),
|
|
9735
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "api", children: "API" }),
|
|
9736
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "auth", children: "Auth" }),
|
|
9737
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "storage", children: "Storage" }),
|
|
9738
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "realtime", children: "Realtime" }),
|
|
9739
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "system", children: "System" })
|
|
9740
|
+
] }),
|
|
9741
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.TextField, { size: "small", placeholder: "Search logs...", value: search, onChange: (e) => setSearch(e.target.value), className: "flex-1 min-w-[200px]" }),
|
|
9742
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 cursor-pointer", children: [
|
|
9743
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Checkbox, { id: "auto-scroll", checked: autoScroll, onCheckedChange: setAutoScroll, size: "small", padding: false }),
|
|
9744
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "auto-scroll", className: "text-xs select-none cursor-pointer", children: "Auto-scroll" })
|
|
9745
|
+
] }),
|
|
9746
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: {
|
|
9747
|
+
fontSize: 12,
|
|
9748
|
+
color: "#6c7086"
|
|
9749
|
+
}, children: [
|
|
9750
|
+
logs.length,
|
|
9751
|
+
" entries"
|
|
9752
|
+
] })
|
|
9753
|
+
] }),
|
|
9754
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, style: {
|
|
9755
|
+
flex: 1,
|
|
9756
|
+
overflow: "auto",
|
|
9757
|
+
fontFamily: "monospace",
|
|
9758
|
+
fontSize: 12,
|
|
9759
|
+
padding: "8px 0"
|
|
9760
|
+
}, children: [
|
|
9761
|
+
logs.map((log) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
|
|
9762
|
+
padding: "2px 16px",
|
|
9763
|
+
display: "flex",
|
|
9764
|
+
gap: 8,
|
|
9765
|
+
borderBottom: "1px solid #181825"
|
|
9766
|
+
}, children: [
|
|
9767
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: {
|
|
9768
|
+
color: "#6c7086",
|
|
9769
|
+
flexShrink: 0
|
|
9770
|
+
}, children: new Date(log.timestamp).toLocaleTimeString() }),
|
|
9771
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: {
|
|
9772
|
+
color: LEVEL_COLORS[log.level] || "#cdd6f4",
|
|
9773
|
+
width: 40,
|
|
9774
|
+
flexShrink: 0,
|
|
9775
|
+
textTransform: "uppercase",
|
|
9776
|
+
fontWeight: 600
|
|
9777
|
+
}, children: log.level }),
|
|
9778
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: {
|
|
9779
|
+
color: SOURCE_COLORS[log.source] || "#cdd6f4",
|
|
9780
|
+
width: 64,
|
|
9781
|
+
flexShrink: 0
|
|
9782
|
+
}, children: [
|
|
9783
|
+
"[",
|
|
9784
|
+
log.source,
|
|
9785
|
+
"]"
|
|
9786
|
+
] }),
|
|
9787
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: {
|
|
9788
|
+
color: "#cdd6f4",
|
|
9789
|
+
flex: 1
|
|
9790
|
+
}, children: log.message })
|
|
9791
|
+
] }, log.id)),
|
|
9792
|
+
logs.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
9793
|
+
padding: 32,
|
|
9794
|
+
textAlign: "center",
|
|
9795
|
+
color: "#6c7086"
|
|
9796
|
+
}, children: "No log entries yet. Logs will appear here as requests come in." })
|
|
9797
|
+
] })
|
|
9798
|
+
] });
|
|
9799
|
+
}
|
|
9800
|
+
const LogsExplorer$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
9801
|
+
__proto__: null,
|
|
9802
|
+
LogsExplorer
|
|
9803
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
9620
9804
|
Object.defineProperty(exports2, "StudioBridgeContext", {
|
|
9621
9805
|
enumerable: true,
|
|
9622
9806
|
get: () => core.StudioBridgeContext
|