| Leo Repp | 58b9f11 | 2021-11-22 11:57:47 +0100 | [diff] [blame^] | 1 | 'use strict'; |
| 2 | |
| 3 | var path = require('path'); |
| 4 | var isAbsolute = require('is-absolute'); |
| 5 | var pathRoot = require('path-root'); |
| 6 | var MapCache = require('map-cache'); |
| 7 | var cache = new MapCache(); |
| 8 | |
| 9 | module.exports = function(filepath) { |
| 10 | if (typeof filepath !== 'string') { |
| 11 | throw new TypeError('parse-filepath expects a string'); |
| 12 | } |
| 13 | |
| 14 | if (cache.has(filepath)) { |
| 15 | return cache.get(filepath); |
| 16 | } |
| 17 | |
| 18 | var obj = {}; |
| 19 | if (typeof path.parse === 'function') { |
| 20 | obj = path.parse(filepath); |
| 21 | obj.extname = obj.ext; |
| 22 | obj.basename = obj.base; |
| 23 | obj.dirname = obj.dir; |
| 24 | obj.stem = obj.name; |
| 25 | |
| 26 | } else { |
| 27 | define(obj, 'root', function() { |
| 28 | return pathRoot(this.path); |
| 29 | }); |
| 30 | |
| 31 | define(obj, 'extname', function() { |
| 32 | return path.extname(filepath); |
| 33 | }); |
| 34 | |
| 35 | define(obj, 'ext', function() { |
| 36 | return this.extname; |
| 37 | }); |
| 38 | |
| 39 | define(obj, 'name', function() { |
| 40 | return path.basename(filepath, this.ext); |
| 41 | }); |
| 42 | |
| 43 | define(obj, 'stem', function() { |
| 44 | return this.name; |
| 45 | }); |
| 46 | |
| 47 | define(obj, 'base', function() { |
| 48 | return this.name + this.ext; |
| 49 | }); |
| 50 | |
| 51 | define(obj, 'basename', function() { |
| 52 | return this.base; |
| 53 | }); |
| 54 | |
| 55 | define(obj, 'dir', function() { |
| 56 | var dir = path.dirname(filepath); |
| 57 | if (dir === '.') { |
| 58 | return (filepath[0] === '.') ? dir : ''; |
| 59 | } else { |
| 60 | return dir; |
| 61 | } |
| 62 | }); |
| 63 | |
| 64 | define(obj, 'dirname', function() { |
| 65 | return this.dir; |
| 66 | }); |
| 67 | } |
| 68 | |
| 69 | obj.path = filepath; |
| 70 | |
| 71 | define(obj, 'absolute', function() { |
| 72 | return path.resolve(this.path); |
| 73 | }); |
| 74 | |
| 75 | define(obj, 'isAbsolute', function() { |
| 76 | return isAbsolute(this.path); |
| 77 | }); |
| 78 | |
| 79 | cache.set(filepath, obj); |
| 80 | return obj; |
| 81 | }; |
| 82 | |
| 83 | function define(obj, prop, fn) { |
| 84 | var cached; |
| 85 | Object.defineProperty(obj, prop, { |
| 86 | configurable: true, |
| 87 | enumerable: true, |
| 88 | set: function(val) { |
| 89 | cached = val; |
| 90 | }, |
| 91 | get: function() { |
| 92 | return cached || (cached = fn.call(obj)); |
| 93 | } |
| 94 | }); |
| 95 | } |