From b6b8beb9023d247856e226d55ab73b443015ed89 Mon Sep 17 00:00:00 2001 From: Garry Trinder Date: Tue, 4 Mar 2025 18:21:34 +0000 Subject: [PATCH] Add config new command. Closes #209 Closes #209 --- CHANGELOG.md | 4 +++- README.md | 1 + package.json | 7 ++++++ src/commands.ts | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ src/helpers.ts | 6 ++--- 5 files changed, 72 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19a7926..77474ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.21.0] - Unreleased -No changes yet. +### Added: + +- Command: `dev-proxy-toolkit.config-new` - Create new configuration file ## [0.20.0] - 2025-04-01 diff --git a/README.md b/README.md index 87cc18c..50a27bf 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ The following sections describe the features that the extension contributes to V - `Dev Proxy Toolkit: Start recording` - Only available when Dev Proxy is running - `Dev Proxy Toolkit: Stop recording`- Only available when Dev Proxy is recording - `Dev Proxy Toolkit: Open configuration file`- Only available when Dev Proxy is installed +- `Dev Proxy Toolkit: Create configuration file`- Only available when Dev Proxy is installed ### Diagnostics diff --git a/package.json b/package.json index 94bd8ef..03dee3e 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,13 @@ "category": "Dev Proxy Toolkit", "icon": "$(file-code)", "enablement": "isDevProxyInstalled" + }, + { + "command": "dev-proxy-toolkit.config-new", + "title": "Create configuration file", + "category": "Dev Proxy Toolkit", + "icon": "$(file-code)", + "enablement": "isDevProxyInstalled" } ], "menus": { diff --git a/src/commands.ts b/src/commands.ts index 4408d5c..26c4444 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -195,4 +195,62 @@ export const registerCommands = (context: vscode.ExtensionContext, configuration ? await executeCommand(`${VersionExeName.Stable} config open`) : await executeCommand(`${VersionExeName.Beta} config open`); })); + + context.subscriptions.push( + vscode.commands.registerCommand('dev-proxy-toolkit.config-new', async () => { + const versionPreference = configuration.get('version') as VersionPreference; + const exeName = versionPreference === VersionPreference.Stable ? VersionExeName.Stable : VersionExeName.Beta; + + // ask the user for the filename that they want to use + const fileName = await vscode.window.showInputBox({ + prompt: 'Enter the name of the new config file', + value: 'devproxyrc.json', + validateInput: (value: string) => { + console.log(value); + const errors: string[] = []; + + if (!value) { + errors.push('The file name cannot be empty'); + } + + if (value.includes('/') || value.includes('\\') || value.includes(' ') || value.includes(':') || value.includes('*') || value.includes('?') || value.includes('"') || value.includes('<') || value.includes('>') || value.includes('|')) { + errors.push('The file name cannot contain special characters'); + } + + if (!value.endsWith('.json') && !value.endsWith('.jsonc')) { + errors.push('The file name must use .json or .jsonc extension'); + } + + return errors.length === 0 ? undefined : errors[0]; + } + }); + + // check if file exists, if it does show an error message + // we do this after the user has entered the filename + try { + const workspaceFolder = vscode.workspace.workspaceFolders?.[0].uri.fsPath; + console.log(workspaceFolder); + const { type } = await vscode.workspace.fs.stat(vscode.Uri.file(`${workspaceFolder}/${fileName}`)); + if (type === vscode.FileType.File) { + vscode.window.showErrorMessage('A file with that name already exists'); + return; + } + } catch { } // file does not exist, continue + + try { + // show progress + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: 'Creating new config file...' + }, async () => { + await executeCommand(`${exeName} config new ${fileName}`, { cwd: vscode.workspace.workspaceFolders?.[0].uri.fsPath }); + }); + + const configUri = vscode.Uri.file(`${vscode.workspace.workspaceFolders?.[0].uri.fsPath}/${fileName}`); + const document = await vscode.workspace.openTextDocument(configUri); + await vscode.window.showTextDocument(document); + } catch (error) { + vscode.window.showErrorMessage('Failed to create new config file'); + } + })); }; diff --git a/src/helpers.ts b/src/helpers.ts index 73bd675..a186b7e 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -1,6 +1,6 @@ import * as vscode from 'vscode'; import parse from 'json-to-ast'; -import { exec } from 'child_process'; +import { exec, ExecOptions } from 'child_process'; export const getASTNode = ( children: parse.PropertyNode[], @@ -98,9 +98,9 @@ export const sleep = (ms: number): Promise => { }); }; -export const executeCommand = async (cmd: string): Promise => { +export const executeCommand = async (cmd: string, options: ExecOptions = {}): Promise => { return new Promise((resolve, reject) => { - exec(cmd, (error, stdout, stderr) => { + exec(cmd, options, (error, stdout, stderr) => { if (error) { reject(`exec error: ${error}`); } else if (stderr) {