-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: verify @types/node version with registry
Signed-off-by: Michael Molisani <[email protected]>
- Loading branch information
Showing
28 changed files
with
3,156 additions
and
82 deletions.
There are no files selected for viewing
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// Copyright 2024 Bloomberg Finance L.P. | ||
// Distributed under the terms of the Apache 2.0 license. | ||
import { discoverPackageRegistry, fetchPackageVersions } from "./registry"; | ||
|
||
export interface NodeVersions { | ||
readonly engine: string; | ||
readonly types: string; | ||
} | ||
|
||
const MAXIMUM_KNOWN_SAFE_NODE_TYPES_VERSION = 22; | ||
|
||
export async function calculateAcceptableNodeVersions(process: NodeJS.Process): Promise<NodeVersions> { | ||
const majorVersion = Number(process.versions.node.split(".")[0]); | ||
let typesVersion: string | undefined; | ||
|
||
if (majorVersion > MAXIMUM_KNOWN_SAFE_NODE_TYPES_VERSION) { | ||
// To avoid hitting the registry every time, only run when higher than a statically-known maximum safe value. | ||
const registry = discoverPackageRegistry(process); | ||
const versions = registry && (await fetchPackageVersions(registry, "@types/node")); | ||
if (versions?.includes(process.versions.node)) { | ||
typesVersion = `^${process.versions.node}`; | ||
} else if (versions) { | ||
const typeMajors = new Set(versions.map((version) => Number(version.split(".")[0]))); | ||
if (typeMajors.has(majorVersion)) { | ||
// Previously unknown major version exists, which means MAXIMUM_KNOWN_SAFE_NODE_TYPES_VERSION should be updated. | ||
typesVersion = `${majorVersion}.x`; | ||
} else { | ||
// Filter available major versions to just even (LTS) and pick highest. | ||
// This assumes that types will exist for the LTS version just prior to the current unknown major version. | ||
const highestEvenTypeMajor = [...typeMajors] | ||
.filter((major) => major % 2 === 0) | ||
.toSorted() | ||
.at(-1); | ||
if (highestEvenTypeMajor) { | ||
typesVersion = `${highestEvenTypeMajor}.x`; | ||
process.stderr.write( | ||
`No version of @types/node found with major ${majorVersion}, falling back to ${typesVersion}\n`, | ||
); | ||
} | ||
} | ||
} | ||
} else { | ||
typesVersion = `${majorVersion}.x`; | ||
} | ||
|
||
if (!typesVersion) { | ||
typesVersion = `${majorVersion}.x`; | ||
// Should only be hit if something went wrong determining registry URL or fetching from registry. | ||
process.stderr.write( | ||
`Unable to determine version of @types/node for ${process.versions.node}, assuming ${typesVersion}\n`, | ||
); | ||
} | ||
|
||
return { | ||
engine: `>=${majorVersion}`, | ||
types: typesVersion, | ||
}; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Copyright 2024 Bloomberg Finance L.P. | ||
// Distributed under the terms of the Apache 2.0 license. | ||
import child_process from "node:child_process"; | ||
|
||
export function discoverPackageRegistry(process: NodeJS.Process): string | undefined { | ||
if (process.env["NPM_CONFIG_REGISTRY"]) { | ||
return process.env["NPM_CONFIG_REGISTRY"]; | ||
} | ||
|
||
if (process.env["NPM_EXECPATH"]) { | ||
return child_process | ||
.execFileSync(process.execPath, [process.env["NPM_EXECPATH"], "config", "get", "registry"], { | ||
encoding: "utf-8", | ||
}) | ||
.trim(); | ||
} | ||
} | ||
|
||
export async function fetchPackageVersions( | ||
registry: string, | ||
packageName: string, | ||
): Promise<readonly string[] | undefined> { | ||
const input = registry + (registry.endsWith("/") ? packageName : `/${packageName}`); | ||
const response = await fetch(input); | ||
const data = await response.json(); | ||
if (typeof data === "object" && data && "versions" in data && typeof data.versions === "object") { | ||
return Object.keys(data.versions ?? {}); | ||
} | ||
} |
Oops, something went wrong.