UNPKG

@pnpm/package-bins

Version:
62 lines 2.26 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getBinsFromPackageManifest = getBinsFromPackageManifest; const path_1 = __importDefault(require("path")); const tinyglobby_1 = require("tinyglobby"); const is_subdir_1 = __importDefault(require("is-subdir")); async function getBinsFromPackageManifest(manifest, pkgPath) { if (manifest.bin) { return commandsFromBin(manifest.bin, manifest.name, pkgPath); } if (manifest.directories?.bin) { const binDir = path_1.default.join(pkgPath, manifest.directories.bin); // Validate: directories.bin must be within the package root if (!(0, is_subdir_1.default)(pkgPath, binDir)) { return []; } const files = await findFiles(binDir); return files.map((file) => ({ name: path_1.default.basename(file), path: path_1.default.join(binDir, file), })); } return []; } async function findFiles(dir) { try { return await (0, tinyglobby_1.glob)('**', { cwd: dir, onlyFiles: true, followSymbolicLinks: false, expandDirectories: false, }); } catch (err) { // eslint-disable-line if (err.code !== 'ENOENT') { throw err; } return []; } } function commandsFromBin(bin, pkgName, pkgPath) { const cmds = []; for (const [commandName, binRelativePath] of typeof bin === 'string' ? [[pkgName, bin]] : Object.entries(bin)) { const binName = commandName[0] === '@' ? commandName.slice(commandName.indexOf('/') + 1) : commandName; // Validate: must be safe (no path traversal) - only allow URL-safe chars or $ if (binName !== encodeURIComponent(binName) && binName !== '$') { continue; } const binPath = path_1.default.join(pkgPath, binRelativePath); if (!(0, is_subdir_1.default)(pkgPath, binPath)) { continue; } cmds.push({ name: binName, path: binPath }); } return cmds; } //# sourceMappingURL=index.js.map