2 * detect-file (https://github.com/doowb/detect-file)
4 * Copyright (c) 2016, Brian Woodward.
5 * Licensed under the MIT License.
10 var fs = require('fs');
11 var path = require('path');
12 var exists = require('fs-exists-sync');
15 * Resolve the given `filepath` if it exists.
18 * var res = detect('package.json');
22 * var res = detect('fake-file.json');
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`.
34 module.exports = function detect(filepath, options) {
35 if (!filepath || (typeof filepath !== 'string')) {
38 if (exists(filepath)) {
39 return path.resolve(filepath);
42 options = options || {};
43 if (options.nocase === true) {
44 return nocase(filepath);
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.
53 * @param {String} `filepath` filepath to check.
54 * @return {String} Returns found filepath if exists, otherwise null.
57 function nocase(filepath) {
58 filepath = path.resolve(filepath);
59 var res = tryReaddir(filepath);
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) {
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;
78 var fp = path.resolve(res.path, res.files[idx]);
79 if (filepath === fp || upper === fp) {
82 var fpUpper = fp.toUpperCase();
83 if (filepath === fpUpper || upper === fpUpper) {
92 * Try to read the filepath as a directory first, then fallback to the filepath's dirname.
94 * @param {String} `filepath` path of the directory to read.
95 * @return {Object} Object containing `path` and `files` if succesful. Otherwise, null.
98 function tryReaddir(filepath) {
99 var ctx = { path: filepath, files: [] };
101 ctx.files = fs.readdirSync(filepath);
105 ctx.path = path.dirname(filepath);
106 ctx.files = fs.readdirSync(ctx.path);