import { Filter, FilterStats } from "builder-util"
import { Minimatch } from "minimatch"
import * as path from "path"
export function hasMagic(pattern: Minimatch) {
const set = pattern.set
if (set.length > 1) {
return true
}
for (const i of set[0]) {
if (typeof i !== "string") {
return true
}
}
return false
}
function ensureEndSlash(s: string) {
return s.length === 0 || s.endsWith(path.sep) ? s : s + path.sep
}
function getRelativePath(file: string, srcWithEndSlash: string, stat: FilterStats) {
let relative = stat.moduleFullFilePath || file.substring(srcWithEndSlash.length)
if (path.sep === "\\") {
if (relative.startsWith("\\")) {
relative = relative.substring(1)
}
relative = relative.replace(/\\/g, "/")
}
return relative
}
export function createFilter(src: string, patterns: Array<Minimatch>, excludePatterns?: Array<Minimatch> | null): Filter {
const srcWithEndSlash = ensureEndSlash(src)
return (file, stat) => {
if (src === file) {
return true
}
let relative = getRelativePath(file, srcWithEndSlash, stat)
if (relative === "node_modules") {
return false
} else if (relative.endsWith("/node_modules")) {
relative += "/"
}
return minimatchAll(relative, patterns, stat) && (excludePatterns == null || stat.isDirectory() || !minimatchAll(relative, excludePatterns, stat))
}
}
function minimatchAll(path: string, patterns: Array<Minimatch>, stat: FilterStats): boolean {
let match = false
for (const pattern of patterns) {
if (match !== pattern.negate) {
continue
}
match = pattern.match(path, stat.isDirectory() && !pattern.negate)
}
return match
}