Skip to content

Commit

Permalink
feat: support new execute API from codelens
Browse files Browse the repository at this point in the history
  • Loading branch information
Codeneos committed Dec 18, 2023
1 parent d20a722 commit 2deeaff
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,21 @@ import * as vscode from 'vscode';

import VlocodeService from "../lib/vlocodeService";
import { container, injectable } from "@vlocode/core";
import { VlocodeCommand } from '../constants';

@injectable()
export class ExecuteApiLensProvider implements vscode.CodeLensProvider {

private documentFilter : Array<vscode.DocumentFilter> = [
{ pattern: '**/*.{api,http,sfhttp,sfapi}' },
{ language: 'sfhttp' }
];

private regex = /^(GET|POST|PUT|DELETE|PATCH) (.*)$/i

public static register(service: VlocodeService) {
const lens = container.get(ExecuteApiLensProvider);
vscode.languages.registerCodeLensProvider({ pattern: '**/*.{api,http,sfhttp,sfapi}' }, lens);
vscode.languages.registerCodeLensProvider({ language: 'sfhttp' }, lens);
vscode.languages.registerCodeLensProvider(lens.documentFilter, lens);
}

public provideCodeLenses(document: vscode.TextDocument): vscode.CodeLens[] {
Expand All @@ -22,9 +27,9 @@ export class ExecuteApiLensProvider implements vscode.CodeLensProvider {
return [
new vscode.CodeLens(line.range, {
title: `Execute as Salesforce API Request (${match[1].toLowerCase()})`,
tooltip: "Execute the API request described in this file on the selected Salesforce org",
command: "vlocode.api.execute",
arguments: [ document ]
tooltip: 'Execute the API request described in this file on the selected Salesforce org',
command: VlocodeCommand.execRestApi,
arguments: [ document.uri ]
})
];
} else if (line.text) {
Expand All @@ -33,4 +38,8 @@ export class ExecuteApiLensProvider implements vscode.CodeLensProvider {
}
return [];
}

public resolveCodeLens(codeLens: vscode.CodeLens, token: vscode.CancellationToken): vscode.CodeLens | undefined {
return codeLens;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import * as vscode from 'vscode';
import { HttpMethod, HttpRequestInfo } from '@vlocode/salesforce';

/**
* Parser for SF HTTP request documents
*/
export class ApiRequestDocumentParser {

private readonly documentHeaderRegex = /^(GET|POST|PUT|DELETE|PATCH) (.*)$/i;
private readonly documentHttpHeaderRegex = /^([a-z0-9-]+): (.*)$/i;

private readonly document: vscode.TextDocument;
private nextLine: number = 0;

private url: string;
private body: string;
private method: HttpMethod;
private headers: Record<string, string> = {};

/**
* Parse a HTTP request document into a HttpRequestInfo object.
* Will throw an error if the document is not a valid HTTP request document.
* @param document VSCode document to parse
* @returns Parsed HttpRequestInfo object
*/
public static async parse(document: vscode.TextDocument) {
const parser = new ApiRequestDocumentParser(document);
await parser.parseRequestMethodAndUrl();
await parser.parseHeaders();
await parser.parseBody();
return parser.toRequestInfo();
}

private constructor(document: vscode.TextDocument) {
this.document = document;
}

private toRequestInfo() : HttpRequestInfo {
return {
url: this.url,
method: this.method,
headers: this.headers,
body: this.body
};
}

private hasMoreLines() {
return this.nextLine < this.document.lineCount;
}

private getNextLine() {
if (!this.hasMoreLines()) {
throw new Error('No more lines to read, reached end of document');
}
return this.document.lineAt(this.nextLine++);
}

private async parseRequestMethodAndUrl() {
while(this.hasMoreLines()) {
const line = this.getNextLine();
const match = line.text.match(this.documentHeaderRegex);

if (match) {
this.url = match[2];
this.method = match[1] as HttpMethod;
break;
} else if (line.text) {
throw new Error(`Expected document to start with HTTP method and URL, got ${line.text} at line ${line.lineNumber}`);
}
}
}

private async parseHeaders() {
while(this.hasMoreLines()) {
const line = this.getNextLine();
const match = line.text.match(this.documentHttpHeaderRegex);

if (match) {
this.headers[match[1].trim()] = match[2].trim();
} else if (!line.text) {
this.nextLine--;
break;
} else {
break;
}
}
}

private async parseBody() {
this.body = this.document.getText(new vscode.Range(this.nextLine, 0, this.document.lineCount, 0));
}
}

0 comments on commit 2deeaff

Please sign in to comment.