@rebasepro/studio 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{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-Br4ke-J4.js} +30 -27
- package/dist/JSEditor-Br4ke-J4.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 +12 -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 +17 -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/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 +232 -35
- 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 +2 -24
- package/dist/types/src/controllers/client.d.ts +0 -3
- package/dist/types/src/controllers/collection_registry.d.ts +1 -1
- package/dist/types/src/controllers/data_driver.d.ts +18 -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 +2 -4
- 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 +2 -2
- package/dist/types/src/types/translations.d.ts +28 -12
- package/dist/types/src/types/user_management_delegate.d.ts +6 -4
- package/dist/types/src/users/roles.d.ts +0 -8
- 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 +10 -10
- 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.ts +16 -2
- 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/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;
|
|
@@ -2769,8 +2787,8 @@ interface RebaseRole {
|
|
|
2769
2787
|
id: string;
|
|
2770
2788
|
name: string;
|
|
2771
2789
|
isAdmin: boolean;
|
|
2772
|
-
defaultPermissions: Record<string,
|
|
2773
|
-
config: Record<string,
|
|
2790
|
+
defaultPermissions: Record<string, unknown> | null;
|
|
2791
|
+
config: Record<string, unknown> | null;
|
|
2774
2792
|
}
|
|
2775
2793
|
|
|
2776
2794
|
interface RebaseAdmin {
|
|
@@ -2781,8 +2799,8 @@ interface RebaseAdmin {
|
|
|
2781
2799
|
deleteUser(userId: string): Promise<{ success: boolean }>;
|
|
2782
2800
|
listRoles(): Promise<{ roles: RebaseRole[] }>;
|
|
2783
2801
|
getRole(roleId: string): Promise<{ role: RebaseRole }>;
|
|
2784
|
-
createRole(data: { id: string; name: string; isAdmin?: boolean; defaultPermissions?:
|
|
2785
|
-
updateRole(roleId: string, data: { name?: string; isAdmin?: boolean; defaultPermissions?:
|
|
2802
|
+
createRole(data: { id: string; name: string; isAdmin?: boolean; defaultPermissions?: Record<string, unknown>; config?: Record<string, unknown> }): Promise<{ role: RebaseRole }>;
|
|
2803
|
+
updateRole(roleId: string, data: { name?: string; isAdmin?: boolean; defaultPermissions?: Record<string, unknown>; config?: Record<string, unknown> }): Promise<{ role: RebaseRole }>;
|
|
2786
2804
|
deleteRole(roleId: string): Promise<{ success: boolean }>;
|
|
2787
2805
|
bootstrap(): Promise<{ success: boolean; message: string; user: { uid: string; roles: string[] } }>;
|
|
2788
2806
|
}
|
|
@@ -2791,7 +2809,7 @@ interface UploadFileProps {
|
|
|
2791
2809
|
file: FileIcon;
|
|
2792
2810
|
fileName?: string;
|
|
2793
2811
|
path?: string;
|
|
2794
|
-
metadata?: Record<string,
|
|
2812
|
+
metadata?: Record<string, unknown>;
|
|
2795
2813
|
bucket?: string;
|
|
2796
2814
|
}
|
|
2797
2815
|
|
|
@@ -2804,7 +2822,7 @@ interface UploadFileResult {
|
|
|
2804
2822
|
interface DownloadConfig {
|
|
2805
2823
|
url: string | null;
|
|
2806
2824
|
fileNotFound?: boolean;
|
|
2807
|
-
metadata?:
|
|
2825
|
+
metadata?: Record<string, unknown>;
|
|
2808
2826
|
}
|
|
2809
2827
|
|
|
2810
2828
|
interface StorageSource {
|
|
@@ -2812,7 +2830,7 @@ interface StorageSource {
|
|
|
2812
2830
|
getSignedUrl(pathOrUrl: string, bucket?: string): Promise<DownloadConfig>;
|
|
2813
2831
|
getObject(path: string, bucket?: string): Promise<FileIcon | null>;
|
|
2814
2832
|
deleteObject(path: string, bucket?: string): Promise<void>;
|
|
2815
|
-
listObjects(path: string, options?: { bucket?: string; maxResults?: number; pageToken?: string }): Promise<
|
|
2833
|
+
listObjects(path: string, options?: { bucket?: string; maxResults?: number; pageToken?: string }): Promise<unknown>;
|
|
2816
2834
|
}
|
|
2817
2835
|
|
|
2818
2836
|
type RebaseData = {
|
|
@@ -2856,9 +2874,9 @@ interface RebaseClient {
|
|
|
2856
2874
|
/** Storage operations */
|
|
2857
2875
|
storage?: StorageSource;
|
|
2858
2876
|
/** Call a custom server-side endpoint */
|
|
2859
|
-
call<T =
|
|
2877
|
+
call<T = unknown>(endpoint: string, payload?: unknown): Promise<T>;
|
|
2860
2878
|
/** Direct collection access (shorthand) */
|
|
2861
|
-
[collectionSlug: string]:
|
|
2879
|
+
[collectionSlug: string]: unknown;
|
|
2862
2880
|
}
|
|
2863
2881
|
|
|
2864
2882
|
/** The pre-configured client instance. Already authenticated with the current user session. */
|
|
@@ -3428,8 +3446,9 @@ return result;
|
|
|
3428
3446
|
}
|
|
3429
3447
|
if (mentionedSlugs.size === 0) return [];
|
|
3430
3448
|
let rows = [];
|
|
3431
|
-
|
|
3432
|
-
|
|
3449
|
+
const rv = resultValue;
|
|
3450
|
+
if (rv?.data && Array.isArray(rv.data)) {
|
|
3451
|
+
rows = rv.data;
|
|
3433
3452
|
} else if (Array.isArray(resultValue)) {
|
|
3434
3453
|
rows = resultValue;
|
|
3435
3454
|
}
|
|
@@ -3691,7 +3710,8 @@ return result;
|
|
|
3691
3710
|
duration: duration_0,
|
|
3692
3711
|
timestamp: Date.now()
|
|
3693
3712
|
});
|
|
3694
|
-
|
|
3713
|
+
const resultObj = value;
|
|
3714
|
+
if (resultObj?.data && Array.isArray(resultObj.data)) {
|
|
3695
3715
|
setResultView("table");
|
|
3696
3716
|
} else if (consoleEntries.length > 0 && value === void 0) {
|
|
3697
3717
|
setResultView("console");
|
|
@@ -3756,10 +3776,11 @@ return result;
|
|
|
3756
3776
|
data: []
|
|
3757
3777
|
};
|
|
3758
3778
|
let rows = [];
|
|
3759
|
-
|
|
3760
|
-
|
|
3779
|
+
const val = result.value;
|
|
3780
|
+
if (val?.data && Array.isArray(val.data)) {
|
|
3781
|
+
rows = val.data.map((entity) => ({
|
|
3761
3782
|
id: entity.id,
|
|
3762
|
-
...entity.values,
|
|
3783
|
+
...entity.values ?? {},
|
|
3763
3784
|
...entity.values ? {} : entity
|
|
3764
3785
|
}));
|
|
3765
3786
|
} else if (Array.isArray(result.value)) {
|
|
@@ -3800,8 +3821,8 @@ return result;
|
|
|
3800
3821
|
if (tableData.data.length === 0) return;
|
|
3801
3822
|
const headers = tableData.columns.map((c_0) => c_0.key).join(",");
|
|
3802
3823
|
const rows_0 = tableData.data.map((row_0) => tableData.columns.map((c_1) => {
|
|
3803
|
-
const
|
|
3804
|
-
const str =
|
|
3824
|
+
const val_0 = row_0[c_1.key];
|
|
3825
|
+
const str = val_0 === null || val_0 === void 0 ? "" : String(val_0);
|
|
3805
3826
|
return str.includes(",") ? `"${str}"` : str;
|
|
3806
3827
|
}).join(","));
|
|
3807
3828
|
const csv = [headers, ...rows_0].join("\n");
|
|
@@ -3821,9 +3842,9 @@ return result;
|
|
|
3821
3842
|
const headerRow = `| ${headers_0.join(" | ")} |`;
|
|
3822
3843
|
const dividerRow = `| ${headers_0.map(() => "---").join(" | ")} |`;
|
|
3823
3844
|
const dataRows = tableData.data.map((row_1) => `| ${headers_0.map((h_0) => {
|
|
3824
|
-
const
|
|
3825
|
-
if (
|
|
3826
|
-
return String(
|
|
3845
|
+
const val_1 = row_1[h_0];
|
|
3846
|
+
if (val_1 === null || val_1 === void 0) return "";
|
|
3847
|
+
return String(val_1).replace(/\|/g, "\\|").replace(/\n/g, " ");
|
|
3827
3848
|
}).join(" | ")} |`);
|
|
3828
3849
|
const markdown = [headerRow, dividerRow, ...dataRows].join("\n");
|
|
3829
3850
|
navigator.clipboard.writeText(markdown).then(() => {
|
|
@@ -3857,7 +3878,7 @@ return result;
|
|
|
3857
3878
|
setSnippetName("");
|
|
3858
3879
|
setShowSaveDialog(true);
|
|
3859
3880
|
}, 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 }) }) }),
|
|
3881
|
+
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
3882
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", color: "primary", disabled: isRunning || !activeTab?.code.trim(), onClick: () => executeCode(), children: [
|
|
3862
3883
|
isRunning ? /* @__PURE__ */ jsxRuntime.jsx(ui.CircularProgress, { size: "smallest", className: "mr-2" }) : /* @__PURE__ */ jsxRuntime.jsx(ui.PlayIcon, { size: ui.iconSize.smallest, className: "mr-2" }),
|
|
3863
3884
|
"Run"
|
|
@@ -3872,7 +3893,7 @@ return result;
|
|
|
3872
3893
|
/* @__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
3894
|
result && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3874
3895
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-grow" }),
|
|
3875
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Tabs, { value: resultView, onValueChange: (
|
|
3896
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Tabs, { value: resultView, onValueChange: (val_2) => setResultView(val_2), variant: "pill", className: "w-[unset] mr-2", children: [
|
|
3876
3897
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Tab, { value: "json", children: "JSON" }),
|
|
3877
3898
|
tableData.data.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Tab, { value: "table", children: "Table" }),
|
|
3878
3899
|
result.console.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(ui.Tab, { value: "console", children: [
|
|
@@ -3921,7 +3942,7 @@ return result;
|
|
|
3921
3942
|
rowIndex
|
|
3922
3943
|
}) => {
|
|
3923
3944
|
if (column.key === "__entity_action__") {
|
|
3924
|
-
const rowActions = getRowEntityActions(rowData_0);
|
|
3945
|
+
const rowActions = getRowEntityActions(rowData_0 ?? {});
|
|
3925
3946
|
if (rowActions.length === 0) return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-full" });
|
|
3926
3947
|
if (rowActions.length === 1) {
|
|
3927
3948
|
const ra = rowActions[0];
|
|
@@ -3951,8 +3972,8 @@ return result;
|
|
|
3951
3972
|
}) }, ra_0.collection.collectionSlug)) }) });
|
|
3952
3973
|
}
|
|
3953
3974
|
if (!rowData_0) return null;
|
|
3954
|
-
const
|
|
3955
|
-
const displayValue = typeof
|
|
3975
|
+
const val_3 = rowData_0[column.key];
|
|
3976
|
+
const displayValue = typeof val_3 === "object" && val_3 !== null ? JSON.stringify(val_3) : String(val_3 ?? "");
|
|
3956
3977
|
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
3978
|
} }) })
|
|
3958
3979
|
] }),
|
|
@@ -6842,10 +6863,27 @@ return result;
|
|
|
6842
6863
|
}
|
|
6843
6864
|
}
|
|
6844
6865
|
load();
|
|
6845
|
-
|
|
6866
|
+
let timeoutId = null;
|
|
6867
|
+
const scheduleNext = () => {
|
|
6868
|
+
if (cancelled) return;
|
|
6869
|
+
timeoutId = setTimeout(async () => {
|
|
6870
|
+
if (document.visibilityState === "visible") {
|
|
6871
|
+
await load();
|
|
6872
|
+
}
|
|
6873
|
+
scheduleNext();
|
|
6874
|
+
}, 15e3);
|
|
6875
|
+
};
|
|
6876
|
+
scheduleNext();
|
|
6877
|
+
const handleVisibility = () => {
|
|
6878
|
+
if (document.visibilityState === "visible") {
|
|
6879
|
+
load();
|
|
6880
|
+
}
|
|
6881
|
+
};
|
|
6882
|
+
document.addEventListener("visibilitychange", handleVisibility);
|
|
6846
6883
|
return () => {
|
|
6847
6884
|
cancelled = true;
|
|
6848
|
-
|
|
6885
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
6886
|
+
document.removeEventListener("visibilitychange", handleVisibility);
|
|
6849
6887
|
};
|
|
6850
6888
|
}, []);
|
|
6851
6889
|
React.useEffect(() => {
|
|
@@ -9138,7 +9176,7 @@ return result;
|
|
|
9138
9176
|
try {
|
|
9139
9177
|
JSON.parse(body);
|
|
9140
9178
|
} catch (err) {
|
|
9141
|
-
setValidationError(`Invalid JSON: ${err.message}`);
|
|
9179
|
+
setValidationError(`Invalid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
9142
9180
|
return;
|
|
9143
9181
|
}
|
|
9144
9182
|
}
|
|
@@ -9183,7 +9221,7 @@ return result;
|
|
|
9183
9221
|
setResponse({
|
|
9184
9222
|
status: 0,
|
|
9185
9223
|
statusText: "Network Error",
|
|
9186
|
-
body: err_0.message
|
|
9224
|
+
body: err_0 instanceof Error ? err_0.message : "Request failed",
|
|
9187
9225
|
time: Math.round(performance.now() - start)
|
|
9188
9226
|
});
|
|
9189
9227
|
} finally {
|
|
@@ -9511,7 +9549,7 @@ return result;
|
|
|
9511
9549
|
}
|
|
9512
9550
|
} catch (err) {
|
|
9513
9551
|
if (!cancelled) {
|
|
9514
|
-
setError(err.message
|
|
9552
|
+
setError(err instanceof Error ? err.message : "Failed to load API spec");
|
|
9515
9553
|
setLoading(false);
|
|
9516
9554
|
}
|
|
9517
9555
|
}
|
|
@@ -9617,6 +9655,165 @@ return result;
|
|
|
9617
9655
|
__proto__: null,
|
|
9618
9656
|
ApiExplorer
|
|
9619
9657
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
9658
|
+
const LEVEL_COLORS = {
|
|
9659
|
+
debug: "#6c7086",
|
|
9660
|
+
info: "#89b4fa",
|
|
9661
|
+
warn: "#f9e2af",
|
|
9662
|
+
error: "#f38ba8"
|
|
9663
|
+
};
|
|
9664
|
+
const SOURCE_COLORS = {
|
|
9665
|
+
api: "#74c7ec",
|
|
9666
|
+
auth: "#cba6f7",
|
|
9667
|
+
storage: "#a6e3a1",
|
|
9668
|
+
realtime: "#fab387",
|
|
9669
|
+
system: "#6c7086"
|
|
9670
|
+
};
|
|
9671
|
+
function LogsExplorer() {
|
|
9672
|
+
const [logs, setLogs] = React.useState([]);
|
|
9673
|
+
const [level, setLevel] = React.useState("");
|
|
9674
|
+
const [source, setSource] = React.useState("");
|
|
9675
|
+
const [search, setSearch] = React.useState("");
|
|
9676
|
+
const [autoScroll, setAutoScroll] = React.useState(true);
|
|
9677
|
+
const containerRef = React.useRef(null);
|
|
9678
|
+
const fetchLogs = React.useCallback(async () => {
|
|
9679
|
+
try {
|
|
9680
|
+
const params = new URLSearchParams();
|
|
9681
|
+
if (level) params.set("level", level);
|
|
9682
|
+
if (source) params.set("source", source);
|
|
9683
|
+
if (search) params.set("search", search);
|
|
9684
|
+
params.set("limit", "200");
|
|
9685
|
+
const resp = await fetch(`/api/logs?${params}`);
|
|
9686
|
+
if (resp.ok) {
|
|
9687
|
+
const data = await resp.json();
|
|
9688
|
+
setLogs(data.entries || []);
|
|
9689
|
+
}
|
|
9690
|
+
} catch {
|
|
9691
|
+
}
|
|
9692
|
+
}, [level, source, search]);
|
|
9693
|
+
React.useEffect(() => {
|
|
9694
|
+
let timeoutId = null;
|
|
9695
|
+
let cancelled = false;
|
|
9696
|
+
fetchLogs();
|
|
9697
|
+
const scheduleNext = () => {
|
|
9698
|
+
if (cancelled) return;
|
|
9699
|
+
timeoutId = setTimeout(async () => {
|
|
9700
|
+
if (document.visibilityState === "visible") {
|
|
9701
|
+
await fetchLogs();
|
|
9702
|
+
}
|
|
9703
|
+
scheduleNext();
|
|
9704
|
+
}, 3e3);
|
|
9705
|
+
};
|
|
9706
|
+
scheduleNext();
|
|
9707
|
+
const handleVisibility = () => {
|
|
9708
|
+
if (document.visibilityState === "visible") {
|
|
9709
|
+
fetchLogs();
|
|
9710
|
+
}
|
|
9711
|
+
};
|
|
9712
|
+
document.addEventListener("visibilitychange", handleVisibility);
|
|
9713
|
+
return () => {
|
|
9714
|
+
cancelled = true;
|
|
9715
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
9716
|
+
document.removeEventListener("visibilitychange", handleVisibility);
|
|
9717
|
+
};
|
|
9718
|
+
}, [fetchLogs]);
|
|
9719
|
+
React.useEffect(() => {
|
|
9720
|
+
if (autoScroll && containerRef.current) {
|
|
9721
|
+
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
9722
|
+
}
|
|
9723
|
+
}, [logs, autoScroll]);
|
|
9724
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
|
|
9725
|
+
display: "flex",
|
|
9726
|
+
flexDirection: "column",
|
|
9727
|
+
height: "calc(100vh - 64px)",
|
|
9728
|
+
background: "#1e1e2e",
|
|
9729
|
+
color: "#cdd6f4"
|
|
9730
|
+
}, children: [
|
|
9731
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
|
|
9732
|
+
display: "flex",
|
|
9733
|
+
gap: 8,
|
|
9734
|
+
padding: "8px 16px",
|
|
9735
|
+
borderBottom: "1px solid #313244",
|
|
9736
|
+
alignItems: "center",
|
|
9737
|
+
flexWrap: "wrap"
|
|
9738
|
+
}, children: [
|
|
9739
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { value: level, onValueChange: setLevel, size: "small", placeholder: "All Levels", children: [
|
|
9740
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "", children: "All Levels" }),
|
|
9741
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "debug", children: "Debug" }),
|
|
9742
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "info", children: "Info" }),
|
|
9743
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "warn", children: "Warn" }),
|
|
9744
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "error", children: "Error" })
|
|
9745
|
+
] }),
|
|
9746
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { value: source, onValueChange: setSource, size: "small", placeholder: "All Sources", children: [
|
|
9747
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "", children: "All Sources" }),
|
|
9748
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "api", children: "API" }),
|
|
9749
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "auth", children: "Auth" }),
|
|
9750
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "storage", children: "Storage" }),
|
|
9751
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "realtime", children: "Realtime" }),
|
|
9752
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "system", children: "System" })
|
|
9753
|
+
] }),
|
|
9754
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.TextField, { size: "small", placeholder: "Search logs...", value: search, onChange: (e) => setSearch(e.target.value), className: "flex-1 min-w-[200px]" }),
|
|
9755
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 cursor-pointer", children: [
|
|
9756
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Checkbox, { id: "auto-scroll", checked: autoScroll, onCheckedChange: setAutoScroll, size: "small", padding: false }),
|
|
9757
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "auto-scroll", className: "text-xs select-none cursor-pointer", children: "Auto-scroll" })
|
|
9758
|
+
] }),
|
|
9759
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: {
|
|
9760
|
+
fontSize: 12,
|
|
9761
|
+
color: "#6c7086"
|
|
9762
|
+
}, children: [
|
|
9763
|
+
logs.length,
|
|
9764
|
+
" entries"
|
|
9765
|
+
] })
|
|
9766
|
+
] }),
|
|
9767
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, style: {
|
|
9768
|
+
flex: 1,
|
|
9769
|
+
overflow: "auto",
|
|
9770
|
+
fontFamily: "monospace",
|
|
9771
|
+
fontSize: 12,
|
|
9772
|
+
padding: "8px 0"
|
|
9773
|
+
}, children: [
|
|
9774
|
+
logs.map((log) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
|
|
9775
|
+
padding: "2px 16px",
|
|
9776
|
+
display: "flex",
|
|
9777
|
+
gap: 8,
|
|
9778
|
+
borderBottom: "1px solid #181825"
|
|
9779
|
+
}, children: [
|
|
9780
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: {
|
|
9781
|
+
color: "#6c7086",
|
|
9782
|
+
flexShrink: 0
|
|
9783
|
+
}, children: new Date(log.timestamp).toLocaleTimeString() }),
|
|
9784
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: {
|
|
9785
|
+
color: LEVEL_COLORS[log.level] || "#cdd6f4",
|
|
9786
|
+
width: 40,
|
|
9787
|
+
flexShrink: 0,
|
|
9788
|
+
textTransform: "uppercase",
|
|
9789
|
+
fontWeight: 600
|
|
9790
|
+
}, children: log.level }),
|
|
9791
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: {
|
|
9792
|
+
color: SOURCE_COLORS[log.source] || "#cdd6f4",
|
|
9793
|
+
width: 64,
|
|
9794
|
+
flexShrink: 0
|
|
9795
|
+
}, children: [
|
|
9796
|
+
"[",
|
|
9797
|
+
log.source,
|
|
9798
|
+
"]"
|
|
9799
|
+
] }),
|
|
9800
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: {
|
|
9801
|
+
color: "#cdd6f4",
|
|
9802
|
+
flex: 1
|
|
9803
|
+
}, children: log.message })
|
|
9804
|
+
] }, log.id)),
|
|
9805
|
+
logs.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
9806
|
+
padding: 32,
|
|
9807
|
+
textAlign: "center",
|
|
9808
|
+
color: "#6c7086"
|
|
9809
|
+
}, children: "No log entries yet. Logs will appear here as requests come in." })
|
|
9810
|
+
] })
|
|
9811
|
+
] });
|
|
9812
|
+
}
|
|
9813
|
+
const LogsExplorer$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
9814
|
+
__proto__: null,
|
|
9815
|
+
LogsExplorer
|
|
9816
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
9620
9817
|
Object.defineProperty(exports2, "StudioBridgeContext", {
|
|
9621
9818
|
enumerable: true,
|
|
9622
9819
|
get: () => core.StudioBridgeContext
|