aboutsummaryrefslogtreecommitdiff
path: root/node_modules/@mrmlnc/readdir-enhanced/lib/normalize-options.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/@mrmlnc/readdir-enhanced/lib/normalize-options.js')
-rw-r--r--node_modules/@mrmlnc/readdir-enhanced/lib/normalize-options.js177
1 files changed, 177 insertions, 0 deletions
diff --git a/node_modules/@mrmlnc/readdir-enhanced/lib/normalize-options.js b/node_modules/@mrmlnc/readdir-enhanced/lib/normalize-options.js
new file mode 100644
index 0000000..66f1158
--- /dev/null
+++ b/node_modules/@mrmlnc/readdir-enhanced/lib/normalize-options.js
@@ -0,0 +1,177 @@
+'use strict';
+
+const path = require('path');
+const globToRegExp = require('glob-to-regexp');
+
+module.exports = normalizeOptions;
+
+let isWindows = /^win/.test(process.platform);
+
+/**
+ * @typedef {Object} FSFacade
+ * @property {fs.readdir} readdir
+ * @property {fs.stat} stat
+ * @property {fs.lstat} lstat
+ */
+
+/**
+ * Validates and normalizes the options argument
+ *
+ * @param {object} [options] - User-specified options, if any
+ * @param {object} internalOptions - Internal options that aren't part of the public API
+ *
+ * @param {number|boolean|function} [options.deep]
+ * The number of directories to recursively traverse. Any falsy value or negative number will
+ * default to zero, so only the top-level contents will be returned. Set to `true` or `Infinity`
+ * to traverse all subdirectories. Or provide a function that accepts a {@link fs.Stats} object
+ * and returns a truthy value if the directory's contents should be crawled.
+ *
+ * @param {function|string|RegExp} [options.filter]
+ * A function that accepts a {@link fs.Stats} object and returns a truthy value if the data should
+ * be returned. Or a RegExp or glob string pattern, to filter by file name.
+ *
+ * @param {string} [options.sep]
+ * The path separator to use. By default, the OS-specific separator will be used, but this can be
+ * set to a specific value to ensure consistency across platforms.
+ *
+ * @param {string} [options.basePath]
+ * The base path to prepend to each result. If empty, then all results will be relative to `dir`.
+ *
+ * @param {FSFacade} [options.fs]
+ * Synchronous or asynchronous facades for Node.js File System module
+ *
+ * @param {object} [internalOptions.facade]
+ * Synchronous or asynchronous facades for various methods, including for the Node.js File System module
+ *
+ * @param {boolean} [internalOptions.emit]
+ * Indicates whether the reader should emit "file", "directory", and "symlink" events
+ *
+ * @param {boolean} [internalOptions.stats]
+ * Indicates whether the reader should emit {@link fs.Stats} objects instead of path strings
+ *
+ * @returns {object}
+ */
+function normalizeOptions (options, internalOptions) {
+ if (options === null || options === undefined) {
+ options = {};
+ }
+ else if (typeof options !== 'object') {
+ throw new TypeError('options must be an object');
+ }
+
+ let recurseDepth, recurseFn, recurseRegExp, recurseGlob, deep = options.deep;
+ if (deep === null || deep === undefined) {
+ recurseDepth = 0;
+ }
+ else if (typeof deep === 'boolean') {
+ recurseDepth = deep ? Infinity : 0;
+ }
+ else if (typeof deep === 'number') {
+ if (deep < 0 || isNaN(deep)) {
+ throw new Error('options.deep must be a positive number');
+ }
+ else if (Math.floor(deep) !== deep) {
+ throw new Error('options.deep must be an integer');
+ }
+ else {
+ recurseDepth = deep;
+ }
+ }
+ else if (typeof deep === 'function') {
+ recurseDepth = Infinity;
+ recurseFn = deep;
+ }
+ else if (deep instanceof RegExp) {
+ recurseDepth = Infinity;
+ recurseRegExp = deep;
+ }
+ else if (typeof deep === 'string' && deep.length > 0) {
+ recurseDepth = Infinity;
+ recurseGlob = globToRegExp(deep, { extended: true, globstar: true });
+ }
+ else {
+ throw new TypeError('options.deep must be a boolean, number, function, regular expression, or glob pattern');
+ }
+
+ let filterFn, filterRegExp, filterGlob, filter = options.filter;
+ if (filter !== null && filter !== undefined) {
+ if (typeof filter === 'function') {
+ filterFn = filter;
+ }
+ else if (filter instanceof RegExp) {
+ filterRegExp = filter;
+ }
+ else if (typeof filter === 'string' && filter.length > 0) {
+ filterGlob = globToRegExp(filter, { extended: true, globstar: true });
+ }
+ else {
+ throw new TypeError('options.filter must be a function, regular expression, or glob pattern');
+ }
+ }
+
+ let sep = options.sep;
+ if (sep === null || sep === undefined) {
+ sep = path.sep;
+ }
+ else if (typeof sep !== 'string') {
+ throw new TypeError('options.sep must be a string');
+ }
+
+ let basePath = options.basePath;
+ if (basePath === null || basePath === undefined) {
+ basePath = '';
+ }
+ else if (typeof basePath === 'string') {
+ // Append a path separator to the basePath, if necessary
+ if (basePath && basePath.substr(-1) !== sep) {
+ basePath += sep;
+ }
+ }
+ else {
+ throw new TypeError('options.basePath must be a string');
+ }
+
+ // Convert the basePath to POSIX (forward slashes)
+ // so that glob pattern matching works consistently, even on Windows
+ let posixBasePath = basePath;
+ if (posixBasePath && sep !== '/') {
+ posixBasePath = posixBasePath.replace(new RegExp('\\' + sep, 'g'), '/');
+
+ /* istanbul ignore if */
+ if (isWindows) {
+ // Convert Windows root paths (C:\) and UNCs (\\) to POSIX root paths
+ posixBasePath = posixBasePath.replace(/^([a-zA-Z]\:\/|\/\/)/, '/');
+ }
+ }
+
+ // Determine which facade methods to use
+ let facade;
+ if (options.fs === null || options.fs === undefined) {
+ // The user didn't provide their own facades, so use our internal ones
+ facade = internalOptions.facade;
+ }
+ else if (typeof options.fs === 'object') {
+ // Merge the internal facade methods with the user-provided `fs` facades
+ facade = Object.assign({}, internalOptions.facade);
+ facade.fs = Object.assign({}, internalOptions.facade.fs, options.fs);
+ }
+ else {
+ throw new TypeError('options.fs must be an object');
+ }
+
+ return {
+ recurseDepth,
+ recurseFn,
+ recurseRegExp,
+ recurseGlob,
+ filterFn,
+ filterRegExp,
+ filterGlob,
+ sep,
+ basePath,
+ posixBasePath,
+ facade,
+ emit: !!internalOptions.emit,
+ stats: !!internalOptions.stats,
+ };
+}