|
'use strict'; |
|
|
|
const os = require('os'); |
|
const path = require('path'); |
|
const isWin = os.platform() === 'win32'; |
|
|
|
const CHARS = { '{': '}', '(': ')', '[': ']'}; |
|
const STRICT = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\)|(\\).|([@?!+*]\(.*\)))/; |
|
const RELAXED = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function isglob(str, { strict = true } = {}) { |
|
if (str === '') return false; |
|
let match, rgx = strict ? STRICT : RELAXED; |
|
|
|
while ((match = rgx.exec(str))) { |
|
if (match[2]) return true; |
|
let idx = match.index + match[0].length; |
|
|
|
|
|
|
|
let open = match[1]; |
|
let close = open ? CHARS[open] : null; |
|
if (open && close) { |
|
let n = str.indexOf(close, idx); |
|
if (n !== -1) idx = n + 1; |
|
} |
|
|
|
str = str.slice(idx); |
|
} |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function parent(str, { strict = false } = {}) { |
|
if (isWin && str.includes('/')) |
|
str = str.split('\\').join('/'); |
|
|
|
|
|
if (/[\{\[].*[\/]*.*[\}\]]$/.test(str)) str += '/'; |
|
|
|
|
|
str += 'a'; |
|
|
|
do {str = path.dirname(str)} |
|
while (isglob(str, {strict}) || /(^|[^\\])([\{\[]|\([^\)]+$)/.test(str)); |
|
|
|
|
|
return str.replace(/\\([\*\?\|\[\]\(\)\{\}])/g, '$1'); |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function globalyzer(pattern, opts = {}) { |
|
let base = parent(pattern, opts); |
|
let isGlob = isglob(pattern, opts); |
|
let glob; |
|
|
|
if (base != '.') { |
|
glob = pattern.substr(base.length); |
|
if (glob.startsWith('/')) glob = glob.substr(1); |
|
} else { |
|
glob = pattern; |
|
} |
|
|
|
if (!isGlob) { |
|
base = path.dirname(pattern); |
|
glob = base !== '.' ? pattern.substr(base.length) : pattern; |
|
} |
|
|
|
if (glob.startsWith('./')) glob = glob.substr(2); |
|
if (glob.startsWith('/')) glob = glob.substr(1); |
|
|
|
return { base, glob, isGlob }; |
|
} |
|
|
|
|
|
module.exports = globalyzer; |
|
|