astro-ghostcms/.pnpm-store/v3/files/78/d7722df42fa19cacc19be39dafa...

254 lines
13 KiB
Plaintext

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.matchFiles = void 0;
const core_1 = require("./core");
const path_1 = require("./path");
require("./types");
// KLUDGE: Don't assume one 'node_modules' links to another. More likely a single directory inside the node_modules is the symlink.
// ALso, don't assume that an `@foo` directory is linked. More likely the contents of that are linked.
// Reserved characters, forces escaping of any non-word (or digit), non-whitespace character.
// It may be inefficient (we could just match (/[-[\]{}()*+?.,\\^$|#\s]/g), but this is future
// proof.
const reservedCharacterPattern = /[^\w\s\/]/g;
const wildcardCharCodes = [42 /* CharacterCodes.asterisk */, 63 /* CharacterCodes.question */];
const commonPackageFolders = ["node_modules", "bower_components", "jspm_packages"];
const implicitExcludePathRegexPattern = `(?!(${commonPackageFolders.join("|")})(/|$))`;
const filesMatcher = {
/**
* Matches any single directory segment unless it is the last segment and a .min.js file
* Breakdown:
* [^./] # matches everything up to the first . character (excluding directory separators)
* (\\.(?!min\\.js$))? # matches . characters but not if they are part of the .min.js file extension
*/
singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*",
/**
* Regex for the ** wildcard. Matches any number of subdirectories. When used for including
* files or directories, does not match subdirectories that start with a . character
*/
doubleAsteriskRegexFragment: `(/${implicitExcludePathRegexPattern}[^/.][^/]*)*?`,
replaceWildcardCharacter: match => replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment)
};
const directoriesMatcher = {
singleAsteriskRegexFragment: "[^/]*",
/**
* Regex for the ** wildcard. Matches any number of subdirectories. When used for including
* files or directories, does not match subdirectories that start with a . character
*/
doubleAsteriskRegexFragment: `(/${implicitExcludePathRegexPattern}[^/.][^/]*)*?`,
replaceWildcardCharacter: match => replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment)
};
const excludeMatcher = {
singleAsteriskRegexFragment: "[^/]*",
doubleAsteriskRegexFragment: "(/.+?)?",
replaceWildcardCharacter: match => replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment)
};
const wildcardMatchers = {
files: filesMatcher,
directories: directoriesMatcher,
exclude: excludeMatcher
};
function getRegularExpressionForWildcard(specs, basePath, usage) {
const patterns = getRegularExpressionsForWildcards(specs, basePath, usage);
if (!patterns || !patterns.length) {
return undefined;
}
const pattern = patterns.map(pattern => `(${pattern})`).join("|");
// If excluding, match "foo/bar/baz...", but if including, only allow "foo".
const terminator = usage === "exclude" ? "($|/)" : "$";
return `^(${pattern})${terminator}`;
}
function getRegularExpressionsForWildcards(specs, basePath, usage) {
if (specs === undefined || specs.length === 0) {
return undefined;
}
return (0, core_1.flatMap)(specs, spec => spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]));
}
/**
* An "includes" path "foo" is implicitly a glob "foo/** /*" (without the space) if its last component has no extension,
* and does not contain any glob characters itself.
*/
function isImplicitGlob(lastPathComponent) {
return !/[.*?]/.test(lastPathComponent);
}
function getSubPatternFromSpec(spec, basePath, usage, { singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter }) {
let subpattern = "";
let hasWrittenComponent = false;
const components = (0, path_1.getNormalizedPathComponents)(spec, basePath);
const lastComponent = (0, core_1.last)(components);
if (usage !== "exclude" && lastComponent === "**") {
return undefined;
}
// getNormalizedPathComponents includes the separator for the root component.
// We need to remove to create our regex correctly.
components[0] = (0, path_1.removeTrailingDirectorySeparator)(components[0]);
if (isImplicitGlob(lastComponent)) {
components.push("**", "*");
}
let optionalCount = 0;
for (let component of components) {
if (component === "**") {
subpattern += doubleAsteriskRegexFragment;
}
else {
if (usage === "directories") {
subpattern += "(";
optionalCount++;
}
if (hasWrittenComponent) {
subpattern += path_1.directorySeparator;
}
if (usage !== "exclude") {
let componentPattern = "";
// The * and ? wildcards should not match directories or files that start with . if they
// appear first in a component. Dotted directories and files can be included explicitly
// like so: **/.*/.*
if (component.charCodeAt(0) === 42 /* CharacterCodes.asterisk */) {
componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?";
component = component.substr(1);
}
else if (component.charCodeAt(0) === 63 /* CharacterCodes.question */) {
componentPattern += "[^./]";
component = component.substr(1);
}
componentPattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
// Patterns should not include subfolders like node_modules unless they are
// explicitly included as part of the path.
//
// As an optimization, if the component pattern is the same as the component,
// then there definitely were no wildcard characters and we do not need to
// add the exclusion pattern.
if (componentPattern !== component) {
subpattern += implicitExcludePathRegexPattern;
}
subpattern += componentPattern;
}
else {
subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
}
}
hasWrittenComponent = true;
}
while (optionalCount > 0) {
subpattern += ")?";
optionalCount--;
}
return subpattern;
}
function replaceWildcardCharacter(match, singleAsteriskRegexFragment) {
return match === "*" ? singleAsteriskRegexFragment : match === "?" ? "[^/]" : "\\" + match;
}
/** @param path directory of the tsconfig.json */
function getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory) {
path = (0, path_1.normalizePath)(path);
currentDirectory = (0, path_1.normalizePath)(currentDirectory);
const absolutePath = (0, path_1.combinePaths)(currentDirectory, path);
return {
includeFilePatterns: (0, core_1.map)(getRegularExpressionsForWildcards(includes, absolutePath, "files"), pattern => `^${pattern}$`),
includeFilePattern: getRegularExpressionForWildcard(includes, absolutePath, "files"),
includeDirectoryPattern: getRegularExpressionForWildcard(includes, absolutePath, "directories"),
excludePattern: getRegularExpressionForWildcard(excludes, absolutePath, "exclude"),
basePaths: getBasePaths(path, includes, useCaseSensitiveFileNames)
};
}
function getRegexFromPattern(pattern, useCaseSensitiveFileNames) {
return new RegExp(pattern, useCaseSensitiveFileNames ? "" : "i");
}
/** @param path directory of the tsconfig.json */
function matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory, depth, getFileSystemEntries, realpath) {
path = (0, path_1.normalizePath)(path);
currentDirectory = (0, path_1.normalizePath)(currentDirectory);
const patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory);
const includeFileRegexes = patterns.includeFilePatterns && patterns.includeFilePatterns.map(pattern => getRegexFromPattern(pattern, useCaseSensitiveFileNames));
const includeDirectoryRegex = patterns.includeDirectoryPattern && getRegexFromPattern(patterns.includeDirectoryPattern, useCaseSensitiveFileNames);
const excludeRegex = patterns.excludePattern && getRegexFromPattern(patterns.excludePattern, useCaseSensitiveFileNames);
// Associate an array of results with each include regex. This keeps results in order of the "include" order.
// If there are no "includes", then just put everything in results[0].
const results = includeFileRegexes ? includeFileRegexes.map(() => []) : [[]];
const visited = new Map();
const toCanonical = (0, core_1.createGetCanonicalFileName)(useCaseSensitiveFileNames);
for (const basePath of patterns.basePaths) {
visitDirectory(basePath, (0, path_1.combinePaths)(currentDirectory, basePath), depth);
}
return (0, core_1.flatten)(results);
function visitDirectory(path, absolutePath, depth) {
const canonicalPath = toCanonical(realpath(absolutePath));
if (visited.has(canonicalPath)) {
return;
}
visited.set(canonicalPath, true);
const { files, directories } = getFileSystemEntries(path);
for (const current of (0, core_1.sort)(files, core_1.compareStringsCaseSensitive)) {
const name = (0, path_1.combinePaths)(path, current);
const absoluteName = (0, path_1.combinePaths)(absolutePath, current);
if (extensions && !(0, path_1.fileExtensionIsOneOf)(name, extensions)) {
continue;
}
if (excludeRegex && excludeRegex.test(absoluteName)) {
continue;
}
if (!includeFileRegexes) {
results[0].push(name);
}
else {
const includeIndex = (0, core_1.findIndex)(includeFileRegexes, re => re.test(absoluteName));
if (includeIndex !== -1) {
results[includeIndex].push(name);
}
}
}
if (depth !== undefined) {
depth--;
if (depth === 0) {
return;
}
}
for (const current of (0, core_1.sort)(directories, core_1.compareStringsCaseSensitive)) {
const name = (0, path_1.combinePaths)(path, current);
const absoluteName = (0, path_1.combinePaths)(absolutePath, current);
if ((!includeDirectoryRegex || includeDirectoryRegex.test(absoluteName)) &&
(!excludeRegex || !excludeRegex.test(absoluteName))) {
visitDirectory(name, absoluteName, depth);
}
}
}
}
exports.matchFiles = matchFiles;
/**
* Computes the unique non-wildcard base paths amongst the provided include patterns.
*/
function getBasePaths(path, includes, useCaseSensitiveFileNames) {
// Storage for our results in the form of literal paths (e.g. the paths as written by the user).
const basePaths = [path];
if (includes) {
// Storage for literal base paths amongst the include patterns.
const includeBasePaths = [];
for (const include of includes) {
// We also need to check the relative paths by converting them to absolute and normalizing
// in case they escape the base path (e.g "..\somedirectory")
const absolute = (0, path_1.isRootedDiskPath)(include) ? include : (0, path_1.normalizePath)((0, path_1.combinePaths)(path, include));
// Append the literal and canonical candidate base paths.
includeBasePaths.push(getIncludeBasePath(absolute));
}
// Sort the offsets array using either the literal or canonical path representations.
includeBasePaths.sort((0, core_1.getStringComparer)(!useCaseSensitiveFileNames));
// Iterate over each include base path and include unique base paths that are not a
// subpath of an existing base path
for (const includeBasePath of includeBasePaths) {
if ((0, core_1.every)(basePaths, basePath => !(0, path_1.containsPath)(basePath, includeBasePath, path, !useCaseSensitiveFileNames))) {
basePaths.push(includeBasePath);
}
}
}
return basePaths;
}
function getIncludeBasePath(absolute) {
const wildcardOffset = (0, core_1.indexOfAnyCharCode)(absolute, wildcardCharCodes);
if (wildcardOffset < 0) {
// No "*" or "?" in the path
return !(0, path_1.hasExtension)(absolute)
? absolute
: (0, path_1.removeTrailingDirectorySeparator)((0, path_1.getDirectoryPath)(absolute));
}
return absolute.substring(0, absolute.lastIndexOf(path_1.directorySeparator, wildcardOffset));
}
//# sourceMappingURL=utilities.js.map