Security update for permissions_by_term
[yaffs-website] / node_modules / detect-file / index.js
1 /*!
2  * detect-file (https://github.com/doowb/detect-file)
3  *
4  * Copyright (c) 2016, Brian Woodward.
5  * Licensed under the MIT License.
6  */
7
8 'use strict';
9
10 var fs = require('fs');
11 var path = require('path');
12 var exists = require('fs-exists-sync');
13
14 /**
15  * Resolve the given `filepath` if it exists.
16  *
17  * ```js
18  * var res = detect('package.json');
19  * console.log(res);
20  * //=> "package.json"
21  *
22  * var res = detect('fake-file.json');
23  * console.log(res)
24  * //=> null
25  * ```
26  *
27  * @param  {String} `filepath` filepath to detect.
28  * @param  {Object} `options` Additional options.
29  * @param  {Boolean} `options.nocase` Set this to `true` force case-insensitive filename checks. This is useful on case sensitive file systems.
30  * @return {String} Returns the resolved filepath if it exists, otherwise returns `null`.
31  * @api public
32  */
33
34 module.exports = function detect(filepath, options) {
35   if (!filepath || (typeof filepath !== 'string')) {
36     return null;
37   }
38   if (exists(filepath)) {
39     return path.resolve(filepath);
40   }
41
42   options = options || {};
43   if (options.nocase === true) {
44     return nocase(filepath);
45   }
46   return null;
47 };
48
49 /**
50  * Check if the filepath exists by falling back to reading in the entire directory.
51  * Returns the real filepath (for case sensitive file systems) if found.
52  *
53  * @param  {String} `filepath` filepath to check.
54  * @return {String} Returns found filepath if exists, otherwise null.
55  */
56
57 function nocase(filepath) {
58   filepath = path.resolve(filepath);
59   var res = tryReaddir(filepath);
60   if (res === null) {
61     return null;
62   }
63
64   // "filepath" is a directory, an error would be
65   // thrown if it doesn't exist. if we're here, it exists
66   if (res.path === filepath) {
67     return res.path;
68   }
69
70   // "filepath" is not a directory
71   // compare against upper case later
72   // see https://nodejs.org/en/docs/guides/working-with-different-filesystems/
73   var upper = filepath.toUpperCase();
74   var len = res.files.length;
75   var idx = -1;
76
77   while (++idx < len) {
78     var fp = path.resolve(res.path, res.files[idx]);
79     if (filepath === fp || upper === fp) {
80       return fp;
81     }
82     var fpUpper = fp.toUpperCase();
83     if (filepath === fpUpper || upper === fpUpper) {
84       return fp;
85     }
86   }
87
88   return null;
89 }
90
91 /**
92  * Try to read the filepath as a directory first, then fallback to the filepath's dirname.
93  *
94  * @param  {String} `filepath` path of the directory to read.
95  * @return {Object} Object containing `path` and `files` if succesful. Otherwise, null.
96  */
97
98 function tryReaddir(filepath) {
99   var ctx = { path: filepath, files: [] };
100   try {
101     ctx.files = fs.readdirSync(filepath);
102     return ctx;
103   } catch (err) {}
104   try {
105     ctx.path = path.dirname(filepath);
106     ctx.files = fs.readdirSync(ctx.path);
107     return ctx;
108   } catch (err) {}
109   return null;
110 }