| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 | 'use strict'const path = require('path')const fs = require('graceful-fs')const pathExists = require('../path-exists').pathExists/** * Function that returns two types of paths, one relative to symlink, and one * relative to the current working directory. Checks if path is absolute or * relative. If the path is relative, this function checks if the path is * relative to symlink or relative to current working directory. This is an * initiative to find a smarter `srcpath` to supply when building symlinks. * This allows you to determine which path to use out of one of three possible * types of source paths. The first is an absolute path. This is detected by * `path.isAbsolute()`. When an absolute path is provided, it is checked to * see if it exists. If it does it's used, if not an error is returned * (callback)/ thrown (sync). The other two options for `srcpath` are a * relative url. By default Node's `fs.symlink` works by creating a symlink * using `dstpath` and expects the `srcpath` to be relative to the newly * created symlink. If you provide a `srcpath` that does not exist on the file * system it results in a broken symlink. To minimize this, the function * checks to see if the 'relative to symlink' source file exists, and if it * does it will use it. If it does not, it checks if there's a file that * exists that is relative to the current working directory, if does its used. * This preserves the expectations of the original fs.symlink spec and adds * the ability to pass in `relative to current working direcotry` paths. */function symlinkPaths (srcpath, dstpath, callback) {  if (path.isAbsolute(srcpath)) {    return fs.lstat(srcpath, (err) => {      if (err) {        err.message = err.message.replace('lstat', 'ensureSymlink')        return callback(err)      }      return callback(null, {        toCwd: srcpath,        toDst: srcpath      })    })  } else {    const dstdir = path.dirname(dstpath)    const relativeToDst = path.join(dstdir, srcpath)    return pathExists(relativeToDst, (err, exists) => {      if (err) return callback(err)      if (exists) {        return callback(null, {          toCwd: relativeToDst,          toDst: srcpath        })      } else {        return fs.lstat(srcpath, (err) => {          if (err) {            err.message = err.message.replace('lstat', 'ensureSymlink')            return callback(err)          }          return callback(null, {            toCwd: srcpath,            toDst: path.relative(dstdir, srcpath)          })        })      }    })  }}function symlinkPathsSync (srcpath, dstpath) {  let exists  if (path.isAbsolute(srcpath)) {    exists = fs.existsSync(srcpath)    if (!exists) throw new Error('absolute srcpath does not exist')    return {      toCwd: srcpath,      toDst: srcpath    }  } else {    const dstdir = path.dirname(dstpath)    const relativeToDst = path.join(dstdir, srcpath)    exists = fs.existsSync(relativeToDst)    if (exists) {      return {        toCwd: relativeToDst,        toDst: srcpath      }    } else {      exists = fs.existsSync(srcpath)      if (!exists) throw new Error('relative srcpath does not exist')      return {        toCwd: srcpath,        toDst: path.relative(dstdir, srcpath)      }    }  }}module.exports = {  symlinkPaths,  symlinkPathsSync}
 |