Skip to content

Commit 93104b1

Browse files
Merge pull request #1184 from christianhelle/vscode-generate-from-refitter-file
2 parents 3591134 + 5aa3768 commit 93104b1

File tree

3 files changed

+153
-4
lines changed

3 files changed

+153
-4
lines changed

src/VSCode/README.md

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ You can install this extension in several ways:
2121

2222
## Features
2323

24-
This extension adds a context menu item **REST API Client Code Generator** when right-clicking on JSON or YAML files in the VS Code explorer. The context menu provides the following code generation options:
24+
This extension adds a context menu item **REST API Client Code Generator** when right-clicking on JSON or YAML files in the VS Code explorer. Additionally, it provides a **Generate Refitter Output** command when right-clicking on `.refitter` settings files. The context menu provides the following code generation options:
2525

2626
### C# Generators
2727

@@ -45,6 +45,10 @@ This extension adds a context menu item **REST API Client Code Generator** when
4545
- **Redux Query**: Generates a TypeScript REST API Client for Redux Query
4646
- **RxJS**: Generates a TypeScript REST API Client for RxJS
4747

48+
### Refitter Settings Support
49+
50+
- **Generate Refitter Output**: When right-clicking on a `.refitter` settings file, you can generate C# Refit interfaces using Refitter with custom configuration. This allows for advanced Refitter configurations including custom settings for authentication, serialization, and other Refitter-specific options.
51+
4852
## Screenshot
4953

