From d6807463d987e5e2038dbfa83504d7a85f4c4308 Mon Sep 17 00:00:00 2001 From: Trivikram Kamat <16024985+trivikr@users.noreply.github.com> Date: Fri, 2 Oct 2026 15:29:32 -0700 Subject: [PATCH] Replace typed-rest-client with global fetch typed-rest-client was only used by PublicGalleryAPI, so it can go now that Node 22 has a built-in fetch. Keep the 'vsce' User-Agent that HttpClient('vsce') used to send, and add a status check: a non-2xx response now throws with the gallery's error message, or the HTTP status if there isn't one. Before, it surfaced as an unclear JSON parse error. --- package-lock.json | 1 - package.json | 1 - src/publicgalleryapi.ts | 28 +++++++++++++++++++++------- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 11674b99..86c6263b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,6 @@ "read": "^1.0.7", "semver": "^7.8.5", "tinyglobby": "^0.2.17", - "typed-rest-client": "^1.8.11", "url-join": "^4.0.1", "xml2js": "^0.5.0", "yauzl": "^3.4.0", diff --git a/package.json b/package.json index ade93eed..33361aff 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,6 @@ "read": "^1.0.7", "semver": "^7.8.5", "tinyglobby": "^0.2.17", - "typed-rest-client": "^1.8.11", "url-join": "^4.0.1", "xml2js": "^0.5.0", "yauzl": "^3.4.0", diff --git a/src/publicgalleryapi.ts b/src/publicgalleryapi.ts index c740c221..992119d1 100644 --- a/src/publicgalleryapi.ts +++ b/src/publicgalleryapi.ts @@ -1,4 +1,3 @@ -import { HttpClient, HttpClientResponse } from 'typed-rest-client/HttpClient'; import { PublishedExtension, ExtensionQueryFlags, @@ -6,7 +5,6 @@ import { ExtensionQueryFilterType, TypeInfo, } from 'azure-devops-node-api/interfaces/GalleryInterfaces'; -import { IHeaders } from 'azure-devops-node-api/interfaces/common/VsoBaseInterfaces'; import { ContractSerializer } from 'azure-devops-node-api/Serialization'; export interface ExtensionQuery { @@ -22,12 +20,15 @@ interface VSCodePublishedExtension extends PublishedExtension { } export class PublicGalleryAPI { - private readonly client = new HttpClient('vsce'); - constructor(private baseUrl: string, private apiVersion = '3.0-preview.1') {} - private post(url: string, data: string, additionalHeaders?: IHeaders): Promise { - return this.client.post(`${this.baseUrl}/_apis/public${url}`, data, additionalHeaders); + private post(url: string, data: string, additionalHeaders?: Record): Promise { + return fetch(`${this.baseUrl}/_apis/public${url}`, { + method: 'POST', + // typed-rest-client's HttpClient('vsce') sent this user agent + headers: { 'User-Agent': 'vsce', ...additionalHeaders }, + body: data, + }); } async extensionQuery({ @@ -47,7 +48,20 @@ export class PublicGalleryAPI { Accept: `application/json;api-version=${this.apiVersion}`, 'Content-Type': 'application/json', }); - const raw = JSON.parse(await res.readBody()); + const body = await res.text(); + + if (!res.ok) { + // Prefer the gallery's own error message when the body carries one + let message: string | undefined; + try { + message = JSON.parse(body).message; + } catch { + // non-JSON error body + } + throw new Error(message ?? `Gallery request failed: ${res.status} ${res.statusText}`); + } + + const raw = JSON.parse(body); if (raw.errorCode !== undefined) { throw new Error(raw.message);