@antfu/install-pkg
Advanced tools
Comparing version 0.3.5 to 0.4.0
@@ -1,6 +0,6 @@ | ||
import * as _jsdevtools_ez_spawn from '@jsdevtools/ez-spawn'; | ||
import { Agent } from 'package-manager-detector'; | ||
export { Agent } from 'package-manager-detector'; | ||
import * as tinyexec from 'tinyexec'; | ||
type PackageManager = 'pnpm' | 'yarn' | 'npm' | 'bun'; | ||
declare const AGENTS: readonly ["pnpm", "yarn", "npm", "pnpm@6", "yarn@berry", "bun"]; | ||
type Agent = typeof AGENTS[number]; | ||
declare function detectPackageManager(cwd?: string): Promise<Agent | null>; | ||
@@ -17,4 +17,4 @@ | ||
} | ||
declare function installPackage(names: string | string[], options?: InstallPackageOptions): Promise<_jsdevtools_ez_spawn.Process<string>>; | ||
declare function installPackage(names: string | string[], options?: InstallPackageOptions): Promise<tinyexec.Output>; | ||
export { type Agent, type InstallPackageOptions, type PackageManager, detectPackageManager, installPackage }; | ||
export { type InstallPackageOptions, type PackageManager, detectPackageManager, installPackage }; |
@@ -1,295 +0,19 @@ | ||
var __defProp = Object.defineProperty; | ||
var __typeError = (msg) => { | ||
throw TypeError(msg); | ||
}; | ||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; | ||
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); | ||
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); | ||
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); | ||
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); | ||
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value); | ||
var __privateWrapper = (obj, member, setter, getter) => ({ | ||
set _(value) { | ||
__privateSet(obj, member, value, setter); | ||
}, | ||
get _() { | ||
return __privateGet(obj, member, getter); | ||
} | ||
}); | ||
// src/detect.ts | ||
import fs2 from "fs"; | ||
import path3 from "path"; | ||
import process2 from "process"; | ||
// node_modules/.pnpm/find-up@7.0.0/node_modules/find-up/index.js | ||
import path2 from "path"; | ||
// node_modules/.pnpm/locate-path@7.2.0/node_modules/locate-path/index.js | ||
import process from "process"; | ||
import path from "path"; | ||
import fs, { promises as fsPromises } from "fs"; | ||
import { fileURLToPath } from "url"; | ||
// node_modules/.pnpm/yocto-queue@1.0.0/node_modules/yocto-queue/index.js | ||
var Node = class { | ||
constructor(value) { | ||
__publicField(this, "value"); | ||
__publicField(this, "next"); | ||
this.value = value; | ||
} | ||
}; | ||
var _head, _tail, _size; | ||
var Queue = class { | ||
constructor() { | ||
__privateAdd(this, _head); | ||
__privateAdd(this, _tail); | ||
__privateAdd(this, _size); | ||
this.clear(); | ||
} | ||
enqueue(value) { | ||
const node = new Node(value); | ||
if (__privateGet(this, _head)) { | ||
__privateGet(this, _tail).next = node; | ||
__privateSet(this, _tail, node); | ||
} else { | ||
__privateSet(this, _head, node); | ||
__privateSet(this, _tail, node); | ||
import { detect } from "package-manager-detector"; | ||
async function detectPackageManager(cwd = process.cwd()) { | ||
const result = await detect({ | ||
cwd, | ||
onUnknown(packageManager) { | ||
console.warn("[@antfu/install-pkg] Unknown packageManager:", packageManager); | ||
} | ||
__privateWrapper(this, _size)._++; | ||
} | ||
dequeue() { | ||
const current = __privateGet(this, _head); | ||
if (!current) { | ||
return; | ||
} | ||
__privateSet(this, _head, __privateGet(this, _head).next); | ||
__privateWrapper(this, _size)._--; | ||
return current.value; | ||
} | ||
clear() { | ||
__privateSet(this, _head, void 0); | ||
__privateSet(this, _tail, void 0); | ||
__privateSet(this, _size, 0); | ||
} | ||
get size() { | ||
return __privateGet(this, _size); | ||
} | ||
*[Symbol.iterator]() { | ||
let current = __privateGet(this, _head); | ||
while (current) { | ||
yield current.value; | ||
current = current.next; | ||
} | ||
} | ||
}; | ||
_head = new WeakMap(); | ||
_tail = new WeakMap(); | ||
_size = new WeakMap(); | ||
// node_modules/.pnpm/p-limit@4.0.0/node_modules/p-limit/index.js | ||
function pLimit(concurrency) { | ||
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) { | ||
throw new TypeError("Expected `concurrency` to be a number from 1 and up"); | ||
} | ||
const queue = new Queue(); | ||
let activeCount = 0; | ||
const next = () => { | ||
activeCount--; | ||
if (queue.size > 0) { | ||
queue.dequeue()(); | ||
} | ||
}; | ||
const run = async (fn, resolve2, args) => { | ||
activeCount++; | ||
const result = (async () => fn(...args))(); | ||
resolve2(result); | ||
try { | ||
await result; | ||
} catch { | ||
} | ||
next(); | ||
}; | ||
const enqueue = (fn, resolve2, args) => { | ||
queue.enqueue(run.bind(void 0, fn, resolve2, args)); | ||
(async () => { | ||
await Promise.resolve(); | ||
if (activeCount < concurrency && queue.size > 0) { | ||
queue.dequeue()(); | ||
} | ||
})(); | ||
}; | ||
const generator = (fn, ...args) => new Promise((resolve2) => { | ||
enqueue(fn, resolve2, args); | ||
}); | ||
Object.defineProperties(generator, { | ||
activeCount: { | ||
get: () => activeCount | ||
}, | ||
pendingCount: { | ||
get: () => queue.size | ||
}, | ||
clearQueue: { | ||
value: () => { | ||
queue.clear(); | ||
} | ||
} | ||
}); | ||
return generator; | ||
return result?.agent || null; | ||
} | ||
// node_modules/.pnpm/p-locate@6.0.0/node_modules/p-locate/index.js | ||
var EndError = class extends Error { | ||
constructor(value) { | ||
super(); | ||
this.value = value; | ||
} | ||
}; | ||
var testElement = async (element, tester) => tester(await element); | ||
var finder = async (element) => { | ||
const values = await Promise.all(element); | ||
if (values[1] === true) { | ||
throw new EndError(values[0]); | ||
} | ||
return false; | ||
}; | ||
async function pLocate(iterable, tester, { | ||
concurrency = Number.POSITIVE_INFINITY, | ||
preserveOrder = true | ||
} = {}) { | ||
const limit = pLimit(concurrency); | ||
const items = [...iterable].map((element) => [element, limit(testElement, element, tester)]); | ||
const checkLimit = pLimit(preserveOrder ? 1 : Number.POSITIVE_INFINITY); | ||
try { | ||
await Promise.all(items.map((element) => checkLimit(finder, element))); | ||
} catch (error) { | ||
if (error instanceof EndError) { | ||
return error.value; | ||
} | ||
throw error; | ||
} | ||
} | ||
// node_modules/.pnpm/locate-path@7.2.0/node_modules/locate-path/index.js | ||
var typeMappings = { | ||
directory: "isDirectory", | ||
file: "isFile" | ||
}; | ||
function checkType(type) { | ||
if (Object.hasOwnProperty.call(typeMappings, type)) { | ||
return; | ||
} | ||
throw new Error(`Invalid type specified: ${type}`); | ||
} | ||
var matchType = (type, stat) => stat[typeMappings[type]](); | ||
var toPath = (urlOrPath) => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath; | ||
async function locatePath(paths, { | ||
cwd = process.cwd(), | ||
type = "file", | ||
allowSymlinks = true, | ||
concurrency, | ||
preserveOrder | ||
} = {}) { | ||
checkType(type); | ||
cwd = toPath(cwd); | ||
const statFunction = allowSymlinks ? fsPromises.stat : fsPromises.lstat; | ||
return pLocate(paths, async (path_) => { | ||
try { | ||
const stat = await statFunction(path.resolve(cwd, path_)); | ||
return matchType(type, stat); | ||
} catch { | ||
return false; | ||
} | ||
}, { concurrency, preserveOrder }); | ||
} | ||
// node_modules/.pnpm/unicorn-magic@0.1.0/node_modules/unicorn-magic/node.js | ||
import { fileURLToPath as fileURLToPath2 } from "url"; | ||
function toPath2(urlOrPath) { | ||
return urlOrPath instanceof URL ? fileURLToPath2(urlOrPath) : urlOrPath; | ||
} | ||
// node_modules/.pnpm/find-up@7.0.0/node_modules/find-up/index.js | ||
var findUpStop = Symbol("findUpStop"); | ||
async function findUpMultiple(name, options = {}) { | ||
let directory = path2.resolve(toPath2(options.cwd) ?? ""); | ||
const { root } = path2.parse(directory); | ||
const stopAt = path2.resolve(directory, toPath2(options.stopAt ?? root)); | ||
const limit = options.limit ?? Number.POSITIVE_INFINITY; | ||
const paths = [name].flat(); | ||
const runMatcher = async (locateOptions) => { | ||
if (typeof name !== "function") { | ||
return locatePath(paths, locateOptions); | ||
} | ||
const foundPath = await name(locateOptions.cwd); | ||
if (typeof foundPath === "string") { | ||
return locatePath([foundPath], locateOptions); | ||
} | ||
return foundPath; | ||
}; | ||
const matches = []; | ||
while (true) { | ||
const foundPath = await runMatcher({ ...options, cwd: directory }); | ||
if (foundPath === findUpStop) { | ||
break; | ||
} | ||
if (foundPath) { | ||
matches.push(path2.resolve(directory, foundPath)); | ||
} | ||
if (directory === stopAt || matches.length >= limit) { | ||
break; | ||
} | ||
directory = path2.dirname(directory); | ||
} | ||
return matches; | ||
} | ||
async function findUp(name, options = {}) { | ||
const matches = await findUpMultiple(name, { ...options, limit: 1 }); | ||
return matches[0]; | ||
} | ||
// src/detect.ts | ||
var AGENTS = ["pnpm", "yarn", "npm", "pnpm@6", "yarn@berry", "bun"]; | ||
var LOCKS = { | ||
"bun.lockb": "bun", | ||
"pnpm-lock.yaml": "pnpm", | ||
"yarn.lock": "yarn", | ||
"package-lock.json": "npm", | ||
"npm-shrinkwrap.json": "npm" | ||
}; | ||
async function detectPackageManager(cwd = process2.cwd()) { | ||
let agent = null; | ||
const lockPath = await findUp(Object.keys(LOCKS), { cwd }); | ||
let packageJsonPath; | ||
if (lockPath) | ||
packageJsonPath = path3.resolve(lockPath, "../package.json"); | ||
else | ||
packageJsonPath = await findUp("package.json", { cwd }); | ||
if (packageJsonPath && fs2.existsSync(packageJsonPath)) { | ||
try { | ||
const pkg = JSON.parse(fs2.readFileSync(packageJsonPath, "utf8")); | ||
if (typeof pkg.packageManager === "string") { | ||
const [name, version] = pkg.packageManager.split("@"); | ||
if (name === "yarn" && Number.parseInt(version) > 1) | ||
agent = "yarn@berry"; | ||
else if (name === "pnpm" && Number.parseInt(version) < 7) | ||
agent = "pnpm@6"; | ||
else if (AGENTS.includes(name)) | ||
agent = name; | ||
else | ||
console.warn("[ni] Unknown packageManager:", pkg.packageManager); | ||
} | ||
} catch { | ||
} | ||
} | ||
if (!agent && lockPath) | ||
agent = LOCKS[path3.basename(lockPath)]; | ||
return agent; | ||
} | ||
// src/install.ts | ||
import { existsSync } from "fs"; | ||
import process3 from "process"; | ||
import process2 from "process"; | ||
import { resolve } from "path"; | ||
import { async as ezspawn } from "@jsdevtools/ez-spawn"; | ||
import { x } from "tinyexec"; | ||
async function installPackage(names, options = {}) { | ||
@@ -307,5 +31,5 @@ const detectedAgent = options.packageManager || await detectPackageManager(options.cwd) || "npm"; | ||
} | ||
if (agent === "pnpm" && existsSync(resolve(options.cwd ?? process3.cwd(), "pnpm-workspace.yaml"))) | ||
if (agent === "pnpm" && existsSync(resolve(options.cwd ?? process2.cwd(), "pnpm-workspace.yaml"))) | ||
args.unshift("-w"); | ||
return ezspawn( | ||
return x( | ||
agent, | ||
@@ -319,4 +43,6 @@ [ | ||
{ | ||
stdio: options.silent ? "ignore" : "inherit", | ||
cwd: options.cwd | ||
nodeOptions: { | ||
stdio: options.silent ? "ignore" : "inherit", | ||
cwd: options.cwd | ||
} | ||
} | ||
@@ -323,0 +49,0 @@ ); |
{ | ||
"name": "@antfu/install-pkg", | ||
"type": "module", | ||
"version": "0.3.5", | ||
"version": "0.4.0", | ||
"description": "Install package programmatically.", | ||
@@ -38,12 +38,12 @@ "author": "Anthony Fu <anthonyfu117@hotmail.com>", | ||
"dependencies": { | ||
"@jsdevtools/ez-spawn": "^3.0.4" | ||
"package-manager-detector": "^0.1.1", | ||
"tinyexec": "^0.2.0" | ||
}, | ||
"devDependencies": { | ||
"@antfu/eslint-config": "^2.25.1", | ||
"@antfu/eslint-config": "^2.26.0", | ||
"@antfu/ni": "^0.22.4", | ||
"@types/node": "^22.3.0", | ||
"@types/node": "^22.4.1", | ||
"bumpp": "^9.5.1", | ||
"eslint": "^9.9.0", | ||
"esno": "^4.7.0", | ||
"find-up": "^7.0.0", | ||
"publint": "^0.2.10", | ||
@@ -50,0 +50,0 @@ "tsup": "^8.2.4", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
9
2
9432
2
154
1
+ Addedtinyexec@^0.2.0
+ Addedpackage-manager-detector@0.1.2(transitive)
+ Addedtinyexec@0.2.0(transitive)
- Removed@jsdevtools/ez-spawn@^3.0.4
- Removed@jsdevtools/ez-spawn@3.0.4(transitive)
- Removedcall-me-maybe@1.0.2(transitive)
- Removedcross-spawn@7.0.5(transitive)
- Removedisexe@2.0.0(transitive)
- Removedpath-key@3.1.1(transitive)
- Removedshebang-command@2.0.0(transitive)
- Removedshebang-regex@3.0.0(transitive)
- Removedstring-argv@0.3.2(transitive)
- Removedtype-detect@4.1.0(transitive)
- Removedwhich@2.0.2(transitive)