Security update for permissions_by_term
[yaffs-website] / node_modules / fs-extra / lib / ensure / symlink-paths.js
1 var path = require('path')
2 // path.isAbsolute shim for Node.js 0.10 support
3 var fs = require('graceful-fs')
4
5 /**
6  * Function that returns two types of paths, one relative to symlink, and one
7  * relative to the current working directory. Checks if path is absolute or
8  * relative. If the path is relative, this function checks if the path is
9  * relative to symlink or relative to current working directory. This is an
10  * initiative to find a smarter `srcpath` to supply when building symlinks.
11  * This allows you to determine which path to use out of one of three possible
12  * types of source paths. The first is an absolute path. This is detected by
13  * `path.isAbsolute()`. When an absolute path is provided, it is checked to
14  * see if it exists. If it does it's used, if not an error is returned
15  * (callback)/ thrown (sync). The other two options for `srcpath` are a
16  * relative url. By default Node's `fs.symlink` works by creating a symlink
17  * using `dstpath` and expects the `srcpath` to be relative to the newly
18  * created symlink. If you provide a `srcpath` that does not exist on the file
19  * system it results in a broken symlink. To minimize this, the function
20  * checks to see if the 'relative to symlink' source file exists, and if it
21  * does it will use it. If it does not, it checks if there's a file that
22  * exists that is relative to the current working directory, if does its used.
23  * This preserves the expectations of the original fs.symlink spec and adds
24  * the ability to pass in `relative to current working direcotry` paths.
25  */
26
27 function symlinkPaths (srcpath, dstpath, callback) {
28   if (path.isAbsolute(srcpath)) {
29     return fs.lstat(srcpath, function (err, stat) {
30       if (err) {
31         err.message = err.message.replace('lstat', 'ensureSymlink')
32         return callback(err)
33       }
34       return callback(null, {
35         'toCwd': srcpath,
36         'toDst': srcpath
37       })
38     })
39   } else {
40     var dstdir = path.dirname(dstpath)
41     var relativeToDst = path.join(dstdir, srcpath)
42     return fs.exists(relativeToDst, function (exists) {
43       if (exists) {
44         return callback(null, {
45           'toCwd': relativeToDst,
46           'toDst': srcpath
47         })
48       } else {
49         return fs.lstat(srcpath, function (err, stat) {
50           if (err) {
51             err.message = err.message.replace('lstat', 'ensureSymlink')
52             return callback(err)
53           }
54           return callback(null, {
55             'toCwd': srcpath,
56             'toDst': path.relative(dstdir, srcpath)
57           })
58         })
59       }
60     })
61   }
62 }
63
64 function symlinkPathsSync (srcpath, dstpath) {
65   var exists
66   if (path.isAbsolute(srcpath)) {
67     exists = fs.existsSync(srcpath)
68     if (!exists) throw new Error('absolute srcpath does not exist')
69     return {
70       'toCwd': srcpath,
71       'toDst': srcpath
72     }
73   } else {
74     var dstdir = path.dirname(dstpath)
75     var relativeToDst = path.join(dstdir, srcpath)
76     exists = fs.existsSync(relativeToDst)
77     if (exists) {
78       return {
79         'toCwd': relativeToDst,
80         'toDst': srcpath
81       }
82     } else {
83       exists = fs.existsSync(srcpath)
84       if (!exists) throw new Error('relative srcpath does not exist')
85       return {
86         'toCwd': srcpath,
87         'toDst': path.relative(dstdir, srcpath)
88       }
89     }
90   }
91 }
92
93 module.exports = {
94   'symlinkPaths': symlinkPaths,
95   'symlinkPathsSync': symlinkPathsSync
96 }