@lobb-js/studio 0.28.6 → 0.29.1
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/README.md +1 -0
- package/dist/actions.d.ts +2 -0
- package/dist/components/Studio.svelte +46 -47
- package/dist/components/StudioRoot.svelte +19 -0
- package/dist/components/StudioRoot.svelte.d.ts +6 -0
- package/dist/components/breadCrumbs.svelte +5 -4
- package/dist/components/codeEditor.svelte +1 -1
- package/dist/components/combobox.svelte +3 -3
- package/dist/components/confirmationDialog/confirmationDialog.svelte +1 -1
- package/dist/components/dataTable/dataTable.svelte +108 -101
- package/dist/components/dataTable/dataTable.svelte.d.ts +5 -20
- package/dist/components/dataTable/dataTableTabs.svelte +4 -2
- package/dist/components/dataTable/dataTableTabs.svelte.d.ts +2 -0
- package/dist/components/dataTable/filter.svelte +1 -1
- package/dist/components/dataTable/filterButton.svelte +1 -1
- package/dist/components/dataTable/header.svelte +30 -47
- package/dist/components/dataTable/header.svelte.d.ts +4 -2
- package/dist/components/dataTable/listViewChildren.svelte +4 -6
- package/dist/components/dataTable/listViewChildren.svelte.d.ts +0 -1
- package/dist/components/dataTable/sort.svelte +1 -1
- package/dist/components/dataTable/sortButton.svelte +2 -2
- package/dist/components/dataTable/table.svelte +8 -10
- package/dist/components/dataTable/table.svelte.d.ts +0 -1
- package/dist/components/dataTableDrawer/dataTableDrawer.svelte +4 -1
- package/dist/components/dataTableDrawer/dataTableDrawer.svelte.d.ts +2 -0
- package/dist/components/detailView/create/children.svelte +2 -2
- package/dist/components/detailView/create/createDetailView.svelte +81 -88
- package/dist/components/detailView/create/createDetailView.svelte.d.ts +2 -2
- package/dist/components/detailView/create/createDetailViewButton.svelte +2 -2
- package/dist/components/detailView/create/createDetailViewButton.svelte.d.ts +1 -1
- package/dist/components/detailView/create/createManyView.svelte +12 -10
- package/dist/components/detailView/detailView.svelte +81 -0
- package/dist/components/detailView/detailView.svelte.d.ts +8 -0
- package/dist/components/detailView/fieldInput.svelte +11 -11
- package/dist/components/detailView/fieldInputReplacement.svelte +8 -8
- package/dist/components/detailView/passwordInput.svelte +1 -1
- package/dist/components/detailView/update/detailViewChildren.svelte +15 -26
- package/dist/components/detailView/update/detailViewChildren.svelte.d.ts +3 -8
- package/dist/components/detailView/update/updateDetailView.svelte +90 -69
- package/dist/components/detailView/update/updateDetailView.svelte.d.ts +2 -2
- package/dist/components/detailView/update/updateDetailViewButton.svelte +3 -2
- package/dist/components/detailView/update/updateDetailViewButton.svelte.d.ts +1 -1
- package/dist/components/detailView/utils.d.ts +17 -0
- package/dist/components/diffViewer.svelte +1 -1
- package/dist/components/extensionsComponents.svelte +3 -1
- package/dist/components/foreingKeyInput.svelte +2 -2
- package/dist/components/importButton.svelte +12 -9
- package/dist/components/landing.svelte +7 -0
- package/dist/components/landing.svelte.d.ts +6 -14
- package/dist/components/miniSidebar.svelte +90 -19
- package/dist/components/miniSidebar.svelte.d.ts +2 -17
- package/dist/components/polymorphicInput.svelte +1 -1
- package/dist/components/rangeCalendarButton.svelte +13 -13
- package/dist/components/richTextEditor.svelte +1 -1
- package/dist/components/routes/collections/collection.svelte +3 -3
- package/dist/components/routes/collections/collections.svelte +34 -12
- package/dist/components/routes/data_model/dataModel.svelte +6 -28
- package/dist/components/routes/data_model/dataModel.svelte.d.ts +17 -2
- package/dist/components/routes/extensions/extension.svelte +1 -1
- package/dist/components/routes/extensions/publicExtension.svelte +19 -0
- package/dist/components/routes/extensions/publicExtension.svelte.d.ts +13 -0
- package/dist/components/routes/home.svelte +3 -3
- package/dist/components/routes/workflows/workflows.svelte +9 -9
- package/dist/components/selectRecord.svelte +2 -21
- package/dist/components/setServerPage.svelte +1 -1
- package/dist/components/sidebar/sidebar.svelte +1 -1
- package/dist/components/sidebar/sidebarElements.svelte +4 -4
- package/dist/components/singletone.svelte +4 -6
- package/dist/components/ui/alert-dialog/alert-dialog-action.svelte +1 -1
- package/dist/components/ui/alert-dialog/alert-dialog-cancel.svelte +1 -1
- package/dist/components/ui/button/button.svelte +2 -3
- package/dist/components/ui/command/command-dialog.svelte +1 -1
- package/dist/components/ui/range-calendar/range-calendar-day.svelte +1 -1
- package/dist/components/ui/range-calendar/range-calendar-next-button.svelte +1 -1
- package/dist/components/ui/range-calendar/range-calendar-prev-button.svelte +1 -1
- package/dist/components/ui/select/select-separator.svelte +1 -1
- package/dist/components/workflowEditor.svelte +5 -5
- package/dist/eventSystem.d.ts +1 -1
- package/dist/eventSystem.js +7 -5
- package/dist/extensions/extension.types.d.ts +38 -14
- package/dist/extensions/extensionUtils.js +4 -2
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/store.types.d.ts +2 -2
- package/dist/studioLifecycle.svelte.d.ts +2 -0
- package/dist/studioLifecycle.svelte.js +15 -0
- package/package.json +3 -4
- package/src/app.css +3 -0
- package/src/lib/actions.ts +2 -0
- package/src/lib/components/Studio.svelte +46 -47
- package/src/lib/components/StudioRoot.svelte +19 -0
- package/src/lib/components/breadCrumbs.svelte +5 -4
- package/src/lib/components/codeEditor.svelte +1 -1
- package/src/lib/components/combobox.svelte +3 -3
- package/src/lib/components/confirmationDialog/confirmationDialog.svelte +1 -1
- package/src/lib/components/dataTable/dataTable.svelte +108 -101
- package/src/lib/components/dataTable/dataTableTabs.svelte +4 -2
- package/src/lib/components/dataTable/filter.svelte +1 -1
- package/src/lib/components/dataTable/filterButton.svelte +1 -1
- package/src/lib/components/dataTable/header.svelte +30 -47
- package/src/lib/components/dataTable/listViewChildren.svelte +4 -6
- package/src/lib/components/dataTable/sort.svelte +1 -1
- package/src/lib/components/dataTable/sortButton.svelte +2 -2
- package/src/lib/components/dataTable/table.svelte +8 -10
- package/src/lib/components/dataTableDrawer/dataTableDrawer.svelte +4 -1
- package/src/lib/components/detailView/create/children.svelte +2 -2
- package/src/lib/components/detailView/create/createDetailView.svelte +81 -88
- package/src/lib/components/detailView/create/createDetailViewButton.svelte +2 -2
- package/src/lib/components/detailView/create/createManyView.svelte +12 -10
- package/src/lib/components/detailView/detailView.svelte +81 -0
- package/src/lib/components/detailView/fieldInput.svelte +11 -11
- package/src/lib/components/detailView/fieldInputReplacement.svelte +8 -8
- package/src/lib/components/detailView/passwordInput.svelte +1 -1
- package/src/lib/components/detailView/update/detailViewChildren.svelte +15 -26
- package/src/lib/components/detailView/update/updateDetailView.svelte +90 -69
- package/src/lib/components/detailView/update/updateDetailViewButton.svelte +3 -2
- package/src/lib/components/detailView/utils.ts +13 -0
- package/src/lib/components/diffViewer.svelte +1 -1
- package/src/lib/components/extensionsComponents.svelte +3 -1
- package/src/lib/components/foreingKeyInput.svelte +2 -2
- package/src/lib/components/importButton.svelte +12 -9
- package/src/lib/components/landing.svelte +7 -0
- package/src/lib/components/miniSidebar.svelte +90 -19
- package/src/lib/components/polymorphicInput.svelte +1 -1
- package/src/lib/components/rangeCalendarButton.svelte +13 -13
- package/src/lib/components/richTextEditor.svelte +1 -1
- package/src/lib/components/routes/collections/collection.svelte +3 -3
- package/src/lib/components/routes/collections/collections.svelte +34 -12
- package/src/lib/components/routes/data_model/dataModel.svelte +6 -28
- package/src/lib/components/routes/extensions/extension.svelte +1 -1
- package/src/lib/components/routes/extensions/publicExtension.svelte +19 -0
- package/src/lib/components/routes/home.svelte +3 -3
- package/src/lib/components/routes/workflows/workflows.svelte +9 -9
- package/src/lib/components/selectRecord.svelte +2 -21
- package/src/lib/components/setServerPage.svelte +1 -1
- package/src/lib/components/sidebar/sidebar.svelte +1 -1
- package/src/lib/components/sidebar/sidebarElements.svelte +4 -4
- package/src/lib/components/singletone.svelte +4 -6
- package/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte +1 -1
- package/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte +1 -1
- package/src/lib/components/ui/button/button.svelte +2 -3
- package/src/lib/components/ui/command/command-dialog.svelte +1 -1
- package/src/lib/components/ui/range-calendar/range-calendar-day.svelte +1 -1
- package/src/lib/components/ui/range-calendar/range-calendar-next-button.svelte +1 -1
- package/src/lib/components/ui/range-calendar/range-calendar-prev-button.svelte +1 -1
- package/src/lib/components/ui/select/select-separator.svelte +1 -1
- package/src/lib/components/workflowEditor.svelte +5 -5
- package/src/lib/eventSystem.ts +8 -7
- package/src/lib/extensions/extension.types.ts +39 -6
- package/src/lib/extensions/extensionUtils.ts +4 -2
- package/src/lib/index.ts +3 -1
- package/src/lib/store.types.ts +2 -2
- package/src/lib/studioLifecycle.svelte.ts +17 -0
- package/vite-plugins/index.js +2 -4
- package/vite-plugins/utils.js +15 -0
- package/vite-plugins/{workspace-optimize.js → workspace-fs-allow.js} +4 -18
- package/dist/components/routes/data_model/syncManager.svelte +0 -94
- package/dist/components/routes/data_model/syncManager.svelte.d.ts +0 -3
- package/src/lib/components/routes/data_model/syncManager.svelte +0 -94
- package/vite-plugins/contextual-lib-alias.js +0 -67
|
@@ -11,7 +11,8 @@ import type CreateDetailViewButton from "../components/detailView/create/createD
|
|
|
11
11
|
import type UpdateDetailViewButton from "../components/detailView/update/updateDetailViewButton.svelte";
|
|
12
12
|
import type { mediaQueries } from "../utils";
|
|
13
13
|
import type Table from "../components/dataTable/table.svelte";
|
|
14
|
-
import type {
|
|
14
|
+
import type { page } from "$app/state";
|
|
15
|
+
import type { goto } from "$app/navigation";
|
|
15
16
|
import type RangeCalendarButton from "../components/rangeCalendarButton.svelte";
|
|
16
17
|
import type DataTable from "../components/dataTable/dataTable.svelte";
|
|
17
18
|
import type Drawer from "../components/drawer.svelte";
|
|
@@ -22,7 +23,7 @@ import * as Icons from "lucide-svelte"
|
|
|
22
23
|
import { ContextMenu } from "bits-ui";
|
|
23
24
|
import * as Tooltip from "../components/ui/tooltip";
|
|
24
25
|
import * as Breadcrumb from "../components/ui/breadcrumb";
|
|
25
|
-
import { showDialog } from "../actions";
|
|
26
|
+
import { showDialog, type OpenDataTableDrawerProps } from "../actions";
|
|
26
27
|
import { toast } from "svelte-sonner";
|
|
27
28
|
import type Drawer from "../components/drawer.svelte";
|
|
28
29
|
import { Switch } from "../components/ui/switch";
|
|
@@ -54,11 +55,23 @@ export interface Components {
|
|
|
54
55
|
export interface ExtensionUtils {
|
|
55
56
|
ctx: CTX;
|
|
56
57
|
lobb: LobbClient;
|
|
57
|
-
|
|
58
|
+
/**
|
|
59
|
+
* SvelteKit's reactive page proxy — exposes `url`, `params`, `route`,
|
|
60
|
+
* `data`, `state`, `error`. Access fields through the proxy
|
|
61
|
+
* (`utils.page.url.pathname`); don't destructure if you need
|
|
62
|
+
* reactivity (`const { url } = utils.page` is a one-time snapshot).
|
|
63
|
+
*/
|
|
64
|
+
page: typeof page;
|
|
65
|
+
/**
|
|
66
|
+
* SvelteKit's client-side navigation. Same signature as
|
|
67
|
+
* `goto(href, options?)` — supports `replaceState`, `invalidateAll`,
|
|
68
|
+
* `noScroll`, `keepFocus`, etc.
|
|
69
|
+
*/
|
|
70
|
+
goto: typeof goto;
|
|
58
71
|
toast: typeof toast;
|
|
59
72
|
showDialog: typeof showDialog;
|
|
60
|
-
openDataTableDrawer: (props:
|
|
61
|
-
emitEvent: (eventName: string, input:
|
|
73
|
+
openDataTableDrawer: (props: OpenDataTableDrawerProps) => void;
|
|
74
|
+
emitEvent: (eventName: string, input: any) => Promise<any>;
|
|
62
75
|
components: Components;
|
|
63
76
|
mediaQueries: typeof mediaQueries;
|
|
64
77
|
intlDate: typeof intlDate;
|
|
@@ -71,6 +84,24 @@ interface DashboardNav {
|
|
|
71
84
|
href?: string;
|
|
72
85
|
onclick?: () => void;
|
|
73
86
|
navs?: DashboardNav[];
|
|
87
|
+
/**
|
|
88
|
+
* The collection(s) this nav item represents — i.e. the UI surface it
|
|
89
|
+
* exposes for that data.
|
|
90
|
+
*
|
|
91
|
+
* Visibility is derived from this: the auth extension's `auth.canAccess`
|
|
92
|
+
* workflow checks the current user's read permission on the represented
|
|
93
|
+
* collection(s), and the item is hidden if denied. Items without a
|
|
94
|
+
* `represents` value are always visible.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* // single collection
|
|
98
|
+
* { label: "Reports", href: "/reports", icon: BarChart, represents: "reports_dashboards" }
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* // multiple collections — user must be able to read all of them
|
|
102
|
+
* { label: "Audit", href: "/audit", icon: ShieldCheck, represents: ["audit_log", "auth_users"] }
|
|
103
|
+
*/
|
|
104
|
+
represents?: string | string[];
|
|
74
105
|
}
|
|
75
106
|
|
|
76
107
|
export interface DashboardNavs {
|
|
@@ -88,11 +119,13 @@ export interface ExtensionProps {
|
|
|
88
119
|
// TODO: instead of doing them this way. you can make the components generic and have static keys and we can pass some dynamic data so that we for example extend the list view
|
|
89
120
|
export type ExtensionComponentKey =
|
|
90
121
|
| `pages.${string}`
|
|
122
|
+
| `publicPages.${string}`
|
|
91
123
|
| "studio.listView"
|
|
92
124
|
| `dvFields.topRight.${string}.${string}`
|
|
93
125
|
| `detailView.update.subRecords.${string}`
|
|
94
126
|
| `detailView.create.subRecords.${string}`
|
|
95
127
|
| `detailView.fields.topRight.${string}.${string}`
|
|
128
|
+
| "detailView.field.label"
|
|
96
129
|
| `detailView.fields.foreignKey.${string}`
|
|
97
130
|
| `listView.entry.children.${string}`
|
|
98
131
|
| `listView.entry.actions`
|
|
@@ -112,7 +145,7 @@ export interface StudioWorkflowContext {
|
|
|
112
145
|
|
|
113
146
|
export interface StudioWorkflow {
|
|
114
147
|
eventName: string;
|
|
115
|
-
handler: (input:
|
|
148
|
+
handler: (input: any, context: StudioWorkflowContext) => Promise<any>;
|
|
116
149
|
}
|
|
117
150
|
|
|
118
151
|
// extension exported object
|
|
@@ -26,7 +26,8 @@ import * as Breadcrumb from "../components/ui/breadcrumb";
|
|
|
26
26
|
import { ContextMenu } from "bits-ui";
|
|
27
27
|
import * as Popover from "../components/ui/popover";
|
|
28
28
|
import * as Icons from "lucide-svelte";
|
|
29
|
-
import {
|
|
29
|
+
import { page } from "$app/state";
|
|
30
|
+
import { goto } from "$app/navigation";
|
|
30
31
|
import RangeCalendarButton from "../components/rangeCalendarButton.svelte";
|
|
31
32
|
import DataTable from "../components/dataTable/dataTable.svelte";
|
|
32
33
|
import Drawer from "../components/drawer.svelte";
|
|
@@ -62,7 +63,8 @@ export function getExtensionUtils(lobb: LobbClient, ctx: CTX): ExtensionUtils {
|
|
|
62
63
|
return {
|
|
63
64
|
ctx: ctx,
|
|
64
65
|
lobb: lobb,
|
|
65
|
-
|
|
66
|
+
page: page,
|
|
67
|
+
goto: goto,
|
|
66
68
|
toast: toast,
|
|
67
69
|
showDialog: showDialog,
|
|
68
70
|
openDataTableDrawer: (props) => openDataTableDrawer({ lobb, ctx }, props),
|
package/src/lib/index.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export type { ExtensionProps, Extension, ExtensionUtils } from "./extensions/extension.types"
|
|
2
2
|
|
|
3
|
-
export { default as
|
|
3
|
+
export { default as StudioRoot } from "./components/StudioRoot.svelte";
|
|
4
4
|
export { default as Landing } from "./components/landing.svelte";
|
|
5
|
+
export { remountStudio } from "./studioLifecycle.svelte";
|
|
5
6
|
export { Button } from "./components/ui/button";
|
|
6
7
|
export { Input } from "./components/ui/input";
|
|
7
8
|
export { Separator } from "./components/ui/separator";
|
|
@@ -11,6 +12,7 @@ export { default as Sidebar } from "./components/sidebar/sidebar.svelte";
|
|
|
11
12
|
export { default as SidebarTrigger } from "./components/sidebar/sidebarTrigger.svelte";
|
|
12
13
|
export { default as CreateDetailViewButton } from "./components/detailView/create/createDetailViewButton.svelte";
|
|
13
14
|
export { default as UpdateDetailViewButton } from "./components/detailView/update/updateDetailViewButton.svelte";
|
|
15
|
+
export { default as DetailView } from "./components/detailView/detailView.svelte";
|
|
14
16
|
export * as Tooltip from "./components/ui/tooltip";
|
|
15
17
|
export * as Breadcrumb from "./components/ui/breadcrumb";
|
|
16
18
|
export { ContextMenu } from "bits-ui";
|
package/src/lib/store.types.ts
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Module-level reactive signal that the Studio root listens to via {#key ...}.
|
|
2
|
+
// Bumping this value tears down the entire Studio component tree and mounts
|
|
3
|
+
// a fresh one, so onStartup re-runs and everything downstream (ctx,
|
|
4
|
+
// extensions, sidebar) initialises with the new session state.
|
|
5
|
+
//
|
|
6
|
+
// Use cases: after login, after logout, after a role/permissions change.
|
|
7
|
+
// Consumers (e.g. the auth extension) call `remountStudio()` instead of
|
|
8
|
+
// having every UI surface listen for auth changes reactively.
|
|
9
|
+
let mountKey = $state(0);
|
|
10
|
+
|
|
11
|
+
export function getStudioMountKey(): number {
|
|
12
|
+
return mountKey;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function remountStudio(): void {
|
|
16
|
+
mountKey += 1;
|
|
17
|
+
}
|
package/vite-plugins/index.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { lobbWorkspaceOptimize } from "./workspace-optimize.js";
|
|
1
|
+
import { lobbWorkspaceFsAllow } from "./workspace-fs-allow.js";
|
|
3
2
|
import { lobbExtensionsPlugin } from "./lobb-extensions.js";
|
|
4
3
|
import { lobbProxyPlugin } from "./lobb-proxy.js";
|
|
5
4
|
|
|
6
5
|
export function lobbStudioPlugins() {
|
|
7
6
|
return [
|
|
8
|
-
|
|
9
|
-
lobbWorkspaceOptimize(),
|
|
7
|
+
lobbWorkspaceFsAllow(),
|
|
10
8
|
lobbExtensionsPlugin(),
|
|
11
9
|
lobbProxyPlugin(),
|
|
12
10
|
];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
|
|
4
|
+
export function getMonorepoRoot() {
|
|
5
|
+
let dir = process.cwd();
|
|
6
|
+
while (true) {
|
|
7
|
+
try {
|
|
8
|
+
const pkg = JSON.parse(readFileSync(join(dir, "package.json"), "utf-8"));
|
|
9
|
+
if (pkg?.workspaces) return dir;
|
|
10
|
+
} catch { /* no package.json here, keep walking */ }
|
|
11
|
+
const parent = dirname(dir);
|
|
12
|
+
if (parent === dir) return null;
|
|
13
|
+
dir = parent;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
1
|
+
import { getMonorepoRoot } from "./utils.js";
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* In monorepo dev, workspace packages are symlinked into node_modules.
|
|
@@ -13,13 +12,13 @@ import { dirname, join } from "node:path";
|
|
|
13
12
|
*
|
|
14
13
|
* @returns {import('vite').Plugin}
|
|
15
14
|
*/
|
|
16
|
-
export function
|
|
15
|
+
export function lobbWorkspaceFsAllow() {
|
|
17
16
|
return {
|
|
18
|
-
name: "lobb-workspace-
|
|
17
|
+
name: "lobb-workspace-fs-allow",
|
|
19
18
|
config(_, { command }) {
|
|
20
19
|
if (command !== "serve") return;
|
|
21
20
|
|
|
22
|
-
const monorepoRoot =
|
|
21
|
+
const monorepoRoot = getMonorepoRoot();
|
|
23
22
|
if (!monorepoRoot) return;
|
|
24
23
|
|
|
25
24
|
return {
|
|
@@ -32,16 +31,3 @@ export function lobbWorkspaceOptimize() {
|
|
|
32
31
|
},
|
|
33
32
|
};
|
|
34
33
|
}
|
|
35
|
-
|
|
36
|
-
function findMonorepoRoot() {
|
|
37
|
-
let dir = process.cwd();
|
|
38
|
-
while (true) {
|
|
39
|
-
try {
|
|
40
|
-
const pkg = JSON.parse(readFileSync(join(dir, "package.json"), "utf-8"));
|
|
41
|
-
if (pkg?.workspaces) return dir;
|
|
42
|
-
} catch { /* no package.json here, keep walking */ }
|
|
43
|
-
const parent = dirname(dir);
|
|
44
|
-
if (parent === dir) return null;
|
|
45
|
-
dir = parent;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import DiffViewer from "../../../components/diffViewer.svelte";
|
|
3
|
-
import { getStudioContext } from "../../../context";
|
|
4
|
-
|
|
5
|
-
const { lobb, ctx } = getStudioContext();
|
|
6
|
-
import { onMount } from "svelte";
|
|
7
|
-
import stringify from "json-stable-stringify";
|
|
8
|
-
import CodeEditor from "../../../components/codeEditor.svelte";
|
|
9
|
-
import Table from "../../../components/dataTable/table.svelte";
|
|
10
|
-
import Button from "../../../components/ui/button/button.svelte";
|
|
11
|
-
import { LoaderCircle, SendHorizontal } from "lucide-svelte";
|
|
12
|
-
|
|
13
|
-
let configSchema: string = $state("");
|
|
14
|
-
let dbSchema: string = $state("");
|
|
15
|
-
let sqlPrompt = $state("");
|
|
16
|
-
let sqlResult = $state([]);
|
|
17
|
-
|
|
18
|
-
onMount(() => {
|
|
19
|
-
loadSchemas();
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
async function loadSchemas() {
|
|
23
|
-
configSchema = "";
|
|
24
|
-
dbSchema = "";
|
|
25
|
-
const response = await fetch(`${ctx.lobbUrl}/api/schema/diff`);
|
|
26
|
-
const result = await response.json();
|
|
27
|
-
configSchema = stringify(result.dbSchema, {
|
|
28
|
-
space: 2,
|
|
29
|
-
}) as string;
|
|
30
|
-
dbSchema = stringify(result.configSchema, {
|
|
31
|
-
space: 2,
|
|
32
|
-
}) as string;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async function handleExecute() {
|
|
36
|
-
const response = await lobb.createOne("core_query", {
|
|
37
|
-
query: sqlPrompt,
|
|
38
|
-
});
|
|
39
|
-
const result = await response.json();
|
|
40
|
-
sqlResult = result.data;
|
|
41
|
-
loadSchemas();
|
|
42
|
-
}
|
|
43
|
-
</script>
|
|
44
|
-
|
|
45
|
-
<div class="h-[50%] border-b overflow-auto">
|
|
46
|
-
{#if configSchema && dbSchema}
|
|
47
|
-
<DiffViewer
|
|
48
|
-
type="json"
|
|
49
|
-
original={configSchema}
|
|
50
|
-
modified={dbSchema}
|
|
51
|
-
class="h-full rounded-none border-0"
|
|
52
|
-
/>
|
|
53
|
-
{:else}
|
|
54
|
-
<div class="flex justify-center items-center h-full gap-2">
|
|
55
|
-
<LoaderCircle class="animate-spin" />
|
|
56
|
-
<div>loading...</div>
|
|
57
|
-
</div>
|
|
58
|
-
{/if}
|
|
59
|
-
</div>
|
|
60
|
-
<div class="flex h-[50%] w-full">
|
|
61
|
-
<div class="h-full flex-1 flex flex-col border-r">
|
|
62
|
-
<div
|
|
63
|
-
class="h-10 flex items-center px-2 bg-background border-b justify-between"
|
|
64
|
-
>
|
|
65
|
-
<div>Query Editor</div>
|
|
66
|
-
<Button
|
|
67
|
-
class="h-7 px-3 text-xs font-normal"
|
|
68
|
-
Icon={SendHorizontal}
|
|
69
|
-
onclick={handleExecute}
|
|
70
|
-
>
|
|
71
|
-
Execute
|
|
72
|
-
</Button>
|
|
73
|
-
</div>
|
|
74
|
-
<CodeEditor
|
|
75
|
-
type="sql"
|
|
76
|
-
name="prompt"
|
|
77
|
-
bind:value={sqlPrompt}
|
|
78
|
-
class="flex-1 rounded-none border-0"
|
|
79
|
-
/>
|
|
80
|
-
</div>
|
|
81
|
-
<div class="flex-1">
|
|
82
|
-
{#if Array.isArray(sqlResult) && sqlResult.length}
|
|
83
|
-
<Table
|
|
84
|
-
data={sqlResult}
|
|
85
|
-
showLastRowBorder={true}
|
|
86
|
-
showLastColumnBorder={true}
|
|
87
|
-
/>
|
|
88
|
-
{:else}
|
|
89
|
-
<div class="flex flex-1 h-full items-center justify-center">
|
|
90
|
-
No results
|
|
91
|
-
</div>
|
|
92
|
-
{/if}
|
|
93
|
-
</div>
|
|
94
|
-
</div>
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import DiffViewer from "../../../components/diffViewer.svelte";
|
|
3
|
-
import { getStudioContext } from "../../../context";
|
|
4
|
-
|
|
5
|
-
const { lobb, ctx } = getStudioContext();
|
|
6
|
-
import { onMount } from "svelte";
|
|
7
|
-
import stringify from "json-stable-stringify";
|
|
8
|
-
import CodeEditor from "../../../components/codeEditor.svelte";
|
|
9
|
-
import Table from "../../../components/dataTable/table.svelte";
|
|
10
|
-
import Button from "../../../components/ui/button/button.svelte";
|
|
11
|
-
import { LoaderCircle, SendHorizontal } from "lucide-svelte";
|
|
12
|
-
|
|
13
|
-
let configSchema: string = $state("");
|
|
14
|
-
let dbSchema: string = $state("");
|
|
15
|
-
let sqlPrompt = $state("");
|
|
16
|
-
let sqlResult = $state([]);
|
|
17
|
-
|
|
18
|
-
onMount(() => {
|
|
19
|
-
loadSchemas();
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
async function loadSchemas() {
|
|
23
|
-
configSchema = "";
|
|
24
|
-
dbSchema = "";
|
|
25
|
-
const response = await fetch(`${ctx.lobbUrl}/api/schema/diff`);
|
|
26
|
-
const result = await response.json();
|
|
27
|
-
configSchema = stringify(result.dbSchema, {
|
|
28
|
-
space: 2,
|
|
29
|
-
}) as string;
|
|
30
|
-
dbSchema = stringify(result.configSchema, {
|
|
31
|
-
space: 2,
|
|
32
|
-
}) as string;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async function handleExecute() {
|
|
36
|
-
const response = await lobb.createOne("core_query", {
|
|
37
|
-
query: sqlPrompt,
|
|
38
|
-
});
|
|
39
|
-
const result = await response.json();
|
|
40
|
-
sqlResult = result.data;
|
|
41
|
-
loadSchemas();
|
|
42
|
-
}
|
|
43
|
-
</script>
|
|
44
|
-
|
|
45
|
-
<div class="h-[50%] border-b overflow-auto">
|
|
46
|
-
{#if configSchema && dbSchema}
|
|
47
|
-
<DiffViewer
|
|
48
|
-
type="json"
|
|
49
|
-
original={configSchema}
|
|
50
|
-
modified={dbSchema}
|
|
51
|
-
class="h-full rounded-none border-0"
|
|
52
|
-
/>
|
|
53
|
-
{:else}
|
|
54
|
-
<div class="flex justify-center items-center h-full gap-2">
|
|
55
|
-
<LoaderCircle class="animate-spin" />
|
|
56
|
-
<div>loading...</div>
|
|
57
|
-
</div>
|
|
58
|
-
{/if}
|
|
59
|
-
</div>
|
|
60
|
-
<div class="flex h-[50%] w-full">
|
|
61
|
-
<div class="h-full flex-1 flex flex-col border-r">
|
|
62
|
-
<div
|
|
63
|
-
class="h-10 flex items-center px-2 bg-background border-b justify-between"
|
|
64
|
-
>
|
|
65
|
-
<div>Query Editor</div>
|
|
66
|
-
<Button
|
|
67
|
-
class="h-7 px-3 text-xs font-normal"
|
|
68
|
-
Icon={SendHorizontal}
|
|
69
|
-
onclick={handleExecute}
|
|
70
|
-
>
|
|
71
|
-
Execute
|
|
72
|
-
</Button>
|
|
73
|
-
</div>
|
|
74
|
-
<CodeEditor
|
|
75
|
-
type="sql"
|
|
76
|
-
name="prompt"
|
|
77
|
-
bind:value={sqlPrompt}
|
|
78
|
-
class="flex-1 rounded-none border-0"
|
|
79
|
-
/>
|
|
80
|
-
</div>
|
|
81
|
-
<div class="flex-1">
|
|
82
|
-
{#if Array.isArray(sqlResult) && sqlResult.length}
|
|
83
|
-
<Table
|
|
84
|
-
data={sqlResult}
|
|
85
|
-
showLastRowBorder={true}
|
|
86
|
-
showLastColumnBorder={true}
|
|
87
|
-
/>
|
|
88
|
-
{:else}
|
|
89
|
-
<div class="flex flex-1 h-full items-center justify-center">
|
|
90
|
-
No results
|
|
91
|
-
</div>
|
|
92
|
-
{/if}
|
|
93
|
-
</div>
|
|
94
|
-
</div>
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import fs from "fs";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Vite plugin that resolves $lib imports contextually based on the importing file's package.
|
|
6
|
-
*
|
|
7
|
-
* Walks up the directory tree from the importer to find the nearest package.json,
|
|
8
|
-
* then checks if that package has a src/lib directory. If so, resolves $lib to that path.
|
|
9
|
-
*
|
|
10
|
-
* This allows any package using the src/lib convention to use $lib imports without conflicts.
|
|
11
|
-
*
|
|
12
|
-
* @returns {import('vite').Plugin}
|
|
13
|
-
*/
|
|
14
|
-
export function contextualLibAlias() {
|
|
15
|
-
const packageRootCache = new Map();
|
|
16
|
-
|
|
17
|
-
function findPackageRoot(filePath) {
|
|
18
|
-
const dir = path.dirname(filePath);
|
|
19
|
-
|
|
20
|
-
// Check cache
|
|
21
|
-
if (packageRootCache.has(dir)) {
|
|
22
|
-
return packageRootCache.get(dir);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Walk up directories to find package.json
|
|
26
|
-
let currentDir = dir;
|
|
27
|
-
const rootDir = path.parse(currentDir).root;
|
|
28
|
-
|
|
29
|
-
while (currentDir !== rootDir) {
|
|
30
|
-
const pkgPath = path.join(currentDir, "package.json");
|
|
31
|
-
if (fs.existsSync(pkgPath)) {
|
|
32
|
-
packageRootCache.set(dir, currentDir);
|
|
33
|
-
return currentDir;
|
|
34
|
-
}
|
|
35
|
-
currentDir = path.dirname(currentDir);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Not found
|
|
39
|
-
packageRootCache.set(dir, null);
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
name: "contextual-lib-alias",
|
|
45
|
-
enforce: "pre",
|
|
46
|
-
|
|
47
|
-
async resolveId(source, importer, options) {
|
|
48
|
-
if (!source.startsWith("$lib")) return null;
|
|
49
|
-
if (!importer) return null;
|
|
50
|
-
|
|
51
|
-
// Find the package root for the importing file
|
|
52
|
-
const packageRoot = findPackageRoot(importer);
|
|
53
|
-
if (!packageRoot) return null;
|
|
54
|
-
|
|
55
|
-
// Check if this package has src/lib
|
|
56
|
-
const libPath = path.join(packageRoot, "src/lib");
|
|
57
|
-
if (!fs.existsSync(libPath)) return null;
|
|
58
|
-
|
|
59
|
-
// Resolve $lib to this package's src/lib
|
|
60
|
-
const importPath = source.slice(4); // Remove "$lib"
|
|
61
|
-
const resolvedPath = path.join(libPath, importPath);
|
|
62
|
-
|
|
63
|
-
// Let Vite resolve the actual file (handles .js, .ts, .svelte extensions)
|
|
64
|
-
return this.resolve(resolvedPath, importer, { skipSelf: true, ...options });
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
}
|