{
  "version": 3,
  "sources": ["../../../../src/packages/fs.indexed-pkg-importer/index.ts"],
  "sourcesContent": ["import assert from 'node:assert';\nimport { constants, type Stats, existsSync } from 'node:fs';\nimport util from 'node:util';\nimport fs from '../graceful-fs/index.ts';\nimport path from 'node:path';\nimport { globalInfo, globalWarn } from '../logger/index.ts';\nimport { packageImportMethodLogger } from '../core-loggers/index.ts';\nimport type {\n  FilesMap,\n  ImportOptions,\n  ImportIndexedPackage,\n} from '../store-controller-types/index.ts';\nimport { importIndexedDir, type ImportFile } from './importIndexedDir.ts';\nimport { reflinkFileSync } from '@reflink/reflink';\n\nexport type { FilesMap, ImportOptions, ImportIndexedPackage };\n\nexport type PackageImportMethod =\n  | 'auto'\n  | 'hardlink'\n  | 'copy'\n  | 'clone'\n  | 'clone-or-copy';\n\nexport function createIndexedPkgImporter(\n  packageImportMethod?: PackageImportMethod\n): ImportIndexedPackage {\n  const importPackage = createImportPackage(packageImportMethod);\n  return importPackage;\n}\n\nfunction createImportPackage(\n  packageImportMethod?: PackageImportMethod\n): ImportIndexedPackage {\n  // this works in the following way:\n  // - hardlink: hardlink the packages, no fallback\n  // - clone: clone the packages, no fallback\n  // - auto: try to clone or hardlink the packages, if it fails, fallback to copy\n  // - copy: copy the packages, do not try to link them first\n  switch (packageImportMethod ?? 'auto') {\n    case 'clone': {\n      packageImportMethodLogger.debug({ method: 'clone' });\n      return clonePkg.bind(null, createCloneFunction());\n    }\n\n    case 'hardlink': {\n      packageImportMethodLogger.debug({ method: 'hardlink' });\n      return hardlinkPkg.bind(null, linkOrCopy);\n    }\n\n    case 'auto': {\n      return createAutoImporter();\n    }\n\n    case 'clone-or-copy': {\n      return createCloneOrCopyImporter();\n    }\n\n    case 'copy': {\n      packageImportMethodLogger.debug({ method: 'copy' });\n      return copyPkg;\n    }\n\n    default: {\n      throw new Error(\n        `Unknown package import method ${packageImportMethod as string}`\n      );\n    }\n  }\n}\n\nfunction createAutoImporter(): ImportIndexedPackage {\n  let auto = initialAuto;\n\n  return (to, opts) => auto(to, opts);\n\n  function initialAuto(to: string, opts: ImportOptions): string | undefined {\n    // Although reflinks are supported on Windows Dev Drives,\n    // they are 10x slower than hard links.\n    // Hence, we prefer reflinks by default only on Linux and macOS.\n    if (process.platform !== 'win32') {\n      try {\n        const _clonePkg = clonePkg.bind(null, createCloneFunction());\n        if (!_clonePkg(to, opts)) return undefined;\n        packageImportMethodLogger.debug({ method: 'clone' });\n        auto = _clonePkg;\n        return 'clone';\n      } catch {\n        // ignore\n      }\n    }\n    try {\n      if (!hardlinkPkg(fs.linkSync, to, opts)) {\n        return undefined;\n      }\n\n      packageImportMethodLogger.debug({ method: 'hardlink' });\n\n      auto = hardlinkPkg.bind(null, linkOrCopy);\n\n      return 'hardlink';\n    } catch (err: unknown) {\n      assert(util.types.isNativeError(err));\n      if (err.message.startsWith('EXDEV: cross-device link not permitted')) {\n        globalWarn(err.message);\n        globalInfo('Falling back to copying packages from store');\n        packageImportMethodLogger.debug({ method: 'copy' });\n        auto = copyPkg;\n        return auto(to, opts);\n      }\n      // We still choose hard linking that will fall back to copying in edge cases.\n      packageImportMethodLogger.debug({ method: 'hardlink' });\n      auto = hardlinkPkg.bind(null, linkOrCopy);\n      return auto(to, opts);\n    }\n  }\n}\n\nfunction createCloneOrCopyImporter(): ImportIndexedPackage {\n  let auto = initialAuto;\n\n  return (to, opts) => auto(to, opts);\n\n  function initialAuto(to: string, opts: ImportOptions): string | undefined {\n    try {\n      const _clonePkg = clonePkg.bind(null, createCloneFunction());\n      if (!_clonePkg(to, opts)) return undefined;\n      packageImportMethodLogger.debug({ method: 'clone' });\n      auto = _clonePkg;\n      return 'clone';\n    } catch {\n      // ignore\n    }\n    packageImportMethodLogger.debug({ method: 'copy' });\n    auto = copyPkg;\n    return auto(to, opts);\n  }\n}\n\ntype CloneFunction = (src: string, dest: string) => void;\n\nfunction clonePkg(\n  clone: CloneFunction,\n  to: string,\n  opts: ImportOptions\n): 'clone' | undefined {\n  const pkgJsonPath = path.join(to, 'package.json');\n\n  if (opts.resolvedFrom !== 'store' || opts.force || !existsSync(pkgJsonPath)) {\n    importIndexedDir(clone, to, opts.filesMap, opts);\n    return 'clone';\n  }\n\n  return undefined;\n}\n\nfunction createCloneFunction(): CloneFunction {\n  // Node.js currently does not natively support reflinks on Windows and macOS.\n  // Hence, we use a third party solution.\n  if (process.platform === 'darwin' || process.platform === 'win32') {\n    return (fr, to) => {\n      try {\n        reflinkFileSync(fr, to);\n      } catch (err: unknown) {\n        // If the file already exists, then we just proceed.\n        // This will probably only happen if the package's index file contains the same file twice.\n        // For instance: { \"index.js\": \"hash\", \"./index.js\": \"hash\" }\n        if (\n          !util.types.isNativeError(err) ||\n          !('code' in err) ||\n          err.code !== 'EEXIST'\n        )\n          throw err;\n      }\n    };\n  }\n  return (src: string, dest: string) => {\n    try {\n      fs.copyFileSync(src, dest, constants.COPYFILE_FICLONE_FORCE);\n    } catch (err: unknown) {\n      if (\n        !(\n          util.types.isNativeError(err) &&\n          'code' in err &&\n          err.code === 'EEXIST'\n        )\n      )\n        throw err;\n    }\n  };\n}\n\nfunction hardlinkPkg(\n  importFile: ImportFile,\n  to: string,\n  opts: ImportOptions\n): 'hardlink' | undefined {\n  if (opts.force || shouldRelinkPkg(to, opts)) {\n    importIndexedDir(importFile, to, opts.filesMap, opts);\n    return 'hardlink';\n  }\n\n  return undefined;\n}\n\nfunction shouldRelinkPkg(to: string, opts: ImportOptions): boolean {\n  if (\n    opts.disableRelinkLocalDirDeps === true &&\n    opts.resolvedFrom === 'local-dir'\n  ) {\n    try {\n      const files = fs.readdirSync(to);\n\n      return (\n        files.length === 0 ||\n        (files.length === 1 && files[0] === 'node_modules')\n      );\n    } catch {\n      return true;\n    }\n  }\n\n  return opts.resolvedFrom !== 'store' || !pkgLinkedToStore(opts.filesMap, to);\n}\n\nfunction linkOrCopy(existingPath: string, newPath: string): void {\n  try {\n    fs.linkSync(existingPath, newPath);\n  } catch (err: unknown) {\n    // If a hard link to the same file already exists\n    // then trying to copy it will make an empty file from it.\n    if (util.types.isNativeError(err) && 'code' in err && err.code === 'EEXIST')\n      return;\n    // In some VERY rare cases (1 in a thousand), hard-link creation fails on Windows.\n    // In that case, we just fall back to copying.\n    // This issue is reproducible with \"pnpm add @material-ui/icons@4.9.1\"\n    fs.copyFileSync(existingPath, newPath);\n  }\n}\n\nfunction pkgLinkedToStore(filesMap: FilesMap, to: string): boolean {\n  if (typeof filesMap['package.json'] === 'string') {\n    if (isSameFile('package.json', to, filesMap)) {\n      return true;\n    }\n  } else {\n    // An injected package might not have a package.json.\n    // This will probably only even happen in a Bit workspace.\n    const [anyFile] = Object.keys(filesMap);\n\n    if (isSameFile(anyFile ?? '', to, filesMap)) return true;\n  }\n\n  return false;\n}\n\nfunction isSameFile(\n  filename: string,\n  linkedPkgDir: string,\n  filesMap: FilesMap\n): boolean {\n  const linkedFile = path.join(linkedPkgDir, filename);\n\n  let stats0!: Stats;\n\n  try {\n    stats0 = fs.statSync(linkedFile);\n  } catch (err: unknown) {\n    if (\n      util.types.isNativeError(err) &&\n      'code' in err &&\n      err.code === 'ENOENT'\n    ) {\n      return false;\n    }\n  }\n\n  const stats1 = fs.statSync(filesMap[filename] ?? '');\n\n  if (stats0.ino === stats1.ino) {\n    return true;\n  }\n\n  globalInfo(`Relinking ${linkedPkgDir} from the store`);\n\n  return false;\n}\n\nexport function copyPkg(to: string, opts: ImportOptions): 'copy' | undefined {\n  const pkgJsonPath = path.join(to, 'package.json');\n\n  if (opts.resolvedFrom !== 'store' || opts.force || !existsSync(pkgJsonPath)) {\n    importIndexedDir(fs.copyFileSync, to, opts.filesMap, opts);\n\n    return 'copy';\n  }\n\n  return undefined;\n}\n"],
  "mappings": "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",
  "names": []
}
