-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathnormalize-options.ts
146 lines (136 loc) · 4.02 KB
/
normalize-options.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import { createFilter } from "@jsdevtools/file-path-filter";
import * as path from "path";
import { Facade } from "./types-internal";
import { FilterFunction, Options, Stats } from "./types-public";
/**
* Normalized and sanitized options.
* @internal
*/
export interface NormalizedOptions {
recurseDepth: number;
recurseFn?: FilterFunction;
recurseFnNeedsStats: boolean;
filterFn?: FilterFunction;
filterFnNeedsStats: boolean;
sep: string;
basePath: string;
facade: Facade;
emit: boolean;
stats: boolean;
}
/**
* Validates and normalizes the options argument
*
* @param [options] - User-specified options, if any
* @param facade - sync or async function implementations
* @param emit - Indicates whether the reader should emit "file", "directory", and "symlink" events.
*
* @internal
*/
export function normalizeOptions(options: Options | undefined, facade: Facade, emit: boolean): NormalizedOptions {
if (options === null || options === undefined) {
options = {};
}
else if (typeof options !== "object") {
throw new TypeError("options must be an object");
}
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 stats = Boolean(options.stats || options.withFileTypes);
let recurseDepth, recurseFn, recurseFnNeedsStats = false, 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") {
// Recursion functions require a Stats object
recurseFnNeedsStats = true;
recurseDepth = Infinity;
recurseFn = deep;
}
else if (deep instanceof RegExp || (typeof deep === "string" && deep.length > 0)) {
recurseDepth = Infinity;
recurseFn = createFilter({ map, sep }, deep);
}
else {
throw new TypeError("options.deep must be a boolean, number, function, regular expression, or glob pattern");
}
let filterFn, filterFnNeedsStats = false, filter = options.filter;
if (filter !== null && filter !== undefined) {
if (typeof filter === "function") {
// Filter functions requres a Stats object
filterFnNeedsStats = true;
filterFn = filter;
}
else if (
filter instanceof RegExp ||
typeof filter === "boolean" ||
(typeof filter === "string" && filter.length > 0)) {
filterFn = createFilter({ map, sep }, filter);
}
else {
throw new TypeError("options.filter must be a boolean, function, regular expression, or glob pattern");
}
}
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");
}
// Determine which facade methods to use
if (options.fs === null || options.fs === undefined) {
// The user didn't provide their own facades, so use our internal ones
}
else if (typeof options.fs === "object") {
// Merge the internal facade methods with the user-provided `fs` facades
facade = Object.assign({}, facade);
facade.fs = Object.assign({}, facade.fs, options.fs);
}
else {
throw new TypeError("options.fs must be an object");
}
return {
recurseDepth,
recurseFn,
recurseFnNeedsStats,
filterFn,
filterFnNeedsStats,
stats,
sep,
basePath,
facade,
emit,
};
}
/**
* Maps our modified fs.Stats objects to file paths
*/
function map(stats: Stats) {
return stats.path;
}