Last active
March 14, 2024 04:51
-
-
Save srijan-paul/8351e70e513ec6dc9032e07f500e14f0 to your computer and use it in GitHub Desktop.
Get a VSCode extension's version using the (undocumented) marketplace API.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// To use this in a `.js` file, just remove the type annotations. | |
/** | |
* (Makes reverse engineered internal API calls from https://marketplace.visualstudio.com) | |
* @param {string} extFullName Org name + "." + extension name. e.g: `"DeepSourceCorp.deepsource-vscode"` | |
* @returns The latest version of the DeepSource extension from the marketplace, as a semver string. | |
*/ | |
async function fetchLatestExtensionVersion(extFullName: string): Promise<string | null> { | |
const resp = await fetch( | |
"https://marketplace.visualstudio.com/_apis/public/gallery/extensionquery", | |
{ | |
method: "POST", | |
headers: { | |
Accept: "application/json;api-version=7.2-preview.1;excludeUrls=true", | |
"Content-Type": "application/json", | |
}, | |
body: JSON.stringify({ | |
// this request body was taken from the browser's network tab when observing the requests | |
// made by the VSCode marketplace web page. | |
assetTypes: null, | |
filters: [ | |
{ | |
criteria: [ | |
{ | |
filterType: 7, | |
value: extFullName, | |
}, | |
], | |
direction: 2, | |
pageSize: 100, | |
pageNumber: 1, | |
sortBy: 0, | |
sortOrder: 0, | |
pagingToken: null, | |
}, | |
], | |
flags: 55, | |
}), | |
}, | |
); | |
const json: unknown = await resp.json(); | |
// The shape of the response was once again taken from the network tab. | |
if (json && typeof json === "object" && "results" in json && Array.isArray(json.results)) { | |
const result: unknown = json.results[0]; | |
if ( | |
!( | |
result && | |
typeof result === "object" && | |
"extensions" in result && | |
Array.isArray(result.extensions) | |
) | |
) | |
return null; | |
const extension: unknown = result.extensions[0]; | |
if ( | |
!( | |
extension && | |
typeof extension === "object" && | |
"versions" in extension && | |
Array.isArray(extension.versions) | |
) | |
) | |
return null; | |
const versions = extension.versions.filter((v) => !isPrelease(v)); | |
const version = versions[0]; | |
if (!(version && typeof version === "object" && "version" in version)) return null; | |
return version.version; | |
} | |
return null; | |
} | |
/** | |
* @param version A version object from the marketplace API. | |
* @returns `true` if the version is a pre-release, `false` otherwise. | |
*/ | |
function isPrelease(version: unknown) { | |
if ( | |
!( | |
typeof version === "object" && | |
version !== null && | |
"properties" in version && | |
Array.isArray(version.properties) | |
) | |
) { | |
return false; | |
} | |
const properties: unknown[] = version.properties; | |
return properties.some((p) => { | |
return ( | |
typeof p === "object" && | |
p && | |
"key" in p && | |
"value" in p && | |
p.key === "Microsoft.VisualStudio.Code.PreRelease" && | |
p.value === "true" | |
); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment