| '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 | 
| } |