-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
81 lines (61 loc) · 2.4 KB
/
index.js
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
'use strict';
const {join, normalize, sep, posix: {isAbsolute: posixIsAbsolute}, win32: {isAbsolute: win32IsAbsolute}} = require('path');
const {inspect} = require('util');
const inspectWithKind = require('inspect-with-kind');
const isPlainObj = require('is-plain-obj');
const COUNT_ERROR = 'Expected a non-negative integer';
module.exports = function stripDirs(...args) {
const argLen = args.length;
if (argLen !== 2 && argLen !== 3) {
throw new RangeError(`Expected 2 or 3 arguments (<string>, <integer>[, <Object>]), but got ${
argLen === 0 ? 'no' : argLen
} arguments.`);
}
const [pathStr, count, option = {disallowOverflow: false}] = args;
if (typeof pathStr !== 'string') {
throw new TypeError(`Expected a relative file path (<string>), but got a non-string value ${
inspectWithKind(pathStr)
}.`);
}
if (posixIsAbsolute(pathStr) || win32IsAbsolute(pathStr)) {
throw new Error(`Expected a relative file path, but got an absolute path ${inspect(pathStr)}.`);
}
if (typeof count !== 'number') {
throw new TypeError(`${COUNT_ERROR}, but got a non-number value ${inspectWithKind(count)}.`);
}
if (count < 0) {
throw new RangeError(`${COUNT_ERROR}, but got a negative value ${inspectWithKind(count)}.`);
}
if (!isFinite(count)) {
throw new RangeError(`${COUNT_ERROR}, but got ${count}.`);
}
if (count > Number.MAX_SAFE_INTEGER) {
throw new RangeError(`${COUNT_ERROR}, but got an extremely large number ${count}.`);
}
if (!Number.isInteger(count)) {
throw new RangeError(`${COUNT_ERROR}, but got a non-integer number ${count}.`);
}
if (argLen === 3) {
if (!isPlainObj(option)) {
throw new TypeError(`Expected an option object to set strip-dirs option, but got ${
inspectWithKind(option)
}.`);
}
if (option.disallowOverflow !== undefined && typeof option.disallowOverflow !== 'boolean') {
throw new TypeError(`Expected \`disallowOverflow\` option to be a boolean, but got a non-boolean value ${
inspectWithKind(option.disallowOverflow)
}.`);
}
}
const pathComponents = normalize(pathStr).split(sep);
if (pathComponents.length > 1 && pathComponents[0] === '.') {
pathComponents.shift();
}
if (count > pathComponents.length - 1) {
if (option.disallowOverflow) {
throw new RangeError('Cannot strip more directories than there are.');
}
return normalize(pathComponents[pathComponents.length - 1]);
}
return join(...pathComponents.slice(count));
};