-
Notifications
You must be signed in to change notification settings - Fork 5
/
index.ts
144 lines (132 loc) · 3.61 KB
/
index.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
/*******************************************************************************
* @author : 程巍巍 ([email protected])
* @created : Thursday Mar 25, 2021 11:12:30 CST
*
* @description : index
*
******************************************************************************/
function _normalize(path: string) {
const components: string[] = [];
for (const component of `${path}`.split(/\/+/g)) {
if (component == '.') {
} else if (component == '..') {
components.pop();
} else {
components.push(component);
}
}
let normalized = (
(path.startsWith('/') ? '/' : '') + components.join('/')
).replace(/\/\/+/g, '/');
return normalized || '.';
}
function _basename(path: string, ext: string) {
const basename = path.split(/\//g).pop();
if (ext) {
const tmp = basename!.split(/\./g);
const _ext = tmp.pop();
if (ext === _ext || ext.slice(1) === _ext) {
return tmp.join('.');
}
}
return basename;
}
function _dirname(path: string) {
return path.split(/\//g).slice(0, -1).join('/');
}
function _extname(path: string) {
const tmp = path.replace(/^[\.]+/, '');
if (/\./.test(tmp)) {
return tmp.match(/\.[^.]*$/)![0];
}
return '';
}
type PathOptions = {
dir?: string;
root?: string;
base?: string;
name?: string;
ext?: string;
};
function _format(options: PathOptions) {
const {dir, root, base, name, ext} = options;
const _dir = dir || root;
const _base =
base || `${name || ''}${ext && /^\./.test(ext) ? '' : '.'}${ext || ''}`;
return _normalize(`${_dir}/${_base}`);
}
function _isAbsolute(path: string) {
return /^\//.test(path);
}
function _parse(path: string) {
const options: PathOptions = {};
const components = path.split(/\//g);
options.base = components.pop();
options.dir = components.join('/');
if (/^\//.test(options.dir)) {
options.root = '/';
}
if (options.base != undefined) {
const tmp = options.base.replace(/^[\.]+/, '');
if (/\./.test(tmp)) {
options.ext = tmp.match(/\.[^.]*$/)![0];
options.name = options.base.slice(0, -options.ext!.length);
} else {
options.name = options.base;
}
} else {
delete options.base;
}
return options;
}
type Segment = string | string[] | Segment[];
function _flatten(segment: Segment): string[] {
if (!Array.isArray(segment)) {
return [segment];
}
let flatten: string[] = [];
for (const seg of segment) {
flatten = flatten.concat(_flatten(seg));
}
return flatten;
}
function _resolve(...segments: Segment[]) {
const flatten = _flatten(segments).reduce((previous, current) => {
if (/^\//.test(current)) {
return current;
}
return `${previous}/${current}`;
});
return _normalize(flatten);
}
function _relative(base: string, path: string) {
const _base = base.split(/\//g);
const _path = path.split(/\//g);
while (_base[0] === _path[0]) {
_base.shift();
_path.shift();
}
return Array(base.length).fill('..').concat(path).join('/');
}
export const normalize = _normalize;
export const basename = (path: string, ext: string) =>
_basename(_normalize(path), ext);
export const dirname = (path: string) => _dirname(_normalize(path));
export const extname = (path: string) => _extname(_normalize(path));
export const format = _format;
export const parse = (path: string) => _parse(_normalize(path));
export const resolve = _resolve;
export const relative = (base: string, path: string) =>
_relative(_normalize(base), _normalize(path));
export const isAbsolute = _isAbsolute;
export default {
normalize,
basename,
dirname,
extname,
parse,
format,
resolve,
relative,
isAbsolute,
};