equicord-companion
Version:
Equicord Companion is a vscode extension to test Equicord patches & webpack finds right from the comfort of your IDE
109 lines (100 loc) • 3.87 kB
text/typescript
import { debounceAsync, zeroRange } from "@ast/util";
import { VencordAstParser } from "@ast/vencord";
import { outputChannel } from "@modules/logging";
import { sendAndGetData, sockets } from "@server/index";
import { Diagnostic, DiagnosticSeverity, languages, Range, TextDocument, TextDocumentChangeEvent, Uri } from "vscode";
const diagnosticCollection = languages.createDiagnosticCollection("equicord-companion");
const runtimeErrorWarning = new Diagnostic(zeroRange, "An error occured, check the log for more info", DiagnosticSeverity.Warning);
const zeroClientsWarning = new Diagnostic(zeroRange, "No clients connected", DiagnosticSeverity.Warning);
export const updateDiagnostics = debounceAsync(updateDiagnosticsImmediately, 1500);
export function onEditCallback(e: TextDocumentChangeEvent) {
if (!e)
return;
return onOpenCallback(e.document);
}
export function onOpenCallback(e: TextDocument) {
// when the editor is first opened, the files will be plaintext
// for some other reason, the file all end in .git
if (e.languageId !== "typescript" && e.languageId !== "typescriptreact" && !e.fileName.match(/\.tsx?(?:\.git)?$/))
return;
updateDiagnostics(e.uri);
}
export function reloadDiagnostics() {
for (const [uri] of diagnosticCollection) {
updateDiagnosticsImmediately(uri);
}
}
async function updateDiagnosticsImmediately(e: Uri) {
if (sockets.size === 0) {
diagnosticCollection.set(e, [zeroClientsWarning]);
return;
}
const doc = await VencordAstParser.fromUri(e);
// Set to filter duplicate error / no client warnings
const diagnostics = Array.from(new Set((await Promise.all([
makeFindDiagnostic(doc),
makePatchDiagnostic(doc),
])).flat()));
diagnosticCollection.set(e, diagnostics);
}
async function makePatchDiagnostic(doc: VencordAstParser): Promise<Diagnostic[]> {
try {
return (
await Promise.all(doc.getPatches()
.map(async ({ range, ...data }) => ({
range,
message: await sendAndGetData({
type: "testPatch",
data,
})
.then(
() => { },
(e: string | Error) => (typeof e === "string" ? e : e?.message),
),
})))
)
.filter((e): e is {
range: Range;
message: string;
} => e.message != null)
.map(({ range, message }) => ({
range,
message,
severity: DiagnosticSeverity.Error,
source: "Equicord-Companion",
code: "patch",
}));
} catch (e) {
outputChannel.error(e);
return [runtimeErrorWarning];
}
}
async function makeFindDiagnostic(doc: VencordAstParser): Promise<Diagnostic[]> {
try {
return (
await Promise.all(doc.getFinds()
.map(async ({ range, use }) => ({
range,
message: await sendAndGetData(use)
.then(
() => { },
(e: string | Error) => (typeof e === "string" ? e : e?.message),
),
})))
)
.filter((e): e is {
range: Range;
message: string;
} => e.message != null)
.map(({ range, message }) => ({
range,
severity: DiagnosticSeverity.Error,
message,
source: "Equicord-Companion",
code: "find",
}));
} catch (e) {
outputChannel.error(e);
return [runtimeErrorWarning];
}
}