@mongoosejs/studio 0.5.1 → 0.5.3
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/backend/actions/ChatThread/streamChatMessage.js +12 -12
- package/backend/actions/Dashboard/getDashboard.js +29 -2
- package/backend/actions/Model/dropCollection.js +29 -0
- package/backend/actions/Model/index.js +1 -0
- package/backend/authorize.js +1 -0
- package/backend/chatAgent/agentSystemPrompt.js +22 -10
- package/backend/chatAgent/getAgentTools.js +19 -8
- package/backend/chatAgent/runChatAgent.js +17 -0
- package/backend/db/dashboardSchema.js +0 -32
- package/backend/index.js +4 -1
- package/backend/integrations/callLLM.js +5 -20
- package/backend/integrations/streamLLM.js +5 -24
- package/backend/sandbox/createSandbox.js +6 -0
- package/backend/vercel.js +3 -0
- package/debugging.js +11 -0
- package/eval/agent/cases.js +168 -0
- package/eval/agent/fixtures/carsharing.js +147 -0
- package/eval/agent/fixtures/ecommerce.js +152 -0
- package/eval/agent/run.js +323 -0
- package/frontend/index.js +2 -1
- package/frontend/public/app.js +581 -203
- package/frontend/public/tw.css +81 -0
- package/frontend/src/_util/recent-pages-history.js +116 -0
- package/frontend/src/api.js +96 -164
- package/frontend/src/chat/chat-message-script/chat-message-script.html +1 -6
- package/frontend/src/chat/chat.html +1 -1
- package/frontend/src/document/confirm-changes/confirm-changes.js +20 -0
- package/frontend/src/document/document.html +2 -2
- package/frontend/src/index.js +148 -1
- package/frontend/src/json-node/json-node.html +41 -39
- package/frontend/src/json-node/json-node.js +38 -0
- package/frontend/src/list-json/list-json.html +3 -2
- package/frontend/src/list-json/list-json.js +5 -0
- package/frontend/src/modal/modal.css +26 -1
- package/frontend/src/modal/modal.html +2 -2
- package/frontend/src/modal/modal.js +5 -1
- package/frontend/src/models/models.html +45 -5
- package/frontend/src/models/models.js +26 -0
- package/frontend/src/navbar/navbar.html +92 -5
- package/frontend/src/navbar/navbar.js +69 -1
- package/index.js +2 -1
- package/package.json +3 -2
package/frontend/public/tw.css
CHANGED
|
@@ -1192,6 +1192,10 @@ video {
|
|
|
1192
1192
|
width: 90vw !important;
|
|
1193
1193
|
}
|
|
1194
1194
|
|
|
1195
|
+
.\!w-\[min\(94vw\2c 28rem\)\] {
|
|
1196
|
+
width: min(94vw,28rem) !important;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1195
1199
|
.w-0 {
|
|
1196
1200
|
width: 0px;
|
|
1197
1201
|
}
|
|
@@ -1583,6 +1587,16 @@ video {
|
|
|
1583
1587
|
gap: 2rem;
|
|
1584
1588
|
}
|
|
1585
1589
|
|
|
1590
|
+
.gap-x-1 {
|
|
1591
|
+
-moz-column-gap: 0.25rem;
|
|
1592
|
+
column-gap: 0.25rem;
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1595
|
+
.gap-x-1\.5 {
|
|
1596
|
+
-moz-column-gap: 0.375rem;
|
|
1597
|
+
column-gap: 0.375rem;
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1586
1600
|
.gap-x-4 {
|
|
1587
1601
|
-moz-column-gap: 1rem;
|
|
1588
1602
|
column-gap: 1rem;
|
|
@@ -1666,6 +1680,10 @@ video {
|
|
|
1666
1680
|
overflow: auto;
|
|
1667
1681
|
}
|
|
1668
1682
|
|
|
1683
|
+
.\!overflow-hidden {
|
|
1684
|
+
overflow: hidden !important;
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1669
1687
|
.overflow-hidden {
|
|
1670
1688
|
overflow: hidden;
|
|
1671
1689
|
}
|
|
@@ -1708,6 +1726,10 @@ video {
|
|
|
1708
1726
|
word-break: break-all;
|
|
1709
1727
|
}
|
|
1710
1728
|
|
|
1729
|
+
.\!rounded-lg {
|
|
1730
|
+
border-radius: 0.5rem !important;
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1711
1733
|
.rounded {
|
|
1712
1734
|
border-radius: 0.25rem;
|
|
1713
1735
|
}
|
|
@@ -1762,6 +1784,10 @@ video {
|
|
|
1762
1784
|
border-bottom-right-radius: 0px;
|
|
1763
1785
|
}
|
|
1764
1786
|
|
|
1787
|
+
.\!border {
|
|
1788
|
+
border-width: 1px !important;
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1765
1791
|
.border {
|
|
1766
1792
|
border-width: 1px;
|
|
1767
1793
|
}
|
|
@@ -1826,6 +1852,10 @@ video {
|
|
|
1826
1852
|
border-style: none;
|
|
1827
1853
|
}
|
|
1828
1854
|
|
|
1855
|
+
.\!border-edge {
|
|
1856
|
+
border-color: var(--color-edge) !important;
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1829
1859
|
.border-black\/10 {
|
|
1830
1860
|
border-color: rgb(0 0 0 / 0.1);
|
|
1831
1861
|
}
|
|
@@ -1867,6 +1897,11 @@ video {
|
|
|
1867
1897
|
border-color: rgb(254 202 202 / var(--tw-border-opacity));
|
|
1868
1898
|
}
|
|
1869
1899
|
|
|
1900
|
+
.border-red-300 {
|
|
1901
|
+
--tw-border-opacity: 1;
|
|
1902
|
+
border-color: rgb(252 165 165 / var(--tw-border-opacity));
|
|
1903
|
+
}
|
|
1904
|
+
|
|
1870
1905
|
.border-red-400 {
|
|
1871
1906
|
--tw-border-opacity: 1;
|
|
1872
1907
|
border-color: rgb(248 113 113 / var(--tw-border-opacity));
|
|
@@ -1906,6 +1941,10 @@ video {
|
|
|
1906
1941
|
border-right-color: rgb(17 24 39 / var(--tw-border-opacity));
|
|
1907
1942
|
}
|
|
1908
1943
|
|
|
1944
|
+
.\!bg-surface {
|
|
1945
|
+
background-color: var(--color-surface) !important;
|
|
1946
|
+
}
|
|
1947
|
+
|
|
1909
1948
|
.bg-amber-100 {
|
|
1910
1949
|
--tw-bg-opacity: 1;
|
|
1911
1950
|
background-color: rgb(254 243 199 / var(--tw-bg-opacity));
|
|
@@ -2190,6 +2229,10 @@ video {
|
|
|
2190
2229
|
--tw-gradient-to: #dc2626 var(--tw-gradient-to-position);
|
|
2191
2230
|
}
|
|
2192
2231
|
|
|
2232
|
+
.\!p-0 {
|
|
2233
|
+
padding: 0px !important;
|
|
2234
|
+
}
|
|
2235
|
+
|
|
2193
2236
|
.p-0 {
|
|
2194
2237
|
padding: 0px;
|
|
2195
2238
|
}
|
|
@@ -2381,6 +2424,14 @@ video {
|
|
|
2381
2424
|
padding-left: 2rem;
|
|
2382
2425
|
}
|
|
2383
2426
|
|
|
2427
|
+
.pr-12 {
|
|
2428
|
+
padding-right: 3rem;
|
|
2429
|
+
}
|
|
2430
|
+
|
|
2431
|
+
.pr-2 {
|
|
2432
|
+
padding-right: 0.5rem;
|
|
2433
|
+
}
|
|
2434
|
+
|
|
2384
2435
|
.pr-3 {
|
|
2385
2436
|
padding-right: 0.75rem;
|
|
2386
2437
|
}
|
|
@@ -2446,6 +2497,10 @@ video {
|
|
|
2446
2497
|
font-size: 10px;
|
|
2447
2498
|
}
|
|
2448
2499
|
|
|
2500
|
+
.text-\[11px\] {
|
|
2501
|
+
font-size: 11px;
|
|
2502
|
+
}
|
|
2503
|
+
|
|
2449
2504
|
.text-base {
|
|
2450
2505
|
font-size: 1rem;
|
|
2451
2506
|
line-height: 1.5rem;
|
|
@@ -2791,6 +2846,12 @@ video {
|
|
|
2791
2846
|
opacity: 0.75;
|
|
2792
2847
|
}
|
|
2793
2848
|
|
|
2849
|
+
.\!shadow-xl {
|
|
2850
|
+
--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1) !important;
|
|
2851
|
+
--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color) !important;
|
|
2852
|
+
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow) !important;
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2794
2855
|
.shadow {
|
|
2795
2856
|
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
|
2796
2857
|
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
|
|
@@ -3227,6 +3288,11 @@ video {
|
|
|
3227
3288
|
background-color: rgb(254 226 226 / var(--tw-bg-opacity));
|
|
3228
3289
|
}
|
|
3229
3290
|
|
|
3291
|
+
.hover\:bg-red-50:hover {
|
|
3292
|
+
--tw-bg-opacity: 1;
|
|
3293
|
+
background-color: rgb(254 242 242 / var(--tw-bg-opacity));
|
|
3294
|
+
}
|
|
3295
|
+
|
|
3230
3296
|
.hover\:bg-red-500:hover {
|
|
3231
3297
|
--tw-bg-opacity: 1;
|
|
3232
3298
|
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
|
@@ -3487,6 +3553,11 @@ video {
|
|
|
3487
3553
|
--tw-ring-color: var(--color-primary-subtle);
|
|
3488
3554
|
}
|
|
3489
3555
|
|
|
3556
|
+
.focus\:ring-red-200:focus {
|
|
3557
|
+
--tw-ring-opacity: 1;
|
|
3558
|
+
--tw-ring-color: rgb(254 202 202 / var(--tw-ring-opacity));
|
|
3559
|
+
}
|
|
3560
|
+
|
|
3490
3561
|
.focus\:ring-sky-600:focus {
|
|
3491
3562
|
--tw-ring-opacity: 1;
|
|
3492
3563
|
--tw-ring-color: rgb(2 132 199 / var(--tw-ring-opacity));
|
|
@@ -3822,6 +3893,11 @@ video {
|
|
|
3822
3893
|
}
|
|
3823
3894
|
}
|
|
3824
3895
|
|
|
3896
|
+
:is(:where(.dark) .dark\:\!bg-shark-900) {
|
|
3897
|
+
--tw-bg-opacity: 1 !important;
|
|
3898
|
+
background-color: rgb(21 25 30 / var(--tw-bg-opacity)) !important;
|
|
3899
|
+
}
|
|
3900
|
+
|
|
3825
3901
|
:is(:where(.dark) .dark\:bg-shark-800) {
|
|
3826
3902
|
--tw-bg-opacity: 1;
|
|
3827
3903
|
background-color: rgb(33 37 41 / var(--tw-bg-opacity));
|
|
@@ -3835,6 +3911,11 @@ video {
|
|
|
3835
3911
|
background-color: rgb(33 37 41 / 0.8);
|
|
3836
3912
|
}
|
|
3837
3913
|
|
|
3914
|
+
:is(:where(.dark) .dark\:bg-shark-900) {
|
|
3915
|
+
--tw-bg-opacity: 1;
|
|
3916
|
+
background-color: rgb(21 25 30 / var(--tw-bg-opacity));
|
|
3917
|
+
}
|
|
3918
|
+
|
|
3838
3919
|
:is(:where(.dark) .dark\:text-gray-400) {
|
|
3839
3920
|
--tw-text-opacity: 1;
|
|
3840
3921
|
color: rgb(156 163 175 / var(--tw-text-opacity));
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const RECENT_PAGES_STORAGE_KEY = 'studio:recent-pages-history';
|
|
4
|
+
const RECENT_PAGES_CHANGED_EVENT = 'studio-recent-pages-changed';
|
|
5
|
+
const RECENT_PAGES_LOCK_NAME = `studio-lock:${RECENT_PAGES_STORAGE_KEY}`;
|
|
6
|
+
const MAX_RECENT_PAGES = 50;
|
|
7
|
+
|
|
8
|
+
/** Collapses hash-style prefixes (e.g. `/#/`) to a normal path; keeps query string. */
|
|
9
|
+
function normalizeTrackedPath(fullPath) {
|
|
10
|
+
if (!fullPath || typeof fullPath !== 'string') {
|
|
11
|
+
return '/';
|
|
12
|
+
}
|
|
13
|
+
const qIndex = fullPath.indexOf('?');
|
|
14
|
+
const rawMain = qIndex === -1 ? fullPath : fullPath.slice(0, qIndex);
|
|
15
|
+
const qs = qIndex === -1 ? '' : fullPath.slice(qIndex);
|
|
16
|
+
|
|
17
|
+
let pathOnly = rawMain.trim().replace(/#/g, '');
|
|
18
|
+
pathOnly = pathOnly.replace(/^\/+/u, '/');
|
|
19
|
+
if (pathOnly !== '/' && /\/$/u.test(pathOnly)) {
|
|
20
|
+
pathOnly = pathOnly.replace(/\/+$/u, '');
|
|
21
|
+
}
|
|
22
|
+
if (pathOnly === '' || pathOnly === '/') {
|
|
23
|
+
pathOnly = '/';
|
|
24
|
+
} else if (!pathOnly.startsWith('/')) {
|
|
25
|
+
pathOnly = `/${pathOnly}`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const out = qs ? pathOnly + qs : pathOnly;
|
|
29
|
+
return out;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function safeReadRecentPages() {
|
|
33
|
+
if (typeof window === 'undefined' || !window.localStorage) {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const raw = window.localStorage.getItem(RECENT_PAGES_STORAGE_KEY);
|
|
38
|
+
if (!raw) {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
const parsed = JSON.parse(raw);
|
|
42
|
+
if (!Array.isArray(parsed)) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
return parsed
|
|
46
|
+
.map(entry => {
|
|
47
|
+
if (!entry || typeof entry.path !== 'string') {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
return { ...entry, path: normalizeTrackedPath(entry.path) };
|
|
51
|
+
})
|
|
52
|
+
.filter(
|
|
53
|
+
entry =>
|
|
54
|
+
entry &&
|
|
55
|
+
typeof entry.label === 'string' &&
|
|
56
|
+
typeof entry.visitedAt === 'number' &&
|
|
57
|
+
entry.path !== ''
|
|
58
|
+
)
|
|
59
|
+
.slice(0, MAX_RECENT_PAGES);
|
|
60
|
+
} catch {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function notifyRecentPagesChangedFromThisTab() {
|
|
66
|
+
if (typeof window === 'undefined') {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
window.dispatchEvent(new CustomEvent(RECENT_PAGES_CHANGED_EVENT));
|
|
71
|
+
} catch {
|
|
72
|
+
/* ignore */
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function saveRecentPages(entries) {
|
|
77
|
+
if (typeof window === 'undefined' || !window.localStorage) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
window.localStorage.setItem(
|
|
81
|
+
RECENT_PAGES_STORAGE_KEY,
|
|
82
|
+
JSON.stringify(entries.slice(0, MAX_RECENT_PAGES))
|
|
83
|
+
);
|
|
84
|
+
notifyRecentPagesChangedFromThisTab();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function withRecentPagesStorageLock(syncFn) {
|
|
88
|
+
if (typeof window === 'undefined' || !window.localStorage) {
|
|
89
|
+
syncFn();
|
|
90
|
+
return Promise.resolve();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
const locksApi =
|
|
95
|
+
typeof navigator !== 'undefined' && navigator.locks !== undefined ? navigator.locks : null;
|
|
96
|
+
|
|
97
|
+
if (locksApi !== null && typeof locksApi.request === 'function') {
|
|
98
|
+
return locksApi.request(RECENT_PAGES_LOCK_NAME, syncFn);
|
|
99
|
+
}
|
|
100
|
+
} catch {
|
|
101
|
+
/* fall through */
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
syncFn();
|
|
105
|
+
return Promise.resolve();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
module.exports = {
|
|
109
|
+
RECENT_PAGES_STORAGE_KEY,
|
|
110
|
+
RECENT_PAGES_CHANGED_EVENT,
|
|
111
|
+
MAX_RECENT_PAGES,
|
|
112
|
+
normalizeTrackedPath,
|
|
113
|
+
safeReadRecentPages,
|
|
114
|
+
saveRecentPages,
|
|
115
|
+
withRecentPagesStorageLock
|
|
116
|
+
};
|
package/frontend/src/api.js
CHANGED
|
@@ -9,6 +9,7 @@ const client = axios.create({
|
|
|
9
9
|
console.log('API baseURL:', window.MONGOOSE_STUDIO_CONFIG.baseURL);
|
|
10
10
|
|
|
11
11
|
window.apiClient = client;
|
|
12
|
+
exports.fetch = fetch;
|
|
12
13
|
client.interceptors.request.use(req => {
|
|
13
14
|
const accessToken = window.localStorage.getItem('_mongooseStudioAccessToken') || null;
|
|
14
15
|
if (accessToken) {
|
|
@@ -24,10 +25,92 @@ client.interceptors.response.use(
|
|
|
24
25
|
if (typeof err?.response?.data === 'string') {
|
|
25
26
|
throw new Error(`Error in ${err.config?.method} ${err.config?.url}: ${err.response.data}`);
|
|
26
27
|
}
|
|
28
|
+
if (typeof err?.response?.data?.message === 'string') {
|
|
29
|
+
throw new Error(`Error in ${err.config?.method} ${err.config?.url}: ${err.response.data.message}`);
|
|
30
|
+
}
|
|
27
31
|
throw err;
|
|
28
32
|
}
|
|
29
33
|
);
|
|
30
34
|
|
|
35
|
+
async function* streamSSE(url, options = {}) {
|
|
36
|
+
const fetch = exports.fetch;
|
|
37
|
+
const response = await fetch(url, {
|
|
38
|
+
method: 'GET',
|
|
39
|
+
...options,
|
|
40
|
+
headers: {
|
|
41
|
+
...(options.headers || {}),
|
|
42
|
+
Accept: 'text/event-stream'
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const reader = response.body.getReader();
|
|
51
|
+
const decoder = new TextDecoder('utf-8');
|
|
52
|
+
let buffer = '';
|
|
53
|
+
|
|
54
|
+
while (true) {
|
|
55
|
+
const { done, value } = await reader.read();
|
|
56
|
+
if (done) {
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
buffer += decoder.decode(value, { stream: true });
|
|
60
|
+
|
|
61
|
+
let eventEnd;
|
|
62
|
+
while ((eventEnd = buffer.indexOf('\n\n')) !== -1) {
|
|
63
|
+
const eventStr = buffer.slice(0, eventEnd);
|
|
64
|
+
buffer = buffer.slice(eventEnd + 2);
|
|
65
|
+
|
|
66
|
+
const event = parseSSEEvent(eventStr);
|
|
67
|
+
if (event == null) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (event.type === 'error') {
|
|
71
|
+
const message = getSSEErrorMessage(event.data);
|
|
72
|
+
throw new Error(message);
|
|
73
|
+
}
|
|
74
|
+
yield event.data;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function parseSSEEvent(eventStr) {
|
|
80
|
+
const lines = eventStr.split('\n');
|
|
81
|
+
let type = 'message';
|
|
82
|
+
let data = '';
|
|
83
|
+
for (const line of lines) {
|
|
84
|
+
if (line.startsWith('event:')) {
|
|
85
|
+
type = line.slice(6).trim() || 'message';
|
|
86
|
+
} else if (line.startsWith('data:')) {
|
|
87
|
+
data += line.slice(5).trim();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (!data) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
return { type, data: JSON.parse(data) };
|
|
96
|
+
} catch (err) {
|
|
97
|
+
return { type, data };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function getSSEErrorMessage(data) {
|
|
102
|
+
if (typeof data === 'string') {
|
|
103
|
+
return data || 'Streaming request failed.';
|
|
104
|
+
}
|
|
105
|
+
if (typeof data?.message === 'string' && data.message.length > 0) {
|
|
106
|
+
return data.message;
|
|
107
|
+
}
|
|
108
|
+
if (typeof data?.error === 'string' && data.error.length > 0) {
|
|
109
|
+
return data.error;
|
|
110
|
+
}
|
|
111
|
+
return 'Streaming request failed.';
|
|
112
|
+
}
|
|
113
|
+
|
|
31
114
|
if (window.MONGOOSE_STUDIO_CONFIG.isLambda) {
|
|
32
115
|
exports.getCapabilities = function getCapabilities() {
|
|
33
116
|
return client.post('', { action: 'getCapabilities' }).then(res => res.data);
|
|
@@ -103,6 +186,7 @@ if (window.MONGOOSE_STUDIO_CONFIG.isLambda) {
|
|
|
103
186
|
exportQueryResults(params) {
|
|
104
187
|
const accessToken = window.localStorage.getItem('_mongooseStudioAccessToken') || null;
|
|
105
188
|
|
|
189
|
+
const fetch = exports.fetch;
|
|
106
190
|
return fetch(window.MONGOOSE_STUDIO_CONFIG.baseURL + '?' + new URLSearchParams({ ...params, action: 'Model.exportQueryResults' }).toString(), {
|
|
107
191
|
method: 'GET',
|
|
108
192
|
headers: {
|
|
@@ -166,6 +250,9 @@ if (window.MONGOOSE_STUDIO_CONFIG.isLambda) {
|
|
|
166
250
|
dropIndex: function dropIndex(params) {
|
|
167
251
|
return client.post('', { action: 'Model.dropIndex', ...params }).then(res => res.data);
|
|
168
252
|
},
|
|
253
|
+
dropCollection: function dropCollection(params) {
|
|
254
|
+
return client.post('', { action: 'Model.dropCollection', ...params }).then(res => res.data);
|
|
255
|
+
},
|
|
169
256
|
listModels: function listModels() {
|
|
170
257
|
return client.post('', { action: 'Model.listModels' }).then(res => res.data);
|
|
171
258
|
},
|
|
@@ -254,50 +341,11 @@ if (window.MONGOOSE_STUDIO_CONFIG.isLambda) {
|
|
|
254
341
|
const accessToken = window.localStorage.getItem('_mongooseStudioAccessToken') || null;
|
|
255
342
|
const url = window.MONGOOSE_STUDIO_CONFIG.baseURL + '/ChatThread/streamChatMessage?' + new URLSearchParams(params).toString();
|
|
256
343
|
|
|
257
|
-
|
|
258
|
-
method: 'GET',
|
|
344
|
+
yield* streamSSE(url, {
|
|
259
345
|
headers: {
|
|
260
|
-
Authorization: `${accessToken}
|
|
261
|
-
Accept: 'text/event-stream'
|
|
346
|
+
Authorization: `${accessToken}`
|
|
262
347
|
}
|
|
263
348
|
});
|
|
264
|
-
|
|
265
|
-
if (!response.ok) {
|
|
266
|
-
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
const reader = response.body.getReader();
|
|
270
|
-
const decoder = new TextDecoder('utf-8');
|
|
271
|
-
let buffer = '';
|
|
272
|
-
|
|
273
|
-
while (true) {
|
|
274
|
-
const { done, value } = await reader.read();
|
|
275
|
-
if (done) break;
|
|
276
|
-
buffer += decoder.decode(value, { stream: true });
|
|
277
|
-
|
|
278
|
-
let eventEnd;
|
|
279
|
-
while ((eventEnd = buffer.indexOf('\n\n')) !== -1) {
|
|
280
|
-
const eventStr = buffer.slice(0, eventEnd);
|
|
281
|
-
buffer = buffer.slice(eventEnd + 2);
|
|
282
|
-
|
|
283
|
-
// Parse SSE event
|
|
284
|
-
const lines = eventStr.split('\n');
|
|
285
|
-
let data = '';
|
|
286
|
-
for (const line of lines) {
|
|
287
|
-
if (line.startsWith('data:')) {
|
|
288
|
-
data += line.slice(5).trim();
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
if (data) {
|
|
292
|
-
try {
|
|
293
|
-
const res = JSON.parse(data);
|
|
294
|
-
yield res;
|
|
295
|
-
} catch (err) {
|
|
296
|
-
yield data;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
349
|
}
|
|
302
350
|
};
|
|
303
351
|
exports.ChatMessage = {
|
|
@@ -330,6 +378,7 @@ if (window.MONGOOSE_STUDIO_CONFIG.isLambda) {
|
|
|
330
378
|
exportQueryResults(params) {
|
|
331
379
|
const accessToken = window.localStorage.getItem('_mongooseStudioAccessToken') || null;
|
|
332
380
|
|
|
381
|
+
const fetch = exports.fetch;
|
|
333
382
|
return fetch(window.MONGOOSE_STUDIO_CONFIG.baseURL + '/Model/exportQueryResults?' + new URLSearchParams(params).toString(), {
|
|
334
383
|
method: 'GET',
|
|
335
384
|
headers: {
|
|
@@ -367,50 +416,11 @@ if (window.MONGOOSE_STUDIO_CONFIG.isLambda) {
|
|
|
367
416
|
const accessToken = window.localStorage.getItem('_mongooseStudioAccessToken') || null;
|
|
368
417
|
const url = window.MONGOOSE_STUDIO_CONFIG.baseURL + '/Model/getDocumentsStream?' + new URLSearchParams(params).toString();
|
|
369
418
|
|
|
370
|
-
|
|
371
|
-
method: 'GET',
|
|
419
|
+
yield* streamSSE(url, {
|
|
372
420
|
headers: {
|
|
373
|
-
Authorization: `${accessToken}
|
|
374
|
-
Accept: 'text/event-stream'
|
|
421
|
+
Authorization: `${accessToken}`
|
|
375
422
|
}
|
|
376
423
|
});
|
|
377
|
-
|
|
378
|
-
if (!response.ok) {
|
|
379
|
-
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
const reader = response.body.getReader();
|
|
383
|
-
const decoder = new TextDecoder('utf-8');
|
|
384
|
-
let buffer = '';
|
|
385
|
-
|
|
386
|
-
while (true) {
|
|
387
|
-
const { done, value } = await reader.read();
|
|
388
|
-
if (done) break;
|
|
389
|
-
buffer += decoder.decode(value, { stream: true });
|
|
390
|
-
|
|
391
|
-
let eventEnd;
|
|
392
|
-
while ((eventEnd = buffer.indexOf('\n\n')) !== -1) {
|
|
393
|
-
const eventStr = buffer.slice(0, eventEnd);
|
|
394
|
-
buffer = buffer.slice(eventEnd + 2);
|
|
395
|
-
|
|
396
|
-
// Parse SSE event
|
|
397
|
-
const lines = eventStr.split('\n');
|
|
398
|
-
let data = '';
|
|
399
|
-
for (const line of lines) {
|
|
400
|
-
if (line.startsWith('data:')) {
|
|
401
|
-
data += line.slice(5).trim();
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
if (data) {
|
|
405
|
-
try {
|
|
406
|
-
yield JSON.parse(data);
|
|
407
|
-
} catch (err) {
|
|
408
|
-
// If not JSON, yield as string
|
|
409
|
-
yield data;
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
424
|
},
|
|
415
425
|
getEstimatedDocumentCounts: function getEstimatedDocumentCounts() {
|
|
416
426
|
return client.post('/Model/getEstimatedDocumentCounts', {}).then(res => res.data);
|
|
@@ -419,51 +429,12 @@ if (window.MONGOOSE_STUDIO_CONFIG.isLambda) {
|
|
|
419
429
|
const accessToken = window.localStorage.getItem('_mongooseStudioAccessToken') || null;
|
|
420
430
|
const url = window.MONGOOSE_STUDIO_CONFIG.baseURL + '/Model/streamDocumentChanges?' + new URLSearchParams(params).toString();
|
|
421
431
|
|
|
422
|
-
|
|
423
|
-
method: 'GET',
|
|
432
|
+
yield* streamSSE(url, {
|
|
424
433
|
headers: {
|
|
425
|
-
Authorization: `${accessToken}
|
|
426
|
-
Accept: 'text/event-stream'
|
|
434
|
+
Authorization: `${accessToken}`
|
|
427
435
|
},
|
|
428
436
|
signal: options.signal
|
|
429
437
|
});
|
|
430
|
-
|
|
431
|
-
if (!response.ok) {
|
|
432
|
-
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
const reader = response.body.getReader();
|
|
436
|
-
const decoder = new TextDecoder('utf-8');
|
|
437
|
-
let buffer = '';
|
|
438
|
-
|
|
439
|
-
while (true) {
|
|
440
|
-
const { done, value } = await reader.read();
|
|
441
|
-
if (done) break;
|
|
442
|
-
buffer += decoder.decode(value, { stream: true });
|
|
443
|
-
|
|
444
|
-
let eventEnd;
|
|
445
|
-
while ((eventEnd = buffer.indexOf('\n\n')) !== -1) {
|
|
446
|
-
const eventStr = buffer.slice(0, eventEnd);
|
|
447
|
-
buffer = buffer.slice(eventEnd + 2);
|
|
448
|
-
|
|
449
|
-
// Parse SSE event
|
|
450
|
-
const lines = eventStr.split('\n');
|
|
451
|
-
let data = '';
|
|
452
|
-
for (const line of lines) {
|
|
453
|
-
if (line.startsWith('data:')) {
|
|
454
|
-
data += line.slice(5).trim();
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
if (data) {
|
|
458
|
-
try {
|
|
459
|
-
yield JSON.parse(data);
|
|
460
|
-
} catch (err) {
|
|
461
|
-
// If not JSON, yield as string
|
|
462
|
-
yield data;
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
438
|
},
|
|
468
439
|
getCollectionInfo: function getCollectionInfo(params) {
|
|
469
440
|
return client.post('/Model/getCollectionInfo', params).then(res => res.data);
|
|
@@ -484,50 +455,11 @@ if (window.MONGOOSE_STUDIO_CONFIG.isLambda) {
|
|
|
484
455
|
const accessToken = window.localStorage.getItem('_mongooseStudioAccessToken') || null;
|
|
485
456
|
const url = window.MONGOOSE_STUDIO_CONFIG.baseURL + '/Model/streamChatMessage?' + new URLSearchParams(params).toString();
|
|
486
457
|
|
|
487
|
-
|
|
488
|
-
method: 'GET',
|
|
458
|
+
yield* streamSSE(url, {
|
|
489
459
|
headers: {
|
|
490
|
-
Authorization: `${accessToken}
|
|
491
|
-
Accept: 'text/event-stream'
|
|
460
|
+
Authorization: `${accessToken}`
|
|
492
461
|
}
|
|
493
462
|
});
|
|
494
|
-
|
|
495
|
-
if (!response.ok) {
|
|
496
|
-
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
const reader = response.body.getReader();
|
|
500
|
-
const decoder = new TextDecoder('utf-8');
|
|
501
|
-
let buffer = '';
|
|
502
|
-
|
|
503
|
-
while (true) {
|
|
504
|
-
const { done, value } = await reader.read();
|
|
505
|
-
if (done) break;
|
|
506
|
-
buffer += decoder.decode(value, { stream: true });
|
|
507
|
-
|
|
508
|
-
let eventEnd;
|
|
509
|
-
while ((eventEnd = buffer.indexOf('\n\n')) !== -1) {
|
|
510
|
-
const eventStr = buffer.slice(0, eventEnd);
|
|
511
|
-
buffer = buffer.slice(eventEnd + 2);
|
|
512
|
-
|
|
513
|
-
// Parse SSE event
|
|
514
|
-
const lines = eventStr.split('\n');
|
|
515
|
-
let data = '';
|
|
516
|
-
for (const line of lines) {
|
|
517
|
-
if (line.startsWith('data:')) {
|
|
518
|
-
data += line.slice(5).trim();
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
if (data) {
|
|
522
|
-
try {
|
|
523
|
-
yield JSON.parse(data);
|
|
524
|
-
} catch (err) {
|
|
525
|
-
// If not JSON, yield as string
|
|
526
|
-
yield data;
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
463
|
},
|
|
532
464
|
updateDocuments: function updateDocument(params) {
|
|
533
465
|
return client.post('/Model/updateDocuments', params).then(res => res.data);
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 1v4m0 0h-4m4 0l-5-5" />
|
|
50
50
|
</svg>
|
|
51
51
|
</button>
|
|
52
|
-
<div
|
|
52
|
+
<div class="relative mr-1" ref="runDropdown">
|
|
53
53
|
<div class="flex items-center">
|
|
54
54
|
<button
|
|
55
55
|
class="px-2 py-1 text-xs bg-primary hover:bg-primary-hover text-primary-text border-none rounded-l-md cursor-pointer transition-colors disabled:bg-gray-400 disabled:cursor-not-allowed"
|
|
@@ -146,11 +146,6 @@
|
|
|
146
146
|
@click.stop="cancelEditing">
|
|
147
147
|
Cancel
|
|
148
148
|
</button>
|
|
149
|
-
<async-button
|
|
150
|
-
class="px-2 py-1 text-xs bg-blue-600 text-white border-none rounded cursor-pointer hover:bg-blue-700 transition-colors disabled:bg-gray-400"
|
|
151
|
-
@click="executeScript(false)">
|
|
152
|
-
Execute
|
|
153
|
-
</async-button>
|
|
154
149
|
</div>
|
|
155
150
|
</div>
|
|
156
151
|
<pre v-else class="whitespace-pre-wrap !my-0 bg-muted"><code v-text="script" ref="code" :class="'language-' + language"></code></pre>
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
</button>
|
|
13
13
|
<!-- Sidebar: Chat Threads -->
|
|
14
14
|
<aside
|
|
15
|
-
class="bg-page border-r overflow-hidden
|
|
15
|
+
class="bg-page border-r overflow-hidden transition-all duration-300 ease-in-out z-20 w-64 fixed top-[55px] bottom-0 lg:top-auto lg:bottom-auto lg:relative lg:h-full shrink-0 flex flex-col"
|
|
16
16
|
:class="hideSidebar === false ? 'translate-x-0' : hideSidebar === true ? '-translate-x-full lg:translate-x-0 lg:!w-0 lg:!border-r-0' : '-translate-x-full lg:translate-x-0'"
|
|
17
17
|
style="z-index: 1000">
|
|
18
18
|
<!-- Search + New Thread -->
|
|
@@ -26,9 +26,29 @@ module.exports = app => app.component('confirm-changes', {
|
|
|
26
26
|
},
|
|
27
27
|
startSave() {
|
|
28
28
|
this.$emit('save');
|
|
29
|
+
},
|
|
30
|
+
onEnter(event) {
|
|
31
|
+
if (event.key !== 'Enter') {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const modalMasks = Array.from(document.querySelectorAll('.modal-mask'));
|
|
36
|
+
const currentMask = this.$el?.closest('.modal-mask');
|
|
37
|
+
const isTopMostModal = modalMasks.length > 0 && modalMasks[modalMasks.length - 1] === currentMask;
|
|
38
|
+
|
|
39
|
+
if (!isTopMostModal) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
event.preventDefault();
|
|
44
|
+
this.startSave();
|
|
29
45
|
}
|
|
30
46
|
},
|
|
31
47
|
mounted() {
|
|
48
|
+
window.addEventListener('keydown', this.onEnter);
|
|
32
49
|
Prism.highlightElement(this.$refs.code);
|
|
50
|
+
},
|
|
51
|
+
beforeUnmount() {
|
|
52
|
+
window.removeEventListener('keydown', this.onEnter);
|
|
33
53
|
}
|
|
34
54
|
});
|