+44
-4
@@ -11,3 +11,3 @@ #!/usr/bin/env node | ||
| var name = "nypm"; | ||
| var version = "0.6.6"; | ||
| var version = "0.6.7"; | ||
| var description = "Unified Package Manager for Node.js"; | ||
@@ -26,2 +26,6 @@ const packageManagers = [ | ||
| { | ||
| name: "nub", | ||
| command: "nub" | ||
| }, | ||
| { | ||
| name: "pnpm", | ||
@@ -73,2 +77,17 @@ command: "pnpm", | ||
| } | ||
| const devEngines = parseDevEnginesPackageManager(packageJSON?.devEngines); | ||
| if (devEngines.name) { | ||
| const { name, version, warnings } = devEngines; | ||
| const majorVersion = version?.match(/\d+/)?.[0]; | ||
| const packageManager = packageManagers.find((pm) => pm.name === name && pm.majorVersion === majorVersion) || packageManagers.find((pm) => pm.name === name); | ||
| return { | ||
| name, | ||
| command: name, | ||
| version, | ||
| majorVersion, | ||
| warnings, | ||
| files: packageManager?.files, | ||
| lockFile: packageManager?.lockFile | ||
| }; | ||
| } | ||
| } | ||
@@ -144,3 +163,3 @@ if (existsSync(join(path, "deno.json"))) return packageManagers.find((pm) => pm.name === "deno"); | ||
| async function executeCommand(command, args, options = {}) { | ||
| const xArgs = command !== "npm" && command !== "bun" && command !== "deno" && command !== "aube" && options.corepack !== false && await hasCorepack() ? ["corepack", [command, ...args]] : [command, args]; | ||
| const xArgs = command !== "npm" && command !== "bun" && command !== "deno" && command !== "aube" && command !== "nub" && options.corepack !== false && await hasCorepack() ? ["corepack", [command, ...args]] : [command, args]; | ||
| const { exitCode, stdout, stderr } = await x(xArgs[0], xArgs[1], { nodeOptions: { | ||
@@ -187,6 +206,7 @@ cwd: resolve(options.cwd || process.cwd()), | ||
| } | ||
| const VALID_PM_NAME_RE = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/; | ||
| function parsePackageManagerField(packageManager) { | ||
| const [name, _version] = (packageManager || "").split("@"); | ||
| const [version, buildMeta] = _version?.split("+") || []; | ||
| if (name && name !== "-" && /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(name)) return { | ||
| if (name && name !== "-" && VALID_PM_NAME_RE.test(name)) return { | ||
| name, | ||
@@ -204,2 +224,21 @@ version, | ||
| } | ||
| function parseDevEnginesPackageManager(devEngines) { | ||
| const field = devEngines?.packageManager; | ||
| const entry = Array.isArray(field) ? field[0] : field; | ||
| const name = typeof entry?.name === "string" ? entry.name : void 0; | ||
| const version = typeof entry?.version === "string" ? entry.version : void 0; | ||
| if (!name) return {}; | ||
| if (!VALID_PM_NAME_RE.test(name)) { | ||
| const sanitized = name.replace(/\W+/g, ""); | ||
| return { | ||
| name: sanitized, | ||
| version, | ||
| warnings: [`Abnormal characters found in \`devEngines.packageManager\` field, sanitizing from \`${name}\` to \`${sanitized}\``] | ||
| }; | ||
| } | ||
| return { | ||
| name, | ||
| version | ||
| }; | ||
| } | ||
| async function installDependencies(options = {}) { | ||
@@ -213,3 +252,4 @@ const resolvedOptions = await resolveOperationOptions(options); | ||
| deno: ["install", "--frozen"], | ||
| aube: ["install", "--frozen-lockfile"] | ||
| aube: ["install", "--frozen-lockfile"], | ||
| nub: ["install", "--frozen-lockfile"] | ||
| }[resolvedOptions.packageManager.name] : ["install"]; | ||
@@ -216,0 +256,0 @@ if (options.ignoreWorkspace && resolvedOptions.packageManager.name === "pnpm") commandArgs.push("--ignore-workspace"); |
+4
-2
@@ -1,2 +0,2 @@ | ||
| type PackageManagerName = "npm" | "yarn" | "pnpm" | "bun" | "deno" | "aube"; | ||
| type PackageManagerName = "npm" | "yarn" | "pnpm" | "bun" | "deno" | "aube" | "nub"; | ||
| type PackageManager = { | ||
@@ -59,3 +59,5 @@ name: PackageManagerName; | ||
| * | ||
| * 2. Known lock files and other files | ||
| * 2. Use `devEngines.packageManager` field from package.json | ||
| * | ||
| * 3. Known lock files and other files | ||
| */ | ||
@@ -62,0 +64,0 @@ declare function detectPackageManager(cwd: string, options?: DetectPackageManagerOptions): Promise<(PackageManager & { |
+48
-6
@@ -63,3 +63,3 @@ import { createRequire } from "node:module"; | ||
| async function executeCommand(command, args, options = {}) { | ||
| const xArgs = command !== "npm" && command !== "bun" && command !== "deno" && command !== "aube" && options.corepack !== false && await hasCorepack() ? ["corepack", [command, ...args]] : [command, args]; | ||
| const xArgs = command !== "npm" && command !== "bun" && command !== "deno" && command !== "aube" && command !== "nub" && options.corepack !== false && await hasCorepack() ? ["corepack", [command, ...args]] : [command, args]; | ||
| const { exitCode, stdout, stderr } = await x(xArgs[0], xArgs[1], { nodeOptions: { | ||
@@ -126,6 +126,7 @@ cwd: resolve(options.cwd || process.cwd()), | ||
| } | ||
| const VALID_PM_NAME_RE = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/; | ||
| function parsePackageManagerField(packageManager) { | ||
| const [name, _version] = (packageManager || "").split("@"); | ||
| const [version, buildMeta] = _version?.split("+") || []; | ||
| if (name && name !== "-" && /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(name)) return { | ||
| if (name && name !== "-" && VALID_PM_NAME_RE.test(name)) return { | ||
| name, | ||
@@ -143,2 +144,21 @@ version, | ||
| } | ||
| function parseDevEnginesPackageManager(devEngines) { | ||
| const field = devEngines?.packageManager; | ||
| const entry = Array.isArray(field) ? field[0] : field; | ||
| const name = typeof entry?.name === "string" ? entry.name : void 0; | ||
| const version = typeof entry?.version === "string" ? entry.version : void 0; | ||
| if (!name) return {}; | ||
| if (!VALID_PM_NAME_RE.test(name)) { | ||
| const sanitized = name.replace(/\W+/g, ""); | ||
| return { | ||
| name: sanitized, | ||
| version, | ||
| warnings: [`Abnormal characters found in \`devEngines.packageManager\` field, sanitizing from \`${name}\` to \`${sanitized}\``] | ||
| }; | ||
| } | ||
| return { | ||
| name, | ||
| version | ||
| }; | ||
| } | ||
| const packageManagers = [ | ||
@@ -156,2 +176,6 @@ { | ||
| { | ||
| name: "nub", | ||
| command: "nub" | ||
| }, | ||
| { | ||
| name: "pnpm", | ||
@@ -203,2 +227,17 @@ command: "pnpm", | ||
| } | ||
| const devEngines = parseDevEnginesPackageManager(packageJSON?.devEngines); | ||
| if (devEngines.name) { | ||
| const { name, version, warnings } = devEngines; | ||
| const majorVersion = version?.match(/\d+/)?.[0]; | ||
| const packageManager = packageManagers.find((pm) => pm.name === name && pm.majorVersion === majorVersion) || packageManagers.find((pm) => pm.name === name); | ||
| return { | ||
| name, | ||
| command: name, | ||
| version, | ||
| majorVersion, | ||
| warnings, | ||
| files: packageManager?.files, | ||
| lockFile: packageManager?.lockFile | ||
| }; | ||
| } | ||
| } | ||
@@ -227,3 +266,4 @@ if (existsSync(join(path, "deno.json"))) return packageManagers.find((pm) => pm.name === "deno"); | ||
| deno: [installCmd, "--frozen"], | ||
| aube: [installCmd, "--frozen-lockfile"] | ||
| aube: [installCmd, "--frozen-lockfile"], | ||
| nub: [installCmd, "--frozen-lockfile"] | ||
| }; | ||
@@ -252,3 +292,3 @@ return fmtCommand([packageManager, ...options.frozenLockFile ? pmToFrozenLockfileInstallCommand[packageManager] : [installCmd]]); | ||
| }), | ||
| options.dev ? options.short ? "-D" : packageManager === "aube" ? "--save-dev" : "--dev" : "", | ||
| options.dev ? options.short ? "-D" : packageManager === "aube" || packageManager === "nub" ? "--save-dev" : "--dev" : "", | ||
| options.global ? "-g" : "", | ||
@@ -272,3 +312,4 @@ ...names | ||
| deno: "deno run -A", | ||
| aube: options.short ? "aubx" : "aube dlx" | ||
| aube: options.short ? "aubx" : "aube dlx", | ||
| nub: options.short ? "nubx" : "nub dlx" | ||
| }[packageManager]; | ||
@@ -302,3 +343,4 @@ let packages = options.packages || []; | ||
| deno: ["install", "--frozen"], | ||
| aube: ["install", "--frozen-lockfile"] | ||
| aube: ["install", "--frozen-lockfile"], | ||
| nub: ["install", "--frozen-lockfile"] | ||
| }[resolvedOptions.packageManager.name] : ["install"]; | ||
@@ -305,0 +347,0 @@ if (options.ignoreWorkspace && resolvedOptions.packageManager.name === "pnpm") commandArgs.push("--ignore-workspace"); |
+9
-9
| { | ||
| "name": "nypm", | ||
| "version": "0.6.7", | ||
| "version": "0.6.8", | ||
| "description": "Unified Package Manager for Node.js", | ||
@@ -29,12 +29,12 @@ "license": "MIT", | ||
| "devDependencies": { | ||
| "@types/node": "^25.9.2", | ||
| "@typescript/native-preview": "7.0.0-dev.20260609.1", | ||
| "@vitest/coverage-v8": "^4.1.8", | ||
| "@types/node": "^26.0.1", | ||
| "@typescript/native-preview": "7.0.0-dev.20260627.2", | ||
| "@vitest/coverage-v8": "^4.1.9", | ||
| "automd": "^0.4.3", | ||
| "changelogen": "^0.6.2", | ||
| "eslint-config-unjs": "^0.6.2", | ||
| "expect-type": "^1.3.0", | ||
| "obuild": "^0.4.36", | ||
| "oxfmt": "^0.54.0", | ||
| "oxlint": "^1.69.0", | ||
| "expect-type": "^1.4.0", | ||
| "obuild": "^0.4.37", | ||
| "oxfmt": "^0.56.0", | ||
| "oxlint": "^1.71.0", | ||
| "pkg-types": "^2.3.1", | ||
@@ -44,3 +44,3 @@ "std-env": "^4.1.0", | ||
| "ufo": "^1.6.4", | ||
| "vitest": "^4.1.8" | ||
| "vitest": "^4.1.9" | ||
| }, | ||
@@ -47,0 +47,0 @@ "engines": { |
+3
-2
@@ -13,3 +13,3 @@ # 🌈 nypm | ||
| ✅ Supports [npm](https://docs.npmjs.com/cli/v10/commands/npm), [yarn](https://yarnpkg.com/), [pnpm](https://pnpm.io/), [bun](https://bun.sh/package-manager), [deno](https://deno.com/) and [aube](https://github.com/jdx/aube) out of the box with a unified API. | ||
| ✅ Supports [npm](https://docs.npmjs.com/cli/v10/commands/npm), [yarn](https://yarnpkg.com/), [pnpm](https://pnpm.io/), [bun](https://bun.sh/package-manager), [deno](https://deno.com/), [aube](https://github.com/jdx/aube) and [nub](https://github.com/nubjs/nub) out of the box with a unified API. | ||
@@ -74,3 +74,4 @@ ✅ Provides an **API interface** to interact with package managers. | ||
| 1. Use `packageManager` field from package.json | ||
| 2. Known lock files and other files | ||
| 2. Use [`devEngines.packageManager`](https://docs.npmjs.com/cli/v11/configuring-npm/package-json#devengines) field from package.json | ||
| 3. Known lock files and other files | ||
@@ -77,0 +78,0 @@ ### `ensureDependencyInstalled(name, options)` |
51024
6.28%1025
8.7%154
0.65%