sql-preview 0.6.1 → 0.6.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/Changelog.md +28 -0
- package/dist/mcp-app.html +285 -100
- package/out/server/standalone.js +606 -181
- package/package.json +1 -1
- package/server.json +2 -2
package/Changelog.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.6.3] - 2026-06-03
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added an MCP-accessible credential request flow that returns a short-lived local browser form so agents can ask users to store connection passwords without putting secrets in chat transcripts.
|
|
10
|
+
- Added local interactive Snowflake Browser SSO support for MCP/daemon connection tests, including analyst-style `user` and `authenticator=externalbrowser` aliases.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Fixed unconfigured VS Code workspaces showing a phantom built-in `Workspace Trino` connection beside saved Snowflake profiles.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Simplified the Snowflake connection form by moving token caching and warehouse/database/schema/role defaults into optional settings, with SSO token caching enabled by default.
|
|
19
|
+
|
|
20
|
+
## [0.6.2] - 2026-06-03
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- Added a product strategy note on using SQL Preview's query wedge to accelerate toward a broader agentic query layer.
|
|
25
|
+
- Added the initial RFC-054 Zed MCP extension scaffold, local verification script, and setup guide.
|
|
26
|
+
- Added Zed marketplace readiness checks, CI, and publishing instructions for submitting the SQL Preview MCP extension to `zed-industries/extensions`.
|
|
27
|
+
- Added Snowflake Browser SSO profile support for VS Code by passing `EXTERNALBROWSER` auth options to the Snowflake driver without storing a Snowflake password.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- Added Snowflake SDK optional-dependency handling so packaged VS Code installs surface guided installation advice instead of an unexplained missing-module failure.
|
|
32
|
+
|
|
5
33
|
## [0.6.1] - 2026-05-29
|
|
6
34
|
|
|
7
35
|
### Fixed
|
package/dist/mcp-app.html
CHANGED
|
@@ -74174,6 +74174,7 @@ const DynamicForm = ({
|
|
|
74174
74174
|
submitFeedback
|
|
74175
74175
|
}) => {
|
|
74176
74176
|
const [formData, setFormData] = reactExports.useState({});
|
|
74177
|
+
const [isAdvancedOpen, setIsAdvancedOpen] = reactExports.useState(false);
|
|
74177
74178
|
const lastResetKey = reactExports.useRef(void 0);
|
|
74178
74179
|
const resetKey = reactExports.useMemo(
|
|
74179
74180
|
() => JSON.stringify({
|
|
@@ -74186,6 +74187,29 @@ const DynamicForm = ({
|
|
|
74186
74187
|
}),
|
|
74187
74188
|
[initialData, schema.properties]
|
|
74188
74189
|
);
|
|
74190
|
+
const isFieldVisible = (prop, data) => {
|
|
74191
|
+
var _a3;
|
|
74192
|
+
const visibleWhen = (_a3 = prop.ui) == null ? void 0 : _a3.visibleWhen;
|
|
74193
|
+
if (!visibleWhen) {
|
|
74194
|
+
return true;
|
|
74195
|
+
}
|
|
74196
|
+
const actual = data[visibleWhen.field];
|
|
74197
|
+
if ("equals" in visibleWhen) {
|
|
74198
|
+
return actual === visibleWhen.equals;
|
|
74199
|
+
}
|
|
74200
|
+
if ("notEquals" in visibleWhen) {
|
|
74201
|
+
return actual !== visibleWhen.notEquals;
|
|
74202
|
+
}
|
|
74203
|
+
if (Array.isArray(visibleWhen.in)) {
|
|
74204
|
+
return visibleWhen.in.includes(actual);
|
|
74205
|
+
}
|
|
74206
|
+
return true;
|
|
74207
|
+
};
|
|
74208
|
+
const visiblePropertyEntries = () => Object.entries(schema.properties || {}).filter(([, prop]) => isFieldVisible(prop, formData));
|
|
74209
|
+
const visibleFormData = () => {
|
|
74210
|
+
const visibleKeys = /* @__PURE__ */ new Set(["name", ...visiblePropertyEntries().map(([key]) => key)]);
|
|
74211
|
+
return Object.fromEntries(Object.entries(formData).filter(([key]) => visibleKeys.has(key)));
|
|
74212
|
+
};
|
|
74189
74213
|
reactExports.useEffect(() => {
|
|
74190
74214
|
if (lastResetKey.current === resetKey) {
|
|
74191
74215
|
return;
|
|
@@ -74209,17 +74233,111 @@ const DynamicForm = ({
|
|
|
74209
74233
|
};
|
|
74210
74234
|
const handleSubmit = (e2) => {
|
|
74211
74235
|
e2.preventDefault();
|
|
74212
|
-
onSubmit(
|
|
74236
|
+
onSubmit(visibleFormData());
|
|
74213
74237
|
};
|
|
74214
74238
|
const handleTest = () => {
|
|
74215
74239
|
if (onTest) {
|
|
74216
|
-
onTest(
|
|
74240
|
+
onTest(visibleFormData());
|
|
74217
74241
|
}
|
|
74218
74242
|
};
|
|
74243
|
+
const hasMeaningfulInitialValue = (key) => {
|
|
74244
|
+
const value = initialData[key];
|
|
74245
|
+
return value !== void 0 && value !== null && value !== "" && value !== false;
|
|
74246
|
+
};
|
|
74247
|
+
const advancedInitiallyOpen = Object.entries(schema.properties || {}).some(
|
|
74248
|
+
([key, prop]) => {
|
|
74249
|
+
var _a3;
|
|
74250
|
+
return ((_a3 = prop.ui) == null ? void 0 : _a3.advanced) && hasMeaningfulInitialValue(key);
|
|
74251
|
+
}
|
|
74252
|
+
);
|
|
74253
|
+
reactExports.useEffect(() => {
|
|
74254
|
+
setIsAdvancedOpen(advancedInitiallyOpen);
|
|
74255
|
+
}, [advancedInitiallyOpen, resetKey]);
|
|
74219
74256
|
const fieldClass = (key, baseClass) => {
|
|
74257
|
+
var _a3, _b2;
|
|
74220
74258
|
const normalizedKey = key.replace(/[^a-z0-9_-]/gi, "-").toLowerCase();
|
|
74221
|
-
|
|
74259
|
+
const fullWidth = ((_b2 = (_a3 = schema.properties[key]) == null ? void 0 : _a3.ui) == null ? void 0 : _b2.fullWidth) ? " sp-conn-form-field-full" : "";
|
|
74260
|
+
return `${baseClass} sp-conn-form-field sp-conn-form-field-${normalizedKey}${fullWidth}`;
|
|
74261
|
+
};
|
|
74262
|
+
const renderPropertyField = ([key, prop]) => {
|
|
74263
|
+
var _a3;
|
|
74264
|
+
const isRequired = (_a3 = schema.required) == null ? void 0 : _a3.includes(key);
|
|
74265
|
+
const value = formData[key];
|
|
74266
|
+
const fieldId = `form-${key}`;
|
|
74267
|
+
const field = (() => {
|
|
74268
|
+
var _a4;
|
|
74269
|
+
if (prop.type === "boolean") {
|
|
74270
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: fieldClass(key, "sp-conn-form-check-row"), children: [
|
|
74271
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
74272
|
+
"input",
|
|
74273
|
+
{
|
|
74274
|
+
type: "checkbox",
|
|
74275
|
+
id: fieldId,
|
|
74276
|
+
checked: !!value,
|
|
74277
|
+
onChange: (e2) => handleChange(key, e2.target.checked)
|
|
74278
|
+
}
|
|
74279
|
+
),
|
|
74280
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: fieldId, className: "sp-conn-form-label", style: { marginBottom: 0 }, children: prop.title || key }),
|
|
74281
|
+
prop.description && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-form-hint", children: prop.description })
|
|
74282
|
+
] });
|
|
74283
|
+
}
|
|
74284
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: fieldClass(key, "sp-conn-form-group"), children: [
|
|
74285
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { htmlFor: fieldId, className: "sp-conn-form-label", children: [
|
|
74286
|
+
prop.title || key,
|
|
74287
|
+
isRequired && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "required", children: "*" })
|
|
74288
|
+
] }),
|
|
74289
|
+
prop.description && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-form-hint", children: prop.description }),
|
|
74290
|
+
Array.isArray(prop.enum) ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
74291
|
+
"select",
|
|
74292
|
+
{
|
|
74293
|
+
id: fieldId,
|
|
74294
|
+
required: isRequired,
|
|
74295
|
+
className: "sp-conn-form-input",
|
|
74296
|
+
value: value || "",
|
|
74297
|
+
onChange: (e2) => handleChange(key, e2.target.value),
|
|
74298
|
+
children: prop.enum.map((option, index2) => {
|
|
74299
|
+
var _a5;
|
|
74300
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: option, children: ((_a5 = prop.enumNames) == null ? void 0 : _a5[index2]) ?? option }, option);
|
|
74301
|
+
})
|
|
74302
|
+
}
|
|
74303
|
+
) : prop.type === "number" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
74304
|
+
"input",
|
|
74305
|
+
{
|
|
74306
|
+
id: fieldId,
|
|
74307
|
+
type: "number",
|
|
74308
|
+
required: isRequired,
|
|
74309
|
+
className: "sp-conn-form-input",
|
|
74310
|
+
value: value !== void 0 ? String(value) : "",
|
|
74311
|
+
onChange: (e2) => handleChange(key, e2.target.value !== "" ? Number(e2.target.value) : void 0)
|
|
74312
|
+
}
|
|
74313
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
74314
|
+
"input",
|
|
74315
|
+
{
|
|
74316
|
+
id: fieldId,
|
|
74317
|
+
type: ((_a4 = prop.ui) == null ? void 0 : _a4.widget) === "password" ? "password" : "text",
|
|
74318
|
+
required: isRequired,
|
|
74319
|
+
className: "sp-conn-form-input",
|
|
74320
|
+
value: value || "",
|
|
74321
|
+
onChange: (e2) => handleChange(key, e2.target.value)
|
|
74322
|
+
}
|
|
74323
|
+
)
|
|
74324
|
+
] });
|
|
74325
|
+
})();
|
|
74326
|
+
const afterField = renderAfterField == null ? void 0 : renderAfterField(key);
|
|
74327
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(React$2.Fragment, { children: [
|
|
74328
|
+
field,
|
|
74329
|
+
afterField
|
|
74330
|
+
] }, key);
|
|
74222
74331
|
};
|
|
74332
|
+
const visibleEntries = visiblePropertyEntries();
|
|
74333
|
+
const primaryEntries = visibleEntries.filter(([, prop]) => {
|
|
74334
|
+
var _a3;
|
|
74335
|
+
return !((_a3 = prop.ui) == null ? void 0 : _a3.advanced);
|
|
74336
|
+
});
|
|
74337
|
+
const advancedEntries = visibleEntries.filter(([, prop]) => {
|
|
74338
|
+
var _a3;
|
|
74339
|
+
return (_a3 = prop.ui) == null ? void 0 : _a3.advanced;
|
|
74340
|
+
});
|
|
74223
74341
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("form", { onSubmit: handleSubmit, className: "sp-conn-form", role: "form", children: [
|
|
74224
74342
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-conn-form-fields", children: [
|
|
74225
74343
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: fieldClass("name", "sp-conn-form-group"), children: [
|
|
@@ -74239,68 +74357,20 @@ const DynamicForm = ({
|
|
|
74239
74357
|
}
|
|
74240
74358
|
)
|
|
74241
74359
|
] }),
|
|
74242
|
-
|
|
74243
|
-
|
|
74244
|
-
|
|
74245
|
-
|
|
74246
|
-
|
|
74247
|
-
|
|
74248
|
-
|
|
74249
|
-
|
|
74250
|
-
|
|
74251
|
-
|
|
74252
|
-
|
|
74253
|
-
|
|
74254
|
-
|
|
74255
|
-
|
|
74256
|
-
onChange: (e2) => handleChange(key, e2.target.checked)
|
|
74257
|
-
}
|
|
74258
|
-
),
|
|
74259
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
74260
|
-
"label",
|
|
74261
|
-
{
|
|
74262
|
-
htmlFor: `form-${key}`,
|
|
74263
|
-
className: "sp-conn-form-label",
|
|
74264
|
-
style: { marginBottom: 0 },
|
|
74265
|
-
children: prop.title || key
|
|
74266
|
-
}
|
|
74267
|
-
),
|
|
74268
|
-
prop.description && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-form-hint", children: prop.description })
|
|
74269
|
-
] });
|
|
74270
|
-
}
|
|
74271
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: fieldClass(key, "sp-conn-form-group"), children: [
|
|
74272
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "sp-conn-form-label", children: [
|
|
74273
|
-
prop.title || key,
|
|
74274
|
-
isRequired && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "required", children: "*" })
|
|
74275
|
-
] }),
|
|
74276
|
-
prop.description && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-form-hint", children: prop.description }),
|
|
74277
|
-
prop.type === "number" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
74278
|
-
"input",
|
|
74279
|
-
{
|
|
74280
|
-
type: "number",
|
|
74281
|
-
required: isRequired,
|
|
74282
|
-
className: "sp-conn-form-input",
|
|
74283
|
-
value: value !== void 0 ? String(value) : "",
|
|
74284
|
-
onChange: (e2) => handleChange(key, e2.target.value !== "" ? Number(e2.target.value) : void 0)
|
|
74285
|
-
}
|
|
74286
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
74287
|
-
"input",
|
|
74288
|
-
{
|
|
74289
|
-
type: ((_a4 = prop.ui) == null ? void 0 : _a4.widget) === "password" ? "password" : "text",
|
|
74290
|
-
required: isRequired,
|
|
74291
|
-
className: "sp-conn-form-input",
|
|
74292
|
-
value: value || "",
|
|
74293
|
-
onChange: (e2) => handleChange(key, e2.target.value)
|
|
74294
|
-
}
|
|
74295
|
-
)
|
|
74296
|
-
] });
|
|
74297
|
-
})();
|
|
74298
|
-
const afterField = renderAfterField == null ? void 0 : renderAfterField(key);
|
|
74299
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs(React$2.Fragment, { children: [
|
|
74300
|
-
field,
|
|
74301
|
-
afterField
|
|
74302
|
-
] }, key);
|
|
74303
|
-
})
|
|
74360
|
+
primaryEntries.map(renderPropertyField),
|
|
74361
|
+
advancedEntries.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
74362
|
+
"details",
|
|
74363
|
+
{
|
|
74364
|
+
className: "sp-conn-form-advanced",
|
|
74365
|
+
open: isAdvancedOpen,
|
|
74366
|
+
onToggle: (event) => setIsAdvancedOpen(event.currentTarget.open),
|
|
74367
|
+
children: [
|
|
74368
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("summary", { className: "sp-conn-form-advanced-summary", children: "Optional settings" }),
|
|
74369
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-form-advanced-fields", children: advancedEntries.map(renderPropertyField) })
|
|
74370
|
+
]
|
|
74371
|
+
},
|
|
74372
|
+
`advanced-${resetKey}`
|
|
74373
|
+
)
|
|
74304
74374
|
] }),
|
|
74305
74375
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-conn-form-actions", children: [
|
|
74306
74376
|
actionStatus && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-form-action-status", children: actionStatus }),
|
|
@@ -74340,12 +74410,20 @@ const DynamicForm = ({
|
|
|
74340
74410
|
] })
|
|
74341
74411
|
] });
|
|
74342
74412
|
};
|
|
74343
|
-
const
|
|
74344
|
-
|
|
74345
|
-
|
|
74346
|
-
|
|
74347
|
-
|
|
74348
|
-
|
|
74413
|
+
const OPTIONAL_DEPENDENCY_ADVICE = [
|
|
74414
|
+
{
|
|
74415
|
+
dependency: "@duckdb/node-api",
|
|
74416
|
+
installCommand: "npm install @duckdb/node-api",
|
|
74417
|
+
title: "DUCKDB support is required",
|
|
74418
|
+
guidance: "Local file queries require optional DuckDB support, but the DuckDB native module is not available in this extension runtime."
|
|
74419
|
+
},
|
|
74420
|
+
{
|
|
74421
|
+
dependency: "snowflake-sdk",
|
|
74422
|
+
installCommand: "npm install snowflake-sdk",
|
|
74423
|
+
title: "Snowflake support is required",
|
|
74424
|
+
guidance: "Snowflake connections require optional Snowflake SDK support, but the SDK is not available in this extension runtime."
|
|
74425
|
+
}
|
|
74426
|
+
];
|
|
74349
74427
|
const CONNECTOR_ICONS = {
|
|
74350
74428
|
duckdb: "🦆",
|
|
74351
74429
|
trino: "⚡",
|
|
@@ -74358,10 +74436,18 @@ const CONNECTOR_ICONS = {
|
|
|
74358
74436
|
};
|
|
74359
74437
|
function getOptionalDependencyAdvice(message) {
|
|
74360
74438
|
const lowerMessage = message.toLowerCase();
|
|
74361
|
-
|
|
74362
|
-
|
|
74363
|
-
|
|
74364
|
-
|
|
74439
|
+
return OPTIONAL_DEPENDENCY_ADVICE.find((advice) => {
|
|
74440
|
+
if (message.includes(advice.dependency)) {
|
|
74441
|
+
return true;
|
|
74442
|
+
}
|
|
74443
|
+
if (advice.dependency === "@duckdb/node-api") {
|
|
74444
|
+
return lowerMessage.includes("duckdb native module");
|
|
74445
|
+
}
|
|
74446
|
+
if (advice.dependency === "snowflake-sdk") {
|
|
74447
|
+
return lowerMessage.includes("snowflake sdk") || lowerMessage.includes("sdk is not available");
|
|
74448
|
+
}
|
|
74449
|
+
return false;
|
|
74450
|
+
}) ?? null;
|
|
74365
74451
|
}
|
|
74366
74452
|
function getOptionalDependencyDetails(message) {
|
|
74367
74453
|
return message.replace(/^Connection Test Failed:\s*/i, "").replace(/^Error:\s*/i, "").trim();
|
|
@@ -74383,6 +74469,16 @@ function isErrorToolResult(result, text) {
|
|
|
74383
74469
|
}
|
|
74384
74470
|
return result.isError === true || text.toLowerCase().includes("failed") || text.toLowerCase().includes("error");
|
|
74385
74471
|
}
|
|
74472
|
+
function buildConnectionTestToast(structuredContent, text) {
|
|
74473
|
+
const advice = (structuredContent == null ? void 0 : structuredContent.optionalDependencyAdvice) ?? getOptionalDependencyAdvice(text);
|
|
74474
|
+
const lowerText = text.toLowerCase();
|
|
74475
|
+
const isError = structuredContent ? !structuredContent.success : lowerText.includes("error") || lowerText.includes("failed");
|
|
74476
|
+
return {
|
|
74477
|
+
text: advice ? advice.guidance : text,
|
|
74478
|
+
severity: advice ? "warning" : isError ? "error" : "success",
|
|
74479
|
+
...advice ? { advice } : {}
|
|
74480
|
+
};
|
|
74481
|
+
}
|
|
74386
74482
|
function getFormInitialData(connection) {
|
|
74387
74483
|
if (!connection) {
|
|
74388
74484
|
return {};
|
|
@@ -74409,6 +74505,32 @@ function schemaWithoutPasswordField(schema) {
|
|
|
74409
74505
|
...required2 ? { required: required2 } : {}
|
|
74410
74506
|
};
|
|
74411
74507
|
}
|
|
74508
|
+
function schemaForConnectionMode(schema, connectorId, mode) {
|
|
74509
|
+
if (connectorId !== "snowflake" || mode !== "headless") {
|
|
74510
|
+
return schema;
|
|
74511
|
+
}
|
|
74512
|
+
const authModeProperty = schema.properties["authMode"];
|
|
74513
|
+
if (!Array.isArray(authModeProperty == null ? void 0 : authModeProperty.enum)) {
|
|
74514
|
+
return schema;
|
|
74515
|
+
}
|
|
74516
|
+
const allowedIndexes = authModeProperty.enum.map((option, index2) => ({ option, index: index2 })).filter(({ option }) => option !== "externalbrowser");
|
|
74517
|
+
const enumNames = Array.isArray(authModeProperty.enumNames) ? allowedIndexes.map(({ option, index: index2 }) => {
|
|
74518
|
+
var _a3;
|
|
74519
|
+
return ((_a3 = authModeProperty.enumNames) == null ? void 0 : _a3[index2]) ?? option;
|
|
74520
|
+
}) : void 0;
|
|
74521
|
+
return {
|
|
74522
|
+
...schema,
|
|
74523
|
+
properties: {
|
|
74524
|
+
...schema.properties,
|
|
74525
|
+
authMode: {
|
|
74526
|
+
...authModeProperty,
|
|
74527
|
+
enum: allowedIndexes.map(({ option }) => option),
|
|
74528
|
+
...enumNames ? { enumNames } : {},
|
|
74529
|
+
default: authModeProperty.default === "externalbrowser" ? "password" : authModeProperty.default
|
|
74530
|
+
}
|
|
74531
|
+
}
|
|
74532
|
+
};
|
|
74533
|
+
}
|
|
74412
74534
|
const ConnectionsManager = () => {
|
|
74413
74535
|
const { callServerTool, isReady, mode, sendMessage } = useHostContext();
|
|
74414
74536
|
const supportsActiveConnection = mode === "vscode";
|
|
@@ -74421,6 +74543,7 @@ const ConnectionsManager = () => {
|
|
|
74421
74543
|
const [statuses, setStatuses] = reactExports.useState({});
|
|
74422
74544
|
const [statusMessages, setStatusMessages] = reactExports.useState({});
|
|
74423
74545
|
const [toast, setToast] = reactExports.useState(null);
|
|
74546
|
+
const toastRef = reactExports.useRef(null);
|
|
74424
74547
|
const [isFormOpen, setIsFormOpen] = reactExports.useState(false);
|
|
74425
74548
|
const [selectedType, setSelectedType] = reactExports.useState("");
|
|
74426
74549
|
const fetchData = reactExports.useCallback(async () => {
|
|
@@ -74485,6 +74608,16 @@ const ConnectionsManager = () => {
|
|
|
74485
74608
|
});
|
|
74486
74609
|
}
|
|
74487
74610
|
}, [connections]);
|
|
74611
|
+
reactExports.useEffect(() => {
|
|
74612
|
+
if (!toast || toast.severity !== "warning") {
|
|
74613
|
+
return;
|
|
74614
|
+
}
|
|
74615
|
+
window.requestAnimationFrame(() => {
|
|
74616
|
+
var _a3, _b2;
|
|
74617
|
+
(_a3 = toastRef.current) == null ? void 0 : _a3.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
74618
|
+
(_b2 = toastRef.current) == null ? void 0 : _b2.focus({ preventScroll: true });
|
|
74619
|
+
});
|
|
74620
|
+
}, [toast]);
|
|
74488
74621
|
const handleTestConnection = async (connectionId) => {
|
|
74489
74622
|
var _a3;
|
|
74490
74623
|
if (!isReady) {
|
|
@@ -74511,7 +74644,7 @@ const ConnectionsManager = () => {
|
|
|
74511
74644
|
}
|
|
74512
74645
|
};
|
|
74513
74646
|
const handleTestFormData = async (formData, connection) => {
|
|
74514
|
-
var _a3
|
|
74647
|
+
var _a3;
|
|
74515
74648
|
const typeToTest = (connection == null ? void 0 : connection.type) ?? selectedType;
|
|
74516
74649
|
if (!isReady || !typeToTest) {
|
|
74517
74650
|
return;
|
|
@@ -74535,15 +74668,11 @@ const ConnectionsManager = () => {
|
|
|
74535
74668
|
});
|
|
74536
74669
|
const text = getToolText(result, ((_a3 = result.structuredContent) == null ? void 0 : _a3.message) ?? "No response");
|
|
74537
74670
|
const isError = isErrorToolResult(result, text);
|
|
74538
|
-
const advice = ((_b2 = result.structuredContent) == null ? void 0 : _b2.optionalDependencyAdvice) ?? getOptionalDependencyAdvice(text);
|
|
74539
74671
|
if (connection) {
|
|
74540
74672
|
setStatuses((prev) => ({ ...prev, [connection.id]: isError ? "error" : "ok" }));
|
|
74541
74673
|
setStatusMessages((prev) => ({ ...prev, [connection.id]: text }));
|
|
74542
74674
|
} else {
|
|
74543
|
-
setToast(
|
|
74544
|
-
text: advice ? advice.guidance : text,
|
|
74545
|
-
severity: advice ? "warning" : isError ? "error" : "success"
|
|
74546
|
-
});
|
|
74675
|
+
setToast(buildConnectionTestToast(result.structuredContent, text));
|
|
74547
74676
|
}
|
|
74548
74677
|
} catch (e2) {
|
|
74549
74678
|
const message = `Error: ${e2}`;
|
|
@@ -74554,7 +74683,8 @@ const ConnectionsManager = () => {
|
|
|
74554
74683
|
} else {
|
|
74555
74684
|
setToast({
|
|
74556
74685
|
text: advice ? advice.guidance : message,
|
|
74557
|
-
severity: advice ? "warning" : "error"
|
|
74686
|
+
severity: advice ? "warning" : "error",
|
|
74687
|
+
...advice ? { advice } : {}
|
|
74558
74688
|
});
|
|
74559
74689
|
}
|
|
74560
74690
|
}
|
|
@@ -74686,6 +74816,7 @@ const ConnectionsManager = () => {
|
|
|
74686
74816
|
};
|
|
74687
74817
|
const activeSchemaDef = connectors.find((c) => c.id === selectedType);
|
|
74688
74818
|
const selectedConnection = selectedConnectionId ? connections.find((c) => c.id === selectedConnectionId) : void 0;
|
|
74819
|
+
const activeFormSchema = (activeSchemaDef == null ? void 0 : activeSchemaDef.schema) ? schemaForConnectionMode(activeSchemaDef.schema, activeSchemaDef.id, mode) : void 0;
|
|
74689
74820
|
const selectedFormInitialData = reactExports.useMemo(
|
|
74690
74821
|
() => getFormInitialData(selectedConnection),
|
|
74691
74822
|
[selectedConnection]
|
|
@@ -74693,18 +74824,40 @@ const ConnectionsManager = () => {
|
|
|
74693
74824
|
const emptyFormInitialData = reactExports.useMemo(() => ({}), []);
|
|
74694
74825
|
const renderToast = () => {
|
|
74695
74826
|
if (!toast) return null;
|
|
74696
|
-
|
|
74697
|
-
|
|
74698
|
-
|
|
74699
|
-
|
|
74700
|
-
|
|
74701
|
-
|
|
74702
|
-
|
|
74703
|
-
|
|
74704
|
-
|
|
74705
|
-
|
|
74706
|
-
|
|
74707
|
-
|
|
74827
|
+
const advice = toast.advice;
|
|
74828
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
74829
|
+
"div",
|
|
74830
|
+
{
|
|
74831
|
+
ref: toastRef,
|
|
74832
|
+
className: `sp-conn-toast sp-conn-toast-${toast.severity}`,
|
|
74833
|
+
role: toast.severity === "warning" || toast.severity === "error" ? "alert" : "status",
|
|
74834
|
+
tabIndex: -1,
|
|
74835
|
+
children: [
|
|
74836
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-toast-text", children: toast.text }),
|
|
74837
|
+
advice && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
74838
|
+
"button",
|
|
74839
|
+
{
|
|
74840
|
+
type: "button",
|
|
74841
|
+
className: "sp-btn sp-btn-primary sp-conn-toast-action",
|
|
74842
|
+
onClick: () => handleInstallOptionalDependency(advice),
|
|
74843
|
+
children: [
|
|
74844
|
+
"Install ",
|
|
74845
|
+
advice.dependency
|
|
74846
|
+
]
|
|
74847
|
+
}
|
|
74848
|
+
),
|
|
74849
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
74850
|
+
"button",
|
|
74851
|
+
{
|
|
74852
|
+
className: "sp-conn-toast-close",
|
|
74853
|
+
onClick: () => setToast(null),
|
|
74854
|
+
"aria-label": "Close message",
|
|
74855
|
+
children: "✕"
|
|
74856
|
+
}
|
|
74857
|
+
)
|
|
74858
|
+
]
|
|
74859
|
+
}
|
|
74860
|
+
);
|
|
74708
74861
|
};
|
|
74709
74862
|
const renderConnectionStatusMessage = (connection) => {
|
|
74710
74863
|
const status = statuses[connection.id] || "unknown";
|
|
@@ -74772,10 +74925,10 @@ const ConnectionsManager = () => {
|
|
|
74772
74925
|
},
|
|
74773
74926
|
c.id
|
|
74774
74927
|
)) }),
|
|
74775
|
-
activeSchemaDef &&
|
|
74928
|
+
activeSchemaDef && activeFormSchema ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
74776
74929
|
DynamicForm,
|
|
74777
74930
|
{
|
|
74778
|
-
schema: { ...
|
|
74931
|
+
schema: { ...activeFormSchema, type: "object" },
|
|
74779
74932
|
initialData: emptyFormInitialData,
|
|
74780
74933
|
onSubmit: (formData) => handleSaveConnection(formData),
|
|
74781
74934
|
onTest: (formData) => handleTestFormData(formData),
|
|
@@ -74794,6 +74947,7 @@ const ConnectionsManager = () => {
|
|
|
74794
74947
|
const schemaDef = connectors.find((c) => c.id === selectedConnection.type);
|
|
74795
74948
|
const canManagePassword = supportsActiveConnection && !selectedConnection.builtIn && schemaHasPasswordField(schemaDef == null ? void 0 : schemaDef.schema);
|
|
74796
74949
|
const editSchema = (schemaDef == null ? void 0 : schemaDef.schema) && canManagePassword ? schemaWithoutPasswordField(schemaDef.schema) : schemaDef == null ? void 0 : schemaDef.schema;
|
|
74950
|
+
const modeAwareEditSchema = editSchema ? schemaForConnectionMode(editSchema, selectedConnection.type, mode) : void 0;
|
|
74797
74951
|
const passwordAnchorField = (editSchema == null ? void 0 : editSchema.properties["user"]) ? "user" : (editSchema == null ? void 0 : editSchema.properties["username"]) ? "username" : void 0;
|
|
74798
74952
|
const renderPasswordManagementField = (key) => {
|
|
74799
74953
|
if (!canManagePassword || key !== passwordAnchorField) {
|
|
@@ -74870,10 +75024,10 @@ const ConnectionsManager = () => {
|
|
|
74870
75024
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-conn-detail-body", children: [
|
|
74871
75025
|
renderToast(),
|
|
74872
75026
|
isActive && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-active-callout", role: "status", children: "Queries from SQL Preview and MCP will use this connection unless a query overrides it." }),
|
|
74873
|
-
|
|
75027
|
+
modeAwareEditSchema ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
74874
75028
|
DynamicForm,
|
|
74875
75029
|
{
|
|
74876
|
-
schema: { ...
|
|
75030
|
+
schema: { ...modeAwareEditSchema, type: "object" },
|
|
74877
75031
|
initialData: selectedFormInitialData,
|
|
74878
75032
|
onSubmit: (formData) => handleSaveConnection(formData, selectedConnection),
|
|
74879
75033
|
onTest: (formData) => handleTestFormData(formData, selectedConnection),
|
|
@@ -98712,7 +98866,8 @@ body.vscode-high-contrast .ag-theme-quartz {
|
|
|
98712
98866
|
}
|
|
98713
98867
|
|
|
98714
98868
|
.sp-conn-form-fields > .sp-conn-form-group:first-child,
|
|
98715
|
-
.sp-conn-form-field-name
|
|
98869
|
+
.sp-conn-form-field-name,
|
|
98870
|
+
.sp-conn-form-field-full {
|
|
98716
98871
|
grid-column: 1 / -1;
|
|
98717
98872
|
}
|
|
98718
98873
|
|
|
@@ -98741,6 +98896,31 @@ body.vscode-high-contrast .ag-theme-quartz {
|
|
|
98741
98896
|
margin-top: 4px;
|
|
98742
98897
|
}
|
|
98743
98898
|
|
|
98899
|
+
.sp-conn-form-advanced {
|
|
98900
|
+
grid-column: 1 / -1;
|
|
98901
|
+
padding-top: 2px;
|
|
98902
|
+
}
|
|
98903
|
+
|
|
98904
|
+
.sp-conn-form-advanced-summary {
|
|
98905
|
+
cursor: pointer;
|
|
98906
|
+
color: var(--sp-muted-fg);
|
|
98907
|
+
font-size: 12px;
|
|
98908
|
+
font-weight: 600;
|
|
98909
|
+
outline: none;
|
|
98910
|
+
}
|
|
98911
|
+
|
|
98912
|
+
.sp-conn-form-advanced-summary:hover,
|
|
98913
|
+
.sp-conn-form-advanced-summary:focus-visible {
|
|
98914
|
+
color: var(--sp-fg);
|
|
98915
|
+
}
|
|
98916
|
+
|
|
98917
|
+
.sp-conn-form-advanced-fields {
|
|
98918
|
+
display: grid;
|
|
98919
|
+
grid-template-columns: repeat(12, minmax(0, 1fr));
|
|
98920
|
+
gap: 12px 16px;
|
|
98921
|
+
margin-top: 10px;
|
|
98922
|
+
}
|
|
98923
|
+
|
|
98744
98924
|
.sp-conn-credential-state {
|
|
98745
98925
|
font-size: 11px;
|
|
98746
98926
|
color: var(--sp-muted-fg);
|
|
@@ -98883,6 +99063,10 @@ body.vscode-high-contrast .ag-theme-quartz {
|
|
|
98883
99063
|
overflow-wrap: anywhere;
|
|
98884
99064
|
word-break: break-word;
|
|
98885
99065
|
}
|
|
99066
|
+
.sp-conn-toast-action {
|
|
99067
|
+
flex-shrink: 0;
|
|
99068
|
+
align-self: center;
|
|
99069
|
+
}
|
|
98886
99070
|
.sp-conn-toast-close {
|
|
98887
99071
|
background: none;
|
|
98888
99072
|
border: none;
|
|
@@ -98999,7 +99183,8 @@ body.vscode-high-contrast .ag-theme-quartz {
|
|
|
98999
99183
|
grid-template-columns: minmax(0, 1fr);
|
|
99000
99184
|
}
|
|
99001
99185
|
|
|
99002
|
-
.sp-conn-form-fields
|
|
99186
|
+
.sp-conn-form-fields,
|
|
99187
|
+
.sp-conn-form-advanced-fields {
|
|
99003
99188
|
grid-template-columns: minmax(0, 1fr);
|
|
99004
99189
|
}
|
|
99005
99190
|
|