jsr
Version:
jsr.io package manager for npm, yarn, pnpm and bun
311 lines • 10.5 kB
JavaScript
;
// Copyright the JSR authors. MIT license.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.styleText = exports.ExecError = exports.JsrPackage = exports.JsrPackageNameError = exports.DEBUG = void 0;
exports.setDebug = setDebug;
exports.logDebug = logDebug;
exports.fileExists = fileExists;
exports.findProjectDir = findProjectDir;
exports.prettyTime = prettyTime;
exports.timeAgo = timeAgo;
exports.exec = exec;
exports.getNewLineChars = getNewLineChars;
exports.readJson = readJson;
exports.writeJson = writeJson;
exports.readTextFile = readTextFile;
exports.writeTextFile = writeTextFile;
const path = __importStar(require("node:path"));
const fs = __importStar(require("node:fs"));
const util = __importStar(require("node:util"));
const node_child_process_1 = require("node:child_process");
exports.DEBUG = false;
function setDebug(enabled) {
exports.DEBUG = enabled;
}
function logDebug(msg) {
if (exports.DEBUG) {
console.log(msg);
}
}
const EXTRACT_REG = /^@([a-z0-9-]+)\/([a-z0-9-]+)(@(.+))?$/;
const EXTRACT_REG_PROXY = /^@jsr\/([a-z0-9-]+)__([a-z0-9-]+)(@(.+))?$/;
class JsrPackageNameError extends Error {
}
exports.JsrPackageNameError = JsrPackageNameError;
class JsrPackage {
scope;
name;
version;
constructor(scope, name, version) {
this.scope = scope;
this.name = name;
this.version = version;
}
static from(input) {
const exactMatch = input.match(EXTRACT_REG);
if (exactMatch !== null) {
const scope = exactMatch[1];
const name = exactMatch[2];
const version = exactMatch[4] ?? null;
return new JsrPackage(scope, name, version);
}
const proxyMatch = input.match(EXTRACT_REG_PROXY);
if (proxyMatch !== null) {
const scope = proxyMatch[1];
const name = proxyMatch[2];
const version = proxyMatch[4] ?? null;
return new JsrPackage(scope, name, version);
}
throw new JsrPackageNameError(`Invalid jsr package name: A jsr package name must have the format @<scope>/<name>, but got "${input}"`);
}
toNpmPackage() {
const version = this.version !== null ? `@${this.version}` : "";
return `@jsr/${this.scope}__${this.name}${version}`;
}
toString() {
const version = this.version !== null ? `@${this.version}` : "";
return `@${this.scope}/${this.name}${version}`;
}
}
exports.JsrPackage = JsrPackage;
async function fileExists(file) {
try {
const stat = await fs.promises.stat(file);
return stat.isFile();
}
catch (err) {
return false;
}
}
async function findProjectDir(cwd, dir = cwd, result = {
projectDir: cwd,
pkgManagerName: null,
pkgJsonPath: null,
root: null,
}) {
// Ensure we check for `package.json` first as this defines
// the root project location.
if (result.pkgJsonPath === null) {
const pkgJsonPath = path.join(dir, "package.json");
if (await fileExists(pkgJsonPath)) {
logDebug(`Found package.json at ${pkgJsonPath}`);
logDebug(`Setting project directory to ${dir}`);
result.projectDir = dir;
result.pkgJsonPath = pkgJsonPath;
}
}
else {
const pkgJsonPath = path.join(dir, "package.json");
if (await fileExists(pkgJsonPath)) {
const json = await readJson(pkgJsonPath);
// npm + yarn + bun workspaces
if (Array.isArray(json.workspaces)) {
result.root = dir;
} // pnpm workspaces
else if (await fileExists(path.join(dir, "pnpm-workspace.yaml"))) {
result.root = dir;
}
}
}
const npmLockfile = path.join(dir, "package-lock.json");
if (await fileExists(npmLockfile)) {
logDebug(`Detected npm from lockfile ${npmLockfile}`);
result.pkgManagerName = "npm";
return result;
}
// prefer bun.lockb over yarn.lock
// In some cases, both bun.lockb and yarn.lock can exist in the same project.
// https://bun.sh/docs/install/lockfile
const bunbLockfile = path.join(dir, "bun.lockb");
if (await fileExists(bunbLockfile)) {
logDebug(`Detected bun from lockfile ${bunbLockfile}`);
result.pkgManagerName = "bun";
return result;
}
const bunLockfile = path.join(dir, "bun.lock");
if (await fileExists(bunLockfile)) {
logDebug(`Detected bun from lockfile ${bunLockfile}`);
result.pkgManagerName = "bun";
return result;
}
const yarnLockFile = path.join(dir, "yarn.lock");
if (await fileExists(yarnLockFile)) {
logDebug(`Detected yarn from lockfile ${yarnLockFile}`);
result.pkgManagerName = "yarn";
return result;
}
const pnpmLockfile = path.join(dir, "pnpm-lock.yaml");
if (await fileExists(pnpmLockfile)) {
logDebug(`Detected pnpm from lockfile ${pnpmLockfile}`);
result.pkgManagerName = "pnpm";
return result;
}
const prev = dir;
dir = path.dirname(dir);
if (dir === prev) {
return result;
}
return findProjectDir(cwd, dir, result);
}
const PERIODS = {
year: 365 * 24 * 60 * 60 * 1000,
month: 30 * 24 * 60 * 60 * 1000,
week: 7 * 24 * 60 * 60 * 1000,
day: 24 * 60 * 60 * 1000,
hour: 60 * 60 * 1000,
minute: 60 * 1000,
seconds: 1000,
};
function prettyTime(diff) {
if (diff > PERIODS.day) {
return Math.floor(diff / PERIODS.day) + "d";
}
else if (diff > PERIODS.hour) {
return Math.floor(diff / PERIODS.hour) + "h";
}
else if (diff > PERIODS.minute) {
return Math.floor(diff / PERIODS.minute) + "m";
}
else if (diff > PERIODS.seconds) {
return Math.floor(diff / PERIODS.seconds) + "s";
}
return diff + "ms";
}
function timeAgo(diff) {
if (diff > PERIODS.year) {
const v = Math.floor(diff / PERIODS.year);
return `${v} year${v > 1 ? "s" : ""} ago`;
}
else if (diff > PERIODS.month) {
const v = Math.floor(diff / PERIODS.month);
return `${v} month${v > 1 ? "s" : ""} ago`;
}
else if (diff > PERIODS.week) {
const v = Math.floor(diff / PERIODS.week);
return `${v} week${v > 1 ? "s" : ""} ago`;
}
else if (diff > PERIODS.day) {
const v = Math.floor(diff / PERIODS.day);
return `${v} day${v > 1 ? "s" : ""} ago`;
}
else if (diff > PERIODS.hour) {
const v = Math.floor(diff / PERIODS.hour);
return `${v} hour${v > 1 ? "s" : ""} ago`;
}
else if (diff > PERIODS.minute) {
const v = Math.floor(diff / PERIODS.minute);
return `${v} minute${v > 1 ? "s" : ""} ago`;
}
else if (diff > PERIODS.seconds) {
const v = Math.floor(diff / PERIODS.seconds);
return `${v} second${v > 1 ? "s" : ""} ago`;
}
return "just now";
}
class ExecError extends Error {
code;
constructor(code) {
super(`Child process exited with: ${code}`);
this.code = code;
}
}
exports.ExecError = ExecError;
async function exec(cmd, args, cwd, env, captureOutput) {
const cp = (0, node_child_process_1.spawn)(cmd, args.map((arg) => process.platform === "win32" ? `"${arg}"` : `'${arg}'`), {
stdio: captureOutput ? "pipe" : "inherit",
cwd,
shell: true,
env,
});
let combined = "";
let stdout = "";
let stderr = "";
if (captureOutput) {
cp.stdout?.on("data", (data) => {
combined += data;
stdout += data;
});
cp.stderr?.on("data", (data) => {
combined += data;
stderr += data;
});
}
return new Promise((resolve, reject) => {
cp.on("exit", (code) => {
if (code === 0) {
resolve({ combined, stdout, stderr });
}
else {
console.log(`Command: ${cmd} ${args.join(" ")}`);
console.log(`CWD: ${cwd}`);
console.log(`Output: ${combined}`);
reject(new ExecError(code ?? 1));
}
});
});
}
function getNewLineChars(source) {
var temp = source.indexOf("\n");
if (source[temp - 1] === "\r") {
return "\r\n";
}
return "\n";
}
async function readJson(file) {
const content = await fs.promises.readFile(file, "utf-8");
return JSON.parse(content);
}
async function writeJson(file, data) {
try {
await fs.promises.mkdir(path.dirname(file), { recursive: true });
}
catch (_) { }
await fs.promises.writeFile(file, JSON.stringify(data, null, 2), "utf-8");
}
async function readTextFile(file) {
return fs.promises.readFile(file, "utf-8");
}
async function writeTextFile(file, content) {
try {
await fs.promises.mkdir(path.dirname(file), { recursive: true });
}
catch (_) { }
await fs.promises.writeFile(file, content, "utf-8");
}
exports.styleText = typeof util.styleText === "function"
? util.styleText
: (_style, text) => text;
//# sourceMappingURL=utils.js.map