@juspay/neurolink
Version:
Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applicatio
98 lines (97 loc) • 3.52 kB
JavaScript
/**
* Proxy auto-update version checker.
*
* Queries the npm registry for the latest published version of
* `@juspay/neurolink` and compares it against the currently running version.
* Designed to be non-blocking and failure-tolerant — any error (network,
* timeout, parse) silently returns `updateAvailable: false`.
*/
import { execFile as execFileCb } from "node:child_process";
import { promisify } from "node:util";
import { logger } from "../utils/logger.js";
const execFile = promisify(execFileCb);
/** Timeout (ms) for the `npm view` child process. */
const NPM_VIEW_TIMEOUT_MS = 10_000;
/**
* Parse a version string of the form `major.minor.patch` into numeric
* components. Returns `null` when the string does not match.
*/
function parseSemVer(version) {
const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(version.trim());
if (!match) {
return null;
}
return {
major: Number(match[1]),
minor: Number(match[2]),
patch: Number(match[3]),
};
}
/**
* Returns `true` when `latest` is strictly greater than `current`.
*
* Both arguments must be valid semver strings; returns `false` on any
* parse failure so the caller never sees a spurious "update available".
*/
function isNewerVersion(current, latest) {
const cur = parseSemVer(current);
const lat = parseSemVer(latest);
if (!cur || !lat) {
return false;
}
if (lat.major !== cur.major) {
return lat.major > cur.major;
}
if (lat.minor !== cur.minor) {
return lat.minor > cur.minor;
}
return lat.patch > cur.patch;
}
// ---------------------------------------------------------------------------
// Core check
// ---------------------------------------------------------------------------
/**
* Query npm for the latest version of `@juspay/neurolink` and compare it
* against {@link currentVersion}.
*
* On **any** failure the function resolves (never rejects) with
* `{ updateAvailable: false, latestVersion: currentVersion }`.
*/
export async function checkForUpdate(currentVersion) {
const fail = {
currentVersion,
latestVersion: currentVersion,
updateAvailable: false,
};
try {
logger.debug("[UpdateChecker] Checking for updates", { currentVersion });
const { stdout } = await execFile("npm", ["view", "@juspay/neurolink", "version", "--json"], { timeout: NPM_VIEW_TIMEOUT_MS });
// `npm view ... --json` wraps the value in double-quotes, e.g. `"9.32.0"`
const parsed = JSON.parse(stdout);
if (typeof parsed !== "string") {
logger.warn("[UpdateChecker] Unexpected npm output type", {
type: typeof parsed,
});
return fail;
}
const latestVersion = parsed.trim();
if (!parseSemVer(latestVersion)) {
logger.warn("[UpdateChecker] Failed to parse latest version", {
latestVersion,
});
return fail;
}
const updateAvailable = isNewerVersion(currentVersion, latestVersion);
logger.debug("[UpdateChecker] Version check complete", {
currentVersion,
latestVersion,
updateAvailable,
});
return { currentVersion, latestVersion, updateAvailable };
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
logger.warn("[UpdateChecker] Update check failed", { error: message });
return fail;
}
}