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 | 'use strict';
|
26 |
|
27 | function assertPath(path) {
|
28 | if (typeof path !== 'string') {
|
29 | throw new TypeError('Path must be a string. Received ' + JSON.stringify(path));
|
30 | }
|
31 | }
|
32 |
|
33 |
|
34 | function normalizeStringPosix(path, allowAboveRoot) {
|
35 | var res = '';
|
36 | var lastSegmentLength = 0;
|
37 | var lastSlash = -1;
|
38 | var dots = 0;
|
39 | var code;
|
40 | for (var i = 0; i <= path.length; ++i) {
|
41 | if (i < path.length)
|
42 | code = path.charCodeAt(i);
|
43 | else if (code === 47 )
|
44 | break;
|
45 | else
|
46 | code = 47 ;
|
47 | if (code === 47 ) {
|
48 | if (lastSlash === i - 1 || dots === 1) {
|
49 |
|
50 | } else if (lastSlash !== i - 1 && dots === 2) {
|
51 | if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46 ) {
|
52 | if (res.length > 2) {
|
53 | var lastSlashIndex = res.lastIndexOf('/');
|
54 | if (lastSlashIndex !== res.length - 1) {
|
55 | if (lastSlashIndex === -1) {
|
56 | res = '';
|
57 | lastSegmentLength = 0;
|
58 | } else {
|
59 | res = res.slice(0, lastSlashIndex);
|
60 | lastSegmentLength = res.length - 1 - res.lastIndexOf('/');
|
61 | }
|
62 | lastSlash = i;
|
63 | dots = 0;
|
64 | continue;
|
65 | }
|
66 | } else if (res.length === 2 || res.length === 1) {
|
67 | res = '';
|
68 | lastSegmentLength = 0;
|
69 | lastSlash = i;
|
70 | dots = 0;
|
71 | continue;
|
72 | }
|
73 | }
|
74 | if (allowAboveRoot) {
|
75 | if (res.length > 0)
|
76 | res += '/..';
|
77 | else
|
78 | res = '..';
|
79 | lastSegmentLength = 2;
|
80 | }
|
81 | } else {
|
82 | if (res.length > 0)
|
83 | res += '/' + path.slice(lastSlash + 1, i);
|
84 | else
|
85 | res = path.slice(lastSlash + 1, i);
|
86 | lastSegmentLength = i - lastSlash - 1;
|
87 | }
|
88 | lastSlash = i;
|
89 | dots = 0;
|
90 | } else if (code === 46 && dots !== -1) {
|
91 | ++dots;
|
92 | } else {
|
93 | dots = -1;
|
94 | }
|
95 | }
|
96 | return res;
|
97 | }
|
98 |
|
99 | function _format(sep, pathObject) {
|
100 | var dir = pathObject.dir || pathObject.root;
|
101 | var base = pathObject.base || (pathObject.name || '') + (pathObject.ext || '');
|
102 | if (!dir) {
|
103 | return base;
|
104 | }
|
105 | if (dir === pathObject.root) {
|
106 | return dir + base;
|
107 | }
|
108 | return dir + sep + base;
|
109 | }
|
110 |
|
111 | var posix = {
|
112 |
|
113 | resolve: function resolve() {
|
114 | var resolvedPath = '';
|
115 | var resolvedAbsolute = false;
|
116 | var cwd;
|
117 |
|
118 | for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
|
119 | var path;
|
120 | if (i >= 0)
|
121 | path = arguments[i];
|
122 | else {
|
123 | if (cwd === undefined)
|
124 | cwd = process.cwd();
|
125 | path = cwd;
|
126 | }
|
127 |
|
128 | assertPath(path);
|
129 |
|
130 |
|
131 | if (path.length === 0) {
|
132 | continue;
|
133 | }
|
134 |
|
135 | resolvedPath = path + '/' + resolvedPath;
|
136 | resolvedAbsolute = path.charCodeAt(0) === 47 ;
|
137 | }
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 | resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute);
|
144 |
|
145 | if (resolvedAbsolute) {
|
146 | if (resolvedPath.length > 0)
|
147 | return '/' + resolvedPath;
|
148 | else
|
149 | return '/';
|
150 | } else if (resolvedPath.length > 0) {
|
151 | return resolvedPath;
|
152 | } else {
|
153 | return '.';
|
154 | }
|
155 | },
|
156 |
|
157 | normalize: function normalize(path) {
|
158 | assertPath(path);
|
159 |
|
160 | if (path.length === 0) return '.';
|
161 |
|
162 | var isAbsolute = path.charCodeAt(0) === 47 ;
|
163 | var trailingSeparator = path.charCodeAt(path.length - 1) === 47 ;
|
164 |
|
165 |
|
166 | path = normalizeStringPosix(path, !isAbsolute);
|
167 |
|
168 | if (path.length === 0 && !isAbsolute) path = '.';
|
169 | if (path.length > 0 && trailingSeparator) path += '/';
|
170 |
|
171 | if (isAbsolute) return '/' + path;
|
172 | return path;
|
173 | },
|
174 |
|
175 | isAbsolute: function isAbsolute(path) {
|
176 | assertPath(path);
|
177 | return path.length > 0 && path.charCodeAt(0) === 47 ;
|
178 | },
|
179 |
|
180 | join: function join() {
|
181 | if (arguments.length === 0)
|
182 | return '.';
|
183 | var joined;
|
184 | for (var i = 0; i < arguments.length; ++i) {
|
185 | var arg = arguments[i];
|
186 | assertPath(arg);
|
187 | if (arg.length > 0) {
|
188 | if (joined === undefined)
|
189 | joined = arg;
|
190 | else
|
191 | joined += '/' + arg;
|
192 | }
|
193 | }
|
194 | if (joined === undefined)
|
195 | return '.';
|
196 | return posix.normalize(joined);
|
197 | },
|
198 |
|
199 | relative: function relative(from, to) {
|
200 | assertPath(from);
|
201 | assertPath(to);
|
202 |
|
203 | if (from === to) return '';
|
204 |
|
205 | from = posix.resolve(from);
|
206 | to = posix.resolve(to);
|
207 |
|
208 | if (from === to) return '';
|
209 |
|
210 |
|
211 | var fromStart = 1;
|
212 | for (; fromStart < from.length; ++fromStart) {
|
213 | if (from.charCodeAt(fromStart) !== 47 )
|
214 | break;
|
215 | }
|
216 | var fromEnd = from.length;
|
217 | var fromLen = fromEnd - fromStart;
|
218 |
|
219 |
|
220 | var toStart = 1;
|
221 | for (; toStart < to.length; ++toStart) {
|
222 | if (to.charCodeAt(toStart) !== 47 )
|
223 | break;
|
224 | }
|
225 | var toEnd = to.length;
|
226 | var toLen = toEnd - toStart;
|
227 |
|
228 |
|
229 | var length = fromLen < toLen ? fromLen : toLen;
|
230 | var lastCommonSep = -1;
|
231 | var i = 0;
|
232 | for (; i <= length; ++i) {
|
233 | if (i === length) {
|
234 | if (toLen > length) {
|
235 | if (to.charCodeAt(toStart + i) === 47 ) {
|
236 |
|
237 |
|
238 | return to.slice(toStart + i + 1);
|
239 | } else if (i === 0) {
|
240 |
|
241 |
|
242 | return to.slice(toStart + i);
|
243 | }
|
244 | } else if (fromLen > length) {
|
245 | if (from.charCodeAt(fromStart + i) === 47 ) {
|
246 |
|
247 |
|
248 | lastCommonSep = i;
|
249 | } else if (i === 0) {
|
250 |
|
251 |
|
252 | lastCommonSep = 0;
|
253 | }
|
254 | }
|
255 | break;
|
256 | }
|
257 | var fromCode = from.charCodeAt(fromStart + i);
|
258 | var toCode = to.charCodeAt(toStart + i);
|
259 | if (fromCode !== toCode)
|
260 | break;
|
261 | else if (fromCode === 47 )
|
262 | lastCommonSep = i;
|
263 | }
|
264 |
|
265 | var out = '';
|
266 |
|
267 |
|
268 | for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {
|
269 | if (i === fromEnd || from.charCodeAt(i) === 47 ) {
|
270 | if (out.length === 0)
|
271 | out += '..';
|
272 | else
|
273 | out += '/..';
|
274 | }
|
275 | }
|
276 |
|
277 |
|
278 |
|
279 | if (out.length > 0)
|
280 | return out + to.slice(toStart + lastCommonSep);
|
281 | else {
|
282 | toStart += lastCommonSep;
|
283 | if (to.charCodeAt(toStart) === 47 )
|
284 | ++toStart;
|
285 | return to.slice(toStart);
|
286 | }
|
287 | },
|
288 |
|
289 | _makeLong: function _makeLong(path) {
|
290 | return path;
|
291 | },
|
292 |
|
293 | dirname: function dirname(path) {
|
294 | assertPath(path);
|
295 | if (path.length === 0) return '.';
|
296 | var code = path.charCodeAt(0);
|
297 | var hasRoot = code === 47 ;
|
298 | var end = -1;
|
299 | var matchedSlash = true;
|
300 | for (var i = path.length - 1; i >= 1; --i) {
|
301 | code = path.charCodeAt(i);
|
302 | if (code === 47 ) {
|
303 | if (!matchedSlash) {
|
304 | end = i;
|
305 | break;
|
306 | }
|
307 | } else {
|
308 |
|
309 | matchedSlash = false;
|
310 | }
|
311 | }
|
312 |
|
313 | if (end === -1) return hasRoot ? '/' : '.';
|
314 | if (hasRoot && end === 1) return '//';
|
315 | return path.slice(0, end);
|
316 | },
|
317 |
|
318 | basename: function basename(path, ext) {
|
319 | if (ext !== undefined && typeof ext !== 'string') throw new TypeError('"ext" argument must be a string');
|
320 | assertPath(path);
|
321 |
|
322 | var start = 0;
|
323 | var end = -1;
|
324 | var matchedSlash = true;
|
325 | var i;
|
326 |
|
327 | if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
|
328 | if (ext.length === path.length && ext === path) return '';
|
329 | var extIdx = ext.length - 1;
|
330 | var firstNonSlashEnd = -1;
|
331 | for (i = path.length - 1; i >= 0; --i) {
|
332 | var code = path.charCodeAt(i);
|
333 | if (code === 47 ) {
|
334 |
|
335 |
|
336 | if (!matchedSlash) {
|
337 | start = i + 1;
|
338 | break;
|
339 | }
|
340 | } else {
|
341 | if (firstNonSlashEnd === -1) {
|
342 |
|
343 |
|
344 | matchedSlash = false;
|
345 | firstNonSlashEnd = i + 1;
|
346 | }
|
347 | if (extIdx >= 0) {
|
348 |
|
349 | if (code === ext.charCodeAt(extIdx)) {
|
350 | if (--extIdx === -1) {
|
351 |
|
352 |
|
353 | end = i;
|
354 | }
|
355 | } else {
|
356 |
|
357 |
|
358 | extIdx = -1;
|
359 | end = firstNonSlashEnd;
|
360 | }
|
361 | }
|
362 | }
|
363 | }
|
364 |
|
365 | if (start === end) end = firstNonSlashEnd;else if (end === -1) end = path.length;
|
366 | return path.slice(start, end);
|
367 | } else {
|
368 | for (i = path.length - 1; i >= 0; --i) {
|
369 | if (path.charCodeAt(i) === 47 ) {
|
370 |
|
371 |
|
372 | if (!matchedSlash) {
|
373 | start = i + 1;
|
374 | break;
|
375 | }
|
376 | } else if (end === -1) {
|
377 |
|
378 |
|
379 | matchedSlash = false;
|
380 | end = i + 1;
|
381 | }
|
382 | }
|
383 |
|
384 | if (end === -1) return '';
|
385 | return path.slice(start, end);
|
386 | }
|
387 | },
|
388 |
|
389 | extname: function extname(path) {
|
390 | assertPath(path);
|
391 | var startDot = -1;
|
392 | var startPart = 0;
|
393 | var end = -1;
|
394 | var matchedSlash = true;
|
395 |
|
396 |
|
397 | var preDotState = 0;
|
398 | for (var i = path.length - 1; i >= 0; --i) {
|
399 | var code = path.charCodeAt(i);
|
400 | if (code === 47 ) {
|
401 |
|
402 |
|
403 | if (!matchedSlash) {
|
404 | startPart = i + 1;
|
405 | break;
|
406 | }
|
407 | continue;
|
408 | }
|
409 | if (end === -1) {
|
410 |
|
411 |
|
412 | matchedSlash = false;
|
413 | end = i + 1;
|
414 | }
|
415 | if (code === 46 ) {
|
416 |
|
417 | if (startDot === -1)
|
418 | startDot = i;
|
419 | else if (preDotState !== 1)
|
420 | preDotState = 1;
|
421 | } else if (startDot !== -1) {
|
422 |
|
423 |
|
424 | preDotState = -1;
|
425 | }
|
426 | }
|
427 |
|
428 | if (startDot === -1 || end === -1 ||
|
429 |
|
430 | preDotState === 0 ||
|
431 |
|
432 | preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
|
433 | return '';
|
434 | }
|
435 | return path.slice(startDot, end);
|
436 | },
|
437 |
|
438 | format: function format(pathObject) {
|
439 | if (pathObject === null || typeof pathObject !== 'object') {
|
440 | throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
|
441 | }
|
442 | return _format('/', pathObject);
|
443 | },
|
444 |
|
445 | parse: function parse(path) {
|
446 | assertPath(path);
|
447 |
|
448 | var ret = { root: '', dir: '', base: '', ext: '', name: '' };
|
449 | if (path.length === 0) return ret;
|
450 | var code = path.charCodeAt(0);
|
451 | var isAbsolute = code === 47 ;
|
452 | var start;
|
453 | if (isAbsolute) {
|
454 | ret.root = '/';
|
455 | start = 1;
|
456 | } else {
|
457 | start = 0;
|
458 | }
|
459 | var startDot = -1;
|
460 | var startPart = 0;
|
461 | var end = -1;
|
462 | var matchedSlash = true;
|
463 | var i = path.length - 1;
|
464 |
|
465 |
|
466 |
|
467 | var preDotState = 0;
|
468 |
|
469 |
|
470 | for (; i >= start; --i) {
|
471 | code = path.charCodeAt(i);
|
472 | if (code === 47 ) {
|
473 |
|
474 |
|
475 | if (!matchedSlash) {
|
476 | startPart = i + 1;
|
477 | break;
|
478 | }
|
479 | continue;
|
480 | }
|
481 | if (end === -1) {
|
482 |
|
483 |
|
484 | matchedSlash = false;
|
485 | end = i + 1;
|
486 | }
|
487 | if (code === 46 ) {
|
488 |
|
489 | if (startDot === -1) startDot = i;else if (preDotState !== 1) preDotState = 1;
|
490 | } else if (startDot !== -1) {
|
491 |
|
492 |
|
493 | preDotState = -1;
|
494 | }
|
495 | }
|
496 |
|
497 | if (startDot === -1 || end === -1 ||
|
498 |
|
499 | preDotState === 0 ||
|
500 |
|
501 | preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
|
502 | if (end !== -1) {
|
503 | if (startPart === 0 && isAbsolute) ret.base = ret.name = path.slice(1, end);else ret.base = ret.name = path.slice(startPart, end);
|
504 | }
|
505 | } else {
|
506 | if (startPart === 0 && isAbsolute) {
|
507 | ret.name = path.slice(1, startDot);
|
508 | ret.base = path.slice(1, end);
|
509 | } else {
|
510 | ret.name = path.slice(startPart, startDot);
|
511 | ret.base = path.slice(startPart, end);
|
512 | }
|
513 | ret.ext = path.slice(startDot, end);
|
514 | }
|
515 |
|
516 | if (startPart > 0) ret.dir = path.slice(0, startPart - 1);else if (isAbsolute) ret.dir = '/';
|
517 |
|
518 | return ret;
|
519 | },
|
520 |
|
521 | sep: '/',
|
522 | delimiter: ':',
|
523 | win32: null,
|
524 | posix: null
|
525 | };
|
526 |
|
527 | posix.posix = posix;
|
528 |
|
529 | module.exports = posix; |
\ | No newline at end of file |