Fix update-node-version script for non-existent @types/node version
This commit is contained in:
@@ -3,6 +3,7 @@ import { execSync } from "child_process";
|
|||||||
import { outputFile, readFile, readJSON } from "fs-extra";
|
import { outputFile, readFile, readJSON } from "fs-extra";
|
||||||
import { getVersionInformation } from "./util/vscode-versions";
|
import { getVersionInformation } from "./util/vscode-versions";
|
||||||
import { fetchJson } from "./util/fetch";
|
import { fetchJson } from "./util/fetch";
|
||||||
|
import { SemVer } from "semver";
|
||||||
|
|
||||||
const extensionDirectory = resolve(__dirname, "..");
|
const extensionDirectory = resolve(__dirname, "..");
|
||||||
|
|
||||||
@@ -10,6 +11,29 @@ interface Release {
|
|||||||
tag_name: string;
|
tag_name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface NpmViewError {
|
||||||
|
error: {
|
||||||
|
code: string;
|
||||||
|
summary: string;
|
||||||
|
detail: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ExecError extends Error {
|
||||||
|
status: number;
|
||||||
|
stdout: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isExecError(e: unknown): e is ExecError {
|
||||||
|
return (
|
||||||
|
e instanceof Error &&
|
||||||
|
"status" in e &&
|
||||||
|
typeof e.status === "number" &&
|
||||||
|
"stdout" in e &&
|
||||||
|
typeof e.stdout === "string"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
async function updateNodeVersion() {
|
async function updateNodeVersion() {
|
||||||
const latestVsCodeRelease = await fetchJson<Release>(
|
const latestVsCodeRelease = await fetchJson<Release>(
|
||||||
"https://api.github.com/repos/microsoft/vscode/releases/latest",
|
"https://api.github.com/repos/microsoft/vscode/releases/latest",
|
||||||
@@ -49,6 +73,8 @@ async function updateNodeVersion() {
|
|||||||
"utf8",
|
"utf8",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const nodeVersion = new SemVer(versionInformation.nodeVersion);
|
||||||
|
|
||||||
// The @types/node version needs to match the first two parts of the Node
|
// The @types/node version needs to match the first two parts of the Node
|
||||||
// version, e.g. if the Node version is 18.17.3, the @types/node version
|
// version, e.g. if the Node version is 18.17.3, the @types/node version
|
||||||
// should be 18.17.*. This corresponds with the documentation at
|
// should be 18.17.*. This corresponds with the documentation at
|
||||||
@@ -56,13 +82,55 @@ async function updateNodeVersion() {
|
|||||||
// "The patch version of the type declaration package is unrelated to the library patch version. This allows
|
// "The patch version of the type declaration package is unrelated to the library patch version. This allows
|
||||||
// Definitely Typed to safely update type declarations for the same major/minor version of a library."
|
// Definitely Typed to safely update type declarations for the same major/minor version of a library."
|
||||||
// 18.17.* is equivalent to >=18.17.0 <18.18.0
|
// 18.17.* is equivalent to >=18.17.0 <18.18.0
|
||||||
const typesNodeVersion = versionInformation.nodeVersion
|
// In some cases, the @types/node version matching the exact Node version may not exist, in which case we'll try
|
||||||
.split(".")
|
// the next lower minor version, and so on, until we find a version that exists.
|
||||||
.slice(0, 2)
|
const typesNodeSemver = new SemVer(nodeVersion);
|
||||||
.join(".");
|
typesNodeSemver.patch = 0;
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-constant-condition
|
||||||
|
while (true) {
|
||||||
|
const typesNodeVersion = `${typesNodeSemver.major}.${typesNodeSemver.minor}.*`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Check that this version actually exists
|
||||||
|
console.log(`Checking if @types/node@${typesNodeVersion} exists`);
|
||||||
|
|
||||||
|
execSync(`npm view --json "@types/node@${typesNodeVersion}"`, {
|
||||||
|
encoding: "utf-8",
|
||||||
|
stdio: "pipe",
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`@types/node@${typesNodeVersion} exists`);
|
||||||
|
|
||||||
|
// If it exists, we can break out of this loop
|
||||||
|
break;
|
||||||
|
} catch (e: unknown) {
|
||||||
|
if (!isExecError(e)) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
const error = JSON.parse(e.stdout) as NpmViewError;
|
||||||
|
if (error.error.code !== "E404") {
|
||||||
|
throw new Error(error.error.detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`@types/node package doesn't exist for ${typesNodeVersion}, trying a lower version (${error.error.summary})`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// This means the version doesn't exist, so we'll try decrementing the minor version
|
||||||
|
typesNodeSemver.minor -= 1;
|
||||||
|
if (typesNodeSemver.minor < 0) {
|
||||||
|
throw new Error(
|
||||||
|
`Could not find a suitable @types/node version for Node ${nodeVersion.format()}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
packageJson.engines.node = `^${versionInformation.nodeVersion}`;
|
packageJson.engines.node = `^${versionInformation.nodeVersion}`;
|
||||||
packageJson.devDependencies["@types/node"] = `${typesNodeVersion}.*`;
|
packageJson.devDependencies["@types/node"] =
|
||||||
|
`${typesNodeSemver.major}.${typesNodeSemver.minor}.*`;
|
||||||
|
|
||||||
await outputFile(
|
await outputFile(
|
||||||
join(extensionDirectory, "package.json"),
|
join(extensionDirectory, "package.json"),
|
||||||
|
|||||||
Reference in New Issue
Block a user