UNPKG

@pnpm/directory-fetcher

Version:
125 lines 5.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.createDirectoryFetcher = createDirectoryFetcher; exports.fetchFromDir = fetchFromDir; const fs_1 = require("fs"); const path_1 = __importDefault(require("path")); const util_1 = __importDefault(require("util")); const exec_pkg_requires_build_1 = require("@pnpm/exec.pkg-requires-build"); const logger_1 = require("@pnpm/logger"); const fs_packlist_1 = require("@pnpm/fs.packlist"); const read_project_manifest_1 = require("@pnpm/read-project-manifest"); const directoryFetcherLogger = (0, logger_1.logger)('directory-fetcher'); function createDirectoryFetcher(opts) { const readFileStat = opts?.resolveSymlinks === true ? realFileStat : fileStat; const fetchFromDir = opts?.includeOnlyPackageFiles ? fetchPackageFilesFromDir : fetchAllFilesFromDir.bind(null, readFileStat); const directoryFetcher = (cafs, resolution, opts) => { const dir = path_1.default.join(opts.lockfileDir, resolution.directory); return fetchFromDir(dir); }; return { directory: directoryFetcher, }; } async function fetchFromDir(dir, opts) { if (opts.includeOnlyPackageFiles) { return fetchPackageFilesFromDir(dir); } const readFileStat = opts?.resolveSymlinks === true ? realFileStat : fileStat; return fetchAllFilesFromDir(readFileStat, dir); } async function fetchAllFilesFromDir(readFileStat, dir) { const { filesIndex, filesStats } = await _fetchAllFilesFromDir(readFileStat, dir); // In a regular pnpm workspace it will probably never happen that a dependency has no package.json file. // Safe read was added to support the Bit workspace in which the components have no package.json files. // Related PR in Bit: https://github.com/teambit/bit/pull/5251 const manifest = await (0, read_project_manifest_1.safeReadProjectManifestOnly)(dir) ?? undefined; const requiresBuild = (0, exec_pkg_requires_build_1.pkgRequiresBuild)(manifest, filesIndex); return { local: true, filesIndex, filesStats, packageImportMethod: 'hardlink', manifest, requiresBuild, }; } async function _fetchAllFilesFromDir(readFileStat, dir, relativeDir = '') { const filesIndex = {}; const filesStats = {}; const files = await fs_1.promises.readdir(dir); await Promise.all(files .filter((file) => file !== 'node_modules') .map(async (file) => { const fileStatResult = await readFileStat(path_1.default.join(dir, file)); if (!fileStatResult) return; const { filePath, stat } = fileStatResult; const relativeSubdir = `${relativeDir}${relativeDir ? '/' : ''}${file}`; if (stat.isDirectory()) { const subFetchResult = await _fetchAllFilesFromDir(readFileStat, filePath, relativeSubdir); Object.assign(filesIndex, subFetchResult.filesIndex); Object.assign(filesStats, subFetchResult.filesStats); } else { filesIndex[relativeSubdir] = filePath; filesStats[relativeSubdir] = fileStatResult.stat; } })); return { filesIndex, filesStats }; } async function realFileStat(filePath) { let stat = await fs_1.promises.lstat(filePath); if (!stat.isSymbolicLink()) { return { filePath, stat }; } try { filePath = await fs_1.promises.realpath(filePath); stat = await fs_1.promises.stat(filePath); return { filePath, stat }; } catch (err) { // Broken symlinks are skipped if (util_1.default.types.isNativeError(err) && 'code' in err && err.code === 'ENOENT') { directoryFetcherLogger.debug({ brokenSymlink: filePath }); return null; } throw err; } } async function fileStat(filePath) { try { return { filePath, stat: await fs_1.promises.stat(filePath), }; } catch (err) { // Broken symlinks are skipped if (util_1.default.types.isNativeError(err) && 'code' in err && err.code === 'ENOENT') { directoryFetcherLogger.debug({ brokenSymlink: filePath }); return null; } throw err; } } async function fetchPackageFilesFromDir(dir) { const files = await (0, fs_packlist_1.packlist)(dir); const filesIndex = Object.fromEntries(files.map((file) => [file, path_1.default.join(dir, file)])); // In a regular pnpm workspace it will probably never happen that a dependency has no package.json file. // Safe read was added to support the Bit workspace in which the components have no package.json files. // Related PR in Bit: https://github.com/teambit/bit/pull/5251 const manifest = await (0, read_project_manifest_1.safeReadProjectManifestOnly)(dir) ?? undefined; const requiresBuild = (0, exec_pkg_requires_build_1.pkgRequiresBuild)(manifest, filesIndex); return { local: true, filesIndex, packageImportMethod: 'hardlink', manifest, requiresBuild, }; } //# sourceMappingURL=index.js.map