Skip to content

Commit e15bfd6

Browse files
committed
Feature/Add command to load OpenAPI specifications from local disk
1 parent 274d441 commit e15bfd6

File tree

3 files changed

+97
-3
lines changed

3 files changed

+97
-3
lines changed

src/vsc-extension/openapi-ui/CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ All notable changes to the "openapi-ui" extension will be documented in this fil
44

55
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
66

7+
## [1.1.1] - 2026-01-27
8+
9+
### Added
10+
11+
- **Load from Disk**: New command `openapi-ui.loadFromDisk` to load OpenAPI specifications from local files
12+
- Supports JSON and YAML files via file picker dialog
13+
- Accepts optional file path parameter for programmatic usage
14+
- Validates JSON content before loading
15+
- Displays file name in webview title
16+
717
## [1.1.0] - 2026-01-27
818

919
### Added
@@ -22,6 +32,8 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
2232
- FetchInterceptor script validation tests
2333

2434

35+
36+
2537
## [Unreleased]
2638

2739
- Initial release

src/vsc-extension/openapi-ui/package.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "openapi-ui",
33
"displayName": "OpenAPI UI",
44
"description": "OpenAPI UI viewer for VS Code",
5-
"version": "1.1.0",
5+
"version": "1.1.1",
66
"publisher": "JakubKozera",
77
"icon": "openapi-ui.png",
88
"repository": {
@@ -84,6 +84,11 @@
8484
"command": "openapi-ui.openWithUrl",
8585
"title": "Open OpenAPI UI with URL",
8686
"icon": "$(link-external)"
87+
},
88+
{
89+
"command": "openapi-ui.loadFromDisk",
90+
"title": "Load OpenAPI UI from Disk",
91+
"icon": "$(file)"
8792
}
8893
],
8994
"menus": {
@@ -113,6 +118,9 @@
113118
},
114119
{
115120
"command": "openapi-ui.openWithUrl"
121+
},
122+
{
123+
"command": "openapi-ui.loadFromDisk"
116124
}
117125
]
118126
}

src/vsc-extension/openapi-ui/src/extension.ts

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ export function activate(context: vscode.ExtensionContext) {
363363

364364
const panel = vscode.window.createWebviewPanel(
365365
"openapiURLUI",
366-
`OpenAPI UI - ${new URL(openapiUrl).hostname}`,
366+
`OpenAPI UI`,
367367
vscode.ViewColumn.One,
368368
{
369369
enableScripts: true,
@@ -399,14 +399,88 @@ export function activate(context: vscode.ExtensionContext) {
399399
}
400400
);
401401

402+
// Register command to load OpenAPI UI from local disk file
403+
let loadFromDiskDisposable = vscode.commands.registerCommand(
404+
"openapi-ui.loadFromDisk",
405+
async (filePath?: string) => {
406+
let selectedFilePath = filePath;
407+
408+
// If no file path provided, show file picker
409+
if (!selectedFilePath) {
410+
const fileUri = await vscode.window.showOpenDialog({
411+
canSelectMany: false,
412+
openLabel: "Select OpenAPI Specification",
413+
filters: {
414+
"JSON files": ["json"],
415+
"YAML files": ["yaml", "yml"],
416+
"All files": ["*"],
417+
},
418+
});
419+
420+
if (!fileUri || fileUri.length === 0) {
421+
return;
422+
}
423+
424+
selectedFilePath = fileUri[0].fsPath;
425+
}
426+
427+
try {
428+
// Read file content
429+
const fileContent = fs.readFileSync(selectedFilePath, "utf8");
430+
431+
// Validate JSON
432+
JSON.parse(fileContent);
433+
434+
const fileName = path.basename(selectedFilePath);
435+
436+
const panel = vscode.window.createWebviewPanel(
437+
"openapiDiskUI",
438+
`OpenAPI UI`,
439+
vscode.ViewColumn.One,
440+
{
441+
enableScripts: true,
442+
localResourceRoots: [
443+
vscode.Uri.file(path.join(context.extensionPath, "core-dist")),
444+
],
445+
}
446+
);
447+
448+
// Set webview icon
449+
panel.iconPath = vscode.Uri.file(
450+
path.join(context.extensionPath, "openapi-ui.png")
451+
);
452+
453+
// Set up message handling for fetch proxy
454+
const messageHandler = setupWebviewMessageHandler(panel);
455+
panel.onDidDispose(() => messageHandler.dispose());
456+
457+
panel.webview.html = getWebviewContent(
458+
panel.webview,
459+
context.extensionPath,
460+
undefined,
461+
fileContent
462+
);
463+
464+
vscode.window.showInformationMessage(
465+
`Opened OpenAPI UI from ${fileName}`
466+
);
467+
} catch (error) {
468+
vscode.window.showErrorMessage(
469+
`Failed to load OpenAPI file: ${error}`
470+
);
471+
}
472+
}
473+
);
474+
402475
context.subscriptions.push(
403476
openViewDisposable,
404477
addSourceDisposable,
405478
removeSourceDisposable,
406479
refreshSourcesDisposable,
407480
loadSourceDisposable,
408481
addJsonSourceDisposable,
409-
openWithUrlDisposable
482+
openWithUrlDisposable,
483+
loadFromDiskDisposable
410484
);
411485
}
412486

0 commit comments

Comments
 (0)