5054
![Command Palette](https://github.com/christianhelle/apiclientcodegen/raw/master/images/vscode-command-palette.png)
@@ -77,12 +81,49 @@ The extension includes configurable settings:
7781

7882
## How to Use
7983

84+
### For OpenAPI/Swagger Specifications
85+
8086
1. Right-click on a Swagger/OpenAPI specification file (JSON or YAML) in the VS Code explorer
8187
2. Select "REST API Client Generator" in the context menu
8288
3. Choose your desired language (C# or TypeScript)
8389
4. Select one of the available generators for that language
8490
5. The generated code will be saved in the configured output directory and opened in the editor
8591

92+
### For Refitter Settings Files
93+
94+
1. Create a `.refitter` settings file with your Refitter configuration
95+
2. Right-click on the `.refitter` file in the VS Code explorer
96+
3. Select "Generate Refitter Output" from the context menu
97+
4. The generated C# Refit interfaces will be created according to your settings file configuration
98+
99+
## Refitter Settings Files
100+
101+
The extension supports Refitter settings files (`.refitter`) which allow you to configure advanced options for generating C# Refit interfaces. A typical `.refitter` settings file includes:
102+
103+
- **OpenAPI specification URL or file path**
104+
- **Namespace configuration**
105+
- **Output file paths**
106+
- **Authentication settings**
107+
- **Serialization options**
108+
- **Custom type mappings**
109+
- **And many other Refitter-specific options**
110+
111+
Example `.refitter` file:
112+
113+
```json
114+
{
115+
"openApiSpecUrl": "https://petstore.swagger.io/v2/swagger.json",
116+
"namespace": "PetStore.Api",
117+
"outputFolder": "./Generated",
118+
"outputFilename": "PetStoreApi.cs",
119+
"clientName": "PetStoreClient",
120+
"generateContracts": true,
121+
"generateXmlDocCodeComments": true
122+
}
123+
```
124+
125+
For more information about Refitter settings, visit the [Refitter documentation](https://github.com/christianhelle/refitter).
126+
86127
## Dependencies
87128

88129
### C# Dependencies

src/VSCode/package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@
8989
{
9090
"command": "restApiClientCodeGenerator.typescript.rxjs",
9191
"title": "Generate TypeScript Client for RxJS"
92+
},
93+
{
94+
"command": "restApiClientCodeGenerator.refitterSettings",
95+
"title": "Generate Refitter Output"
9296
}
9397
],
9498
"menus": {
@@ -97,6 +101,11 @@
97101
"submenu": "restApiClientCodeGenerator.submenu",
98102
"when": "resourceExtname == .json || resourceExtname == .yaml || resourceExtname == .yml",
99103
"group": "z_commands"
104+
},
105+
{
106+
"command": "restApiClientCodeGenerator.refitterSettings",
107+
"when": "resourceExtname == .refitter",
108+
"group": "z_commands"
100109
}
101110
],
102111
"restApiClientCodeGenerator.submenu": [

src/VSCode/src/extension.ts

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,73 @@ async function executeRapicgenTypeScript(generator: string, specificationFilePat
545545
}
546546
}
547547

548+
/**
549+
* Executes the Rapicgen tool with Refitter using a settings file
550+
* @param settingsFilePath The path to the .refitter settings file
551+
* @param context The extension context
552+
*/
553+
async function executeRapicgenRefitterSettings(settingsFilePath: string, context: vscode.ExtensionContext): Promise<void> {
554+
// Validate the settings file
555+
if (!validateSpecificationFile(settingsFilePath)) {
556+
return;
557+
}
558+
559+
// Check if .NET SDK is installed
560+
if (!isDotNetSdkInstalled()) {
561+
vscode.window.showErrorMessage(
562+
'.NET SDK not found. Please install .NET SDK 6.0 or higher to use this extension. Visit https://dotnet.microsoft.com/download/dotnet to download and install.'
563+
);
564+
return;
565+
}
566+
567+
// Ensure the Rapicgen tool is installed and up-to-date
568+
const rapicgenAvailable = await ensureRapicgenToolAvailable(context);
569+
if (!rapicgenAvailable) {
570+
return;
571+
}
572+
573+
const command = `rapicgen csharp refitter --settings-file "${settingsFilePath}"`;
574+
575+
try {
576+
// Show progress while generating
577+
await vscode.window.withProgress({
578+
location: vscode.ProgressLocation.Notification,
579+
title: 'Generating Refitter output from settings file...',
580+
cancellable: false
581+
}, async () => {
582+
try {
583+
// Run with higher timeout since code generation can take time
584+
const output = execSync(command, {
585+
encoding: 'utf-8',
586+
timeout: 120000 // 2 minute timeout
587+
});
588+
589+
// Log output for debugging
590+
console.log(`Rapicgen Refitter settings output: ${output}`);
591+
592+
vscode.window.showInformationMessage('Successfully generated Refitter output from settings file');
593+
} catch (error: unknown) {
594+
let errorMessage = 'Error generating Refitter output from settings file';
595+
596+
const err = error as { message?: string; stderr?: string };
597+
if (err.message) {
598+
errorMessage += `: ${err.message}`;
599+
}
600+
601+
if (err.stderr) {
602+
errorMessage += `\n${err.stderr}`;
603+
console.error('Command stderr:', err.stderr);
604+
}
605+
606+
vscode.window.showErrorMessage(errorMessage);
607+
console.error('Command execution error:', error);
608+
}
609+
});
610+
} catch (error) {
611+
console.error('Error during Refitter settings code generation process:', error);
612+
}
613+
}
614+
548615
/**
549616
* Validates that a specification file exists and is readable
550617
* @param specificationFilePath The path to the OpenAPI/Swagger specification file
@@ -641,10 +708,42 @@ export function activate(context: vscode.ExtensionContext) {
641708

642709
executeRapicgenTypeScript(generator.command, fileUri.fsPath, context);
643710
}
644-
);
645-
646-
context.subscriptions.push(disposable);
711+
); context.subscriptions.push(disposable);
647712
}
713+
714+
// Register command for Refitter settings
715+
const refitterSettingsDisposable = vscode.commands.registerCommand(
716+
'restApiClientCodeGenerator.refitterSettings',
717+
async (fileUri: vscode.Uri) => {
718+
if (!fileUri) {
719+
// If command was triggered from command palette, ask for file
720+
const files = await vscode.workspace.findFiles('**/*.refitter');
721+
if (files.length === 0) {
722+
vscode.window.showErrorMessage('No .refitter settings files found in the workspace');
723+
return;
724+
}
725+
726+
const fileItems = files.map(file => ({
727+
label: path.basename(file.fsPath),
728+
description: vscode.workspace.asRelativePath(file),
729+
path: file.fsPath
730+
}));
731+
732+
const selectedFile = await vscode.window.showQuickPick(fileItems, {
733+
placeHolder: 'Select a .refitter settings file'
734+
});
735+
736+
if (!selectedFile) {
737+
return;
738+
}
739+
fileUri = vscode.Uri.file(selectedFile.path);
740+
}
741+
742+
executeRapicgenRefitterSettings(fileUri.fsPath, context);
743+
}
744+
);
745+
746+
context.subscriptions.push(refitterSettingsDisposable);
648747
}
649748

650749
/**

0 commit comments

Comments
 (0)