mirror of
https://github.com/goauthentik/authentik
synced 2026-05-08 16:13:02 +02:00
115 lines
3.8 KiB
JavaScript
Executable File
115 lines
3.8 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
/**
|
|
* @file Lints the installed Node.js and npm versions against the requirements specified in package.json.
|
|
*
|
|
* Usage:
|
|
* lint-node [options] [directory]
|
|
*
|
|
* Exit codes:
|
|
* 0 Versions are in sync
|
|
* 1 Version mismatch detected
|
|
*/
|
|
|
|
import * as assert from "node:assert/strict";
|
|
import { parseArgs } from "node:util";
|
|
|
|
import { ConsoleLogger } from "../../packages/logger-js/lib/node.js";
|
|
import { CommandError, parseCWD, reportAndExit } from "./utils/commands.mjs";
|
|
import { corepack } from "./utils/corepack.mjs";
|
|
import { resolveRepoRoot } from "./utils/git.mjs";
|
|
import { compareVersions, findNPMPackage, loadJSON, node, npm, parseRange } from "./utils/node.mjs";
|
|
|
|
const logger = ConsoleLogger.prefix("lint-runtime");
|
|
|
|
/**
|
|
* @param {string} start
|
|
*/
|
|
async function readRequirements(start) {
|
|
const { packageJSONPath } = await findNPMPackage(start);
|
|
|
|
logger.info(`Checking versions in ${packageJSONPath}`);
|
|
|
|
const packageJSONData = await loadJSON(packageJSONPath);
|
|
|
|
const nodeVersion = await node`--version`().then((output) => output.replace(/^v/, ""));
|
|
|
|
const requiredNpmVersion = packageJSONData.engines?.npm;
|
|
const requiredNodeVersion = packageJSONData.engines?.node;
|
|
|
|
return { nodeVersion, requiredNpmVersion, requiredNodeVersion };
|
|
}
|
|
|
|
async function main() {
|
|
const parsedArgs = parseArgs({
|
|
allowPositionals: true,
|
|
});
|
|
|
|
const cwd = parseCWD(parsedArgs.positionals);
|
|
const repoRoot = await resolveRepoRoot(cwd).catch(() => null);
|
|
|
|
logger.info(`cwd ${cwd}`);
|
|
logger.info(`repository ${repoRoot || "not found"}`);
|
|
|
|
const corepackVersion = await corepack`--version`().catch(() => null);
|
|
const useCorepack = !!corepackVersion;
|
|
logger.info(`corepack ${corepackVersion || "disabled"}`);
|
|
|
|
const npmVersion = await npm`--version`({ cwd, useCorepack })
|
|
.then((version) => {
|
|
logger.info(`npm${corepackVersion ? " (via Corepack)" : ""} ${version}`);
|
|
|
|
return version;
|
|
})
|
|
.catch((error) => {
|
|
if (error instanceof CommandError && corepackVersion) {
|
|
logger.warn(`Failed to read npm version via Corepack ${error.message}`);
|
|
|
|
logger.info(`Attempting to read npm version directly without Corepack...`);
|
|
// Corepack might be misconfigured or outdated.
|
|
// Attempting a second read without Corepack can help us distinguish
|
|
// between a general npm issue and a Corepack-specific one.
|
|
return npm`--version`({ cwd }).then((version) => {
|
|
logger.info(`npm (direct) ${version}`);
|
|
|
|
return version;
|
|
});
|
|
}
|
|
|
|
throw error;
|
|
});
|
|
|
|
const { nodeVersion, requiredNpmVersion, requiredNodeVersion } = await readRequirements(cwd);
|
|
|
|
logger.info(`node ${nodeVersion}`);
|
|
|
|
if (requiredNpmVersion) {
|
|
logger.info(`package.json npm ${requiredNpmVersion}`);
|
|
|
|
const { operator, version: required } = parseRange(requiredNpmVersion);
|
|
const result = compareVersions(npmVersion, required);
|
|
|
|
assert.ok(
|
|
operator === ">=" ? result >= 0 : result === 0,
|
|
`npm version ${npmVersion} does not satisfy required version ${requiredNpmVersion}`,
|
|
);
|
|
}
|
|
|
|
if (requiredNodeVersion) {
|
|
logger.info(`package.json node ${requiredNodeVersion}`);
|
|
|
|
const { operator, version: required } = parseRange(requiredNodeVersion);
|
|
const result = compareVersions(nodeVersion, required);
|
|
|
|
assert.ok(
|
|
operator === ">=" ? result >= 0 : result === 0,
|
|
`Node.js version ${nodeVersion} does not satisfy required version ${requiredNodeVersion}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
main()
|
|
.then(() => {
|
|
logger.info("✅ Node.js and npm versions are in sync.");
|
|
})
|
|
.catch((error) => reportAndExit(error, logger));
|