push all website files

This commit is contained in:
Jacob Levine
2019-01-06 13:14:45 -06:00
parent d7301e26c3
commit d2d5d4c04e
15662 changed files with 2166516 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
/// <reference types="node" />
import * as fs from 'fs';
import FileSystem from './fs';
import { FilterFunction } from '@mrmlnc/readdir-enhanced';
import { Entry } from '../types/entries';
import { Pattern } from '../types/patterns';
export default class FileSystemStream extends FileSystem<NodeJS.ReadableStream> {
/**
* Use stream API to read entries for Task.
*/
read(patterns: string[], filter: FilterFunction): NodeJS.ReadableStream;
/**
* Return entry for the provided path.
*/
getEntry(filepath: string, pattern: Pattern): Promise<Entry | null>;
/**
* Return fs.Stats for the provided path.
*/
getStat(filepath: string): Promise<fs.Stats>;
}

View File

@@ -0,0 +1,64 @@
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var stream = require("stream");
var fsStat = require("@nodelib/fs.stat");
var fs_1 = require("./fs");
var FileSystemStream = /** @class */ (function (_super) {
__extends(FileSystemStream, _super);
function FileSystemStream() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Use stream API to read entries for Task.
*/
FileSystemStream.prototype.read = function (patterns, filter) {
var _this = this;
var filepaths = patterns.map(this.getFullEntryPath, this);
var transform = new stream.Transform({ objectMode: true });
transform._transform = function (index, _enc, done) {
return _this.getEntry(filepaths[index], patterns[index]).then(function (entry) {
if (entry !== null && filter(entry)) {
transform.push(entry);
}
if (index === filepaths.length - 1) {
transform.end();
}
done();
});
};
for (var i = 0; i < filepaths.length; i++) {
transform.write(i);
}
return transform;
};
/**
* Return entry for the provided path.
*/
FileSystemStream.prototype.getEntry = function (filepath, pattern) {
var _this = this;
return this.getStat(filepath)
.then(function (stat) { return _this.makeEntry(stat, pattern); })
.catch(function () { return null; });
};
/**
* Return fs.Stats for the provided path.
*/
FileSystemStream.prototype.getStat = function (filepath) {
return fsStat.stat(filepath, { throwErrorOnBrokenSymlinks: false });
};
return FileSystemStream;
}(fs_1.default));
exports.default = FileSystemStream;

View File

@@ -0,0 +1,20 @@
/// <reference types="node" />
import * as fs from 'fs';
import FileSystem from './fs';
import { FilterFunction } from '@mrmlnc/readdir-enhanced';
import { Entry } from '../types/entries';
import { Pattern } from '../types/patterns';
export default class FileSystemSync extends FileSystem<Entry[]> {
/**
* Use sync API to read entries for Task.
*/
read(patterns: string[], filter: FilterFunction): Entry[];
/**
* Return entry for the provided path.
*/
getEntry(filepath: string, pattern: Pattern): Entry | null;
/**
* Return fs.Stats for the provided path.
*/
getStat(filepath: string): fs.Stats;
}

View File

@@ -0,0 +1,59 @@
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var fsStat = require("@nodelib/fs.stat");
var fs_1 = require("./fs");
var FileSystemSync = /** @class */ (function (_super) {
__extends(FileSystemSync, _super);
function FileSystemSync() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Use sync API to read entries for Task.
*/
FileSystemSync.prototype.read = function (patterns, filter) {
var _this = this;
var entries = [];
patterns.forEach(function (pattern) {
var filepath = _this.getFullEntryPath(pattern);
var entry = _this.getEntry(filepath, pattern);
if (entry === null || !filter(entry)) {
return;
}
entries.push(entry);
});
return entries;
};
/**
* Return entry for the provided path.
*/
FileSystemSync.prototype.getEntry = function (filepath, pattern) {
try {
var stat = this.getStat(filepath);
return this.makeEntry(stat, pattern);
}
catch (err) {
return null;
}
};
/**
* Return fs.Stats for the provided path.
*/
FileSystemSync.prototype.getStat = function (filepath) {
return fsStat.statSync(filepath, { throwErrorOnBrokenSymlinks: false });
};
return FileSystemSync;
}(fs_1.default));
exports.default = FileSystemSync;

View File

@@ -0,0 +1,22 @@
/// <reference types="node" />
import * as fs from 'fs';
import { FilterFunction } from '@mrmlnc/readdir-enhanced';
import { IOptions } from '../managers/options';
import { Entry } from '../types/entries';
import { Pattern } from '../types/patterns';
export default abstract class FileSystem<T> {
private readonly options;
constructor(options: IOptions);
/**
* The main logic of reading the entries that must be implemented by each adapter.
*/
abstract read(filepaths: string[], filter: FilterFunction): T;
/**
* Return full path to entry.
*/
getFullEntryPath(filepath: string): string;
/**
* Return an implementation of the Entry interface.
*/
makeEntry(stat: fs.Stats, pattern: Pattern): Entry;
}

View File

@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
var FileSystem = /** @class */ (function () {
function FileSystem(options) {
this.options = options;
}
/**
* Return full path to entry.
*/
FileSystem.prototype.getFullEntryPath = function (filepath) {
return path.resolve(this.options.cwd, filepath);
};
/**
* Return an implementation of the Entry interface.
*/
FileSystem.prototype.makeEntry = function (stat, pattern) {
return Object.assign(stat, {
path: pattern,
depth: pattern.split('/').length
});
};
return FileSystem;
}());
exports.default = FileSystem;

View File

@@ -0,0 +1,21 @@
/// <reference types="node" />
import { IPartialOptions } from './managers/options';
import { ITask } from './managers/tasks';
import { EntryItem } from './types/entries';
import { Pattern } from './types/patterns';
/**
* Synchronous API.
*/
export declare function sync(source: Pattern | Pattern[], opts?: IPartialOptions): EntryItem[];
/**
* Asynchronous API.
*/
export declare function async(source: Pattern | Pattern[], opts?: IPartialOptions): Promise<EntryItem[]>;
/**
* Stream API.
*/
export declare function stream(source: Pattern | Pattern[], opts?: IPartialOptions): NodeJS.ReadableStream;
/**
* Return a set of tasks based on provided patterns.
*/
export declare function generateTasks(source: Pattern | Pattern[], opts?: IPartialOptions): ITask[];

71
website/functions/node_modules/fast-glob/out/index.js generated vendored Normal file
View File

@@ -0,0 +1,71 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var merge2 = require("merge2");
var optionsManager = require("./managers/options");
var taskManager = require("./managers/tasks");
var reader_async_1 = require("./providers/reader-async");
var reader_stream_1 = require("./providers/reader-stream");
var reader_sync_1 = require("./providers/reader-sync");
var arrayUtils = require("./utils/array");
/**
* Synchronous API.
*/
function sync(source, opts) {
assertPatternsInput(source);
var works = getWorks(source, reader_sync_1.default, opts);
return arrayUtils.flatten(works);
}
exports.sync = sync;
/**
* Asynchronous API.
*/
function async(source, opts) {
try {
assertPatternsInput(source);
}
catch (error) {
return Promise.reject(error);
}
var works = getWorks(source, reader_async_1.default, opts);
return Promise.all(works).then(arrayUtils.flatten);
}
exports.async = async;
/**
* Stream API.
*/
function stream(source, opts) {
assertPatternsInput(source);
var works = getWorks(source, reader_stream_1.default, opts);
return merge2(works);
}
exports.stream = stream;
/**
* Return a set of tasks based on provided patterns.
*/
function generateTasks(source, opts) {
assertPatternsInput(source);
var patterns = [].concat(source);
var options = optionsManager.prepare(opts);
return taskManager.generate(patterns, options);
}
exports.generateTasks = generateTasks;
/**
* Returns a set of works based on provided tasks and class of the reader.
*/
function getWorks(source, _Reader, opts) {
var patterns = [].concat(source);
var options = optionsManager.prepare(opts);
var tasks = taskManager.generate(patterns, options);
var reader = new _Reader(options);
return tasks.map(reader.read, reader);
}
function assertPatternsInput(source) {
if ([].concat(source).every(isString)) {
return;
}
throw new TypeError('Patterns must be a string or an array of strings');
}
function isString(source) {
/* tslint:disable-next-line strict-type-predicates */
return typeof source === 'string';
}

View File

@@ -0,0 +1,94 @@
import { EntryItem } from '../types/entries';
import { Pattern } from '../types/patterns';
export declare type TransformFunction<T> = (entry: EntryItem) => T;
export interface IOptions<T = EntryItem> {
/**
* The current working directory in which to search.
*/
cwd: string;
/**
* The deep option can be set to true to traverse the entire directory structure,
* or it can be set to a number to only traverse that many levels deep.
*/
deep: number | boolean;
/**
* Add an array of glob patterns to exclude matches.
*/
ignore: Pattern[];
/**
* Allow patterns to match filenames starting with a period (files & directories),
* even if the pattern does not explicitly have a period in that spot.
*/
dot: boolean;
/**
* Return `fs.Stats` with `path` property instead of file path.
*/
stats: boolean;
/**
* Return only files.
*/
onlyFiles: boolean;
/**
* Return only directories.
*/
onlyDirectories: boolean;
/**
* Follow symlinked directories when expanding `**` patterns.
*/
followSymlinkedDirectories: boolean;
/**
* Prevent duplicate results.
*/
unique: boolean;
/**
* Add a `/` character to directory entries.
*/
markDirectories: boolean;
/**
* Return absolute paths for matched entries.
*/
absolute: boolean;
/**
* Disable expansion of brace patterns.
*/
nobrace: boolean;
/**
* Enable expansion of brace patterns.
*/
brace: boolean;
/**
* Disable matching with globstars (`**`).
*/
noglobstar: boolean;
/**
* Enable matching with globstars (`**`).
*/
globstar: boolean;
/**
* Disable extglob support, so that extglobs are regarded as literal characters.
*/
noext: boolean;
/**
* Enable extglob support, so that extglobs are regarded as literal characters.
*/
extension: boolean;
/**
* Disable a case-insensitive regex for matching files.
*/
nocase: boolean;
/**
* Enable a case-insensitive regex for matching files.
*/
case: boolean;
/**
* Allow glob patterns without slashes to match a file path based on its basename.
* For example, `a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
*/
matchBase: boolean;
/**
* Allows you to transform a path or `fs.Stats` object before sending to the array.
*/
transform: TransformFunction<T> | null;
}
export declare type IPartialOptions<T = EntryItem> = Partial<IOptions<T>>;
export declare function prepare(options?: IPartialOptions): IOptions;

View File

@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function prepare(options) {
var opts = Object.assign({
cwd: process.cwd(),
deep: true,
ignore: [],
dot: false,
stats: false,
onlyFiles: true,
onlyDirectories: false,
followSymlinkedDirectories: true,
unique: true,
markDirectories: false,
absolute: false,
nobrace: false,
brace: true,
noglobstar: false,
globstar: true,
noext: false,
extension: true,
nocase: false,
case: true,
matchBase: false,
transform: null
}, options);
if (opts.onlyDirectories) {
opts.onlyFiles = false;
}
opts.brace = !opts.nobrace;
opts.globstar = !opts.noglobstar;
opts.extension = !opts.noext;
opts.case = !opts.nocase;
if (options) {
opts.brace = ('brace' in options ? options.brace : opts.brace);
opts.globstar = ('globstar' in options ? options.globstar : opts.globstar);
opts.extension = ('extension' in options ? options.extension : opts.extension);
opts.case = ('case' in options ? options.case : opts.case);
}
return opts;
}
exports.prepare = prepare;

View File

@@ -0,0 +1,37 @@
import { Pattern, PatternsGroup } from '../types/patterns';
import { IOptions } from './options';
export interface ITask {
base: string;
dynamic: boolean;
patterns: Pattern[];
positive: Pattern[];
negative: Pattern[];
}
/**
* Generate tasks based on parent directory of each pattern.
*/
export declare function generate(patterns: Pattern[], options: IOptions): ITask[];
/**
* Convert patterns to tasks based on parent directory of each pattern.
*/
export declare function convertPatternsToTasks(positive: Pattern[], negative: Pattern[], dynamic: boolean): ITask[];
/**
* Return only positive patterns.
*/
export declare function getPositivePatterns(patterns: Pattern[]): Pattern[];
/**
* Return only negative patterns.
*/
export declare function getNegativePatternsAsPositive(patterns: Pattern[], ignore: Pattern[]): Pattern[];
/**
* Group patterns by base directory of each pattern.
*/
export declare function groupPatternsByBaseDirectory(patterns: Pattern[]): PatternsGroup;
/**
* Convert group of patterns to tasks.
*/
export declare function convertPatternGroupsToTasks(positive: PatternsGroup, negative: Pattern[], dynamic: boolean): ITask[];
/**
* Create a task for positive and negative patterns.
*/
export declare function convertPatternGroupToTask(base: string, positive: Pattern[], negative: Pattern[], dynamic: boolean): ITask;

View File

@@ -0,0 +1,86 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var patternUtils = require("../utils/pattern");
/**
* Generate tasks based on parent directory of each pattern.
*/
function generate(patterns, options) {
var unixPatterns = patterns.map(patternUtils.unixifyPattern);
var unixIgnore = options.ignore.map(patternUtils.unixifyPattern);
var positivePatterns = getPositivePatterns(unixPatterns);
var negativePatterns = getNegativePatternsAsPositive(unixPatterns, unixIgnore);
var staticPatterns = positivePatterns.filter(patternUtils.isStaticPattern);
var dynamicPatterns = positivePatterns.filter(patternUtils.isDynamicPattern);
var staticTasks = convertPatternsToTasks(staticPatterns, negativePatterns, /* dynamic */ false);
var dynamicTasks = convertPatternsToTasks(dynamicPatterns, negativePatterns, /* dynamic */ true);
return staticTasks.concat(dynamicTasks);
}
exports.generate = generate;
/**
* Convert patterns to tasks based on parent directory of each pattern.
*/
function convertPatternsToTasks(positive, negative, dynamic) {
var positivePatternsGroup = groupPatternsByBaseDirectory(positive);
// When we have a global group there is no reason to divide the patterns into independent tasks.
// In this case, the global task covers the rest.
if ('.' in positivePatternsGroup) {
var task = convertPatternGroupToTask('.', positive, negative, dynamic);
return [task];
}
return convertPatternGroupsToTasks(positivePatternsGroup, negative, dynamic);
}
exports.convertPatternsToTasks = convertPatternsToTasks;
/**
* Return only positive patterns.
*/
function getPositivePatterns(patterns) {
return patternUtils.getPositivePatterns(patterns);
}
exports.getPositivePatterns = getPositivePatterns;
/**
* Return only negative patterns.
*/
function getNegativePatternsAsPositive(patterns, ignore) {
var negative = patternUtils.getNegativePatterns(patterns).concat(ignore);
var positive = negative.map(patternUtils.convertToPositivePattern);
return positive;
}
exports.getNegativePatternsAsPositive = getNegativePatternsAsPositive;
/**
* Group patterns by base directory of each pattern.
*/
function groupPatternsByBaseDirectory(patterns) {
return patterns.reduce(function (collection, pattern) {
var base = patternUtils.getBaseDirectory(pattern);
if (base in collection) {
collection[base].push(pattern);
}
else {
collection[base] = [pattern];
}
return collection;
}, {});
}
exports.groupPatternsByBaseDirectory = groupPatternsByBaseDirectory;
/**
* Convert group of patterns to tasks.
*/
function convertPatternGroupsToTasks(positive, negative, dynamic) {
return Object.keys(positive).map(function (base) {
return convertPatternGroupToTask(base, positive[base], negative, dynamic);
});
}
exports.convertPatternGroupsToTasks = convertPatternGroupsToTasks;
/**
* Create a task for positive and negative patterns.
*/
function convertPatternGroupToTask(base, positive, negative, dynamic) {
return {
base: base,
dynamic: dynamic,
patterns: [].concat(positive, negative.map(patternUtils.convertToNegativePattern)),
positive: positive,
negative: negative
};
}
exports.convertPatternGroupToTask = convertPatternGroupToTask;

View File

@@ -0,0 +1,45 @@
import micromatch = require('micromatch');
import { IOptions } from '../../managers/options';
import { FilterFunction } from '@mrmlnc/readdir-enhanced';
import { Pattern } from '../../types/patterns';
export default class DeepFilter {
private readonly options;
private readonly micromatchOptions;
constructor(options: IOptions, micromatchOptions: micromatch.Options);
/**
* Returns filter for directories.
*/
getFilter(positive: Pattern[], negative: Pattern[]): FilterFunction;
/**
* Returns max depth of the provided patterns.
*/
private getMaxPatternDepth;
/**
* Returns RegExp's for patterns that can affect the depth of reading.
*/
private getNegativePatternsRe;
/**
* Returns «true» for directory that should be read.
*/
private filter;
/**
* Returns «true» when the «deep» option is disabled or number and depth of the entry is greater that the option value.
*/
private isSkippedByDeepOption;
/**
* Returns «true» when depth parameter is not an Infinity and entry depth greater that the parameter value.
*/
private isSkippedByMaxPatternDepth;
/**
* Returns «true» for symlinked directory if the «followSymlinkedDirectories» option is disabled.
*/
private isSkippedSymlinkedDirectory;
/**
* Returns «true» for a directory whose name starts with a period if «dot» option is disabled.
*/
private isSkippedDotDirectory;
/**
* Returns «true» for a directory whose path math to any negative pattern.
*/
private isSkippedByNegativePatterns;
}

View File

@@ -0,0 +1,83 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var pathUtils = require("../../utils/path");
var patternUtils = require("../../utils/pattern");
var DeepFilter = /** @class */ (function () {
function DeepFilter(options, micromatchOptions) {
this.options = options;
this.micromatchOptions = micromatchOptions;
}
/**
* Returns filter for directories.
*/
DeepFilter.prototype.getFilter = function (positive, negative) {
var _this = this;
var maxPatternDepth = this.getMaxPatternDepth(positive);
var negativeRe = this.getNegativePatternsRe(negative);
return function (entry) { return _this.filter(entry, negativeRe, maxPatternDepth); };
};
/**
* Returns max depth of the provided patterns.
*/
DeepFilter.prototype.getMaxPatternDepth = function (patterns) {
var globstar = patterns.some(patternUtils.hasGlobStar);
return globstar ? Infinity : patternUtils.getMaxNaivePatternsDepth(patterns);
};
/**
* Returns RegExp's for patterns that can affect the depth of reading.
*/
DeepFilter.prototype.getNegativePatternsRe = function (patterns) {
var affectDepthOfReadingPatterns = patterns.filter(patternUtils.isAffectDepthOfReadingPattern);
return patternUtils.convertPatternsToRe(affectDepthOfReadingPatterns, this.micromatchOptions);
};
/**
* Returns «true» for directory that should be read.
*/
DeepFilter.prototype.filter = function (entry, negativeRe, maxPatternDepth) {
if (this.isSkippedByDeepOption(entry.depth)) {
return false;
}
if (this.isSkippedByMaxPatternDepth(entry.depth, maxPatternDepth)) {
return false;
}
if (this.isSkippedSymlinkedDirectory(entry)) {
return false;
}
if (this.isSkippedDotDirectory(entry)) {
return false;
}
return this.isSkippedByNegativePatterns(entry, negativeRe);
};
/**
* Returns «true» when the «deep» option is disabled or number and depth of the entry is greater that the option value.
*/
DeepFilter.prototype.isSkippedByDeepOption = function (entryDepth) {
return !this.options.deep || (typeof this.options.deep === 'number' && entryDepth >= this.options.deep);
};
/**
* Returns «true» when depth parameter is not an Infinity and entry depth greater that the parameter value.
*/
DeepFilter.prototype.isSkippedByMaxPatternDepth = function (entryDepth, maxPatternDepth) {
return maxPatternDepth !== Infinity && entryDepth >= maxPatternDepth;
};
/**
* Returns «true» for symlinked directory if the «followSymlinkedDirectories» option is disabled.
*/
DeepFilter.prototype.isSkippedSymlinkedDirectory = function (entry) {
return !this.options.followSymlinkedDirectories && entry.isSymbolicLink();
};
/**
* Returns «true» for a directory whose name starts with a period if «dot» option is disabled.
*/
DeepFilter.prototype.isSkippedDotDirectory = function (entry) {
return !this.options.dot && pathUtils.isDotDirectory(entry.path);
};
/**
* Returns «true» for a directory whose path math to any negative pattern.
*/
DeepFilter.prototype.isSkippedByNegativePatterns = function (entry, negativeRe) {
return !patternUtils.matchAny(entry.path, negativeRe);
};
return DeepFilter;
}());
exports.default = DeepFilter;

View File

@@ -0,0 +1,45 @@
import micromatch = require('micromatch');
import { IOptions } from '../../managers/options';
import { FilterFunction } from '@mrmlnc/readdir-enhanced';
import { Pattern } from '../../types/patterns';
export default class DeepFilter {
private readonly options;
private readonly micromatchOptions;
readonly index: Map<string, undefined>;
constructor(options: IOptions, micromatchOptions: micromatch.Options);
/**
* Returns filter for directories.
*/
getFilter(positive: Pattern[], negative: Pattern[]): FilterFunction;
/**
* Returns true if entry must be added to result.
*/
private filter;
/**
* Return true if the entry already has in the cross reader index.
*/
private isDuplicateEntry;
/**
* Create record in the cross reader index.
*/
private createIndexRecord;
/**
* Returns true for non-files if the «onlyFiles» option is enabled.
*/
private onlyFileFilter;
/**
* Returns true for non-directories if the «onlyDirectories» option is enabled.
*/
private onlyDirectoryFilter;
/**
* Return true when `absolute` option is enabled and matched to the negative patterns.
*/
private isSkippedByAbsoluteNegativePatterns;
/**
* Return true when entry match to provided patterns.
*
* First, just trying to apply patterns to the path.
* Second, trying to apply patterns to the path with final slash (need to micromatch to support «directory/**» patterns).
*/
private isMatchToPatterns;
}

View File

@@ -0,0 +1,85 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var pathUtils = require("../../utils/path");
var patternUtils = require("../../utils/pattern");
var DeepFilter = /** @class */ (function () {
function DeepFilter(options, micromatchOptions) {
this.options = options;
this.micromatchOptions = micromatchOptions;
this.index = new Map();
}
/**
* Returns filter for directories.
*/
DeepFilter.prototype.getFilter = function (positive, negative) {
var _this = this;
var positiveRe = patternUtils.convertPatternsToRe(positive, this.micromatchOptions);
var negativeRe = patternUtils.convertPatternsToRe(negative, this.micromatchOptions);
return function (entry) { return _this.filter(entry, positiveRe, negativeRe); };
};
/**
* Returns true if entry must be added to result.
*/
DeepFilter.prototype.filter = function (entry, positiveRe, negativeRe) {
// Exclude duplicate results
if (this.options.unique) {
if (this.isDuplicateEntry(entry)) {
return false;
}
this.createIndexRecord(entry);
}
// Filter files and directories by options
if (this.onlyFileFilter(entry) || this.onlyDirectoryFilter(entry)) {
return false;
}
if (this.isSkippedByAbsoluteNegativePatterns(entry, negativeRe)) {
return false;
}
return this.isMatchToPatterns(entry.path, positiveRe) && !this.isMatchToPatterns(entry.path, negativeRe);
};
/**
* Return true if the entry already has in the cross reader index.
*/
DeepFilter.prototype.isDuplicateEntry = function (entry) {
return this.index.has(entry.path);
};
/**
* Create record in the cross reader index.
*/
DeepFilter.prototype.createIndexRecord = function (entry) {
this.index.set(entry.path, undefined);
};
/**
* Returns true for non-files if the «onlyFiles» option is enabled.
*/
DeepFilter.prototype.onlyFileFilter = function (entry) {
return this.options.onlyFiles && !entry.isFile();
};
/**
* Returns true for non-directories if the «onlyDirectories» option is enabled.
*/
DeepFilter.prototype.onlyDirectoryFilter = function (entry) {
return this.options.onlyDirectories && !entry.isDirectory();
};
/**
* Return true when `absolute` option is enabled and matched to the negative patterns.
*/
DeepFilter.prototype.isSkippedByAbsoluteNegativePatterns = function (entry, negativeRe) {
if (!this.options.absolute) {
return false;
}
var fullpath = pathUtils.makeAbsolute(this.options.cwd, entry.path);
return this.isMatchToPatterns(fullpath, negativeRe);
};
/**
* Return true when entry match to provided patterns.
*
* First, just trying to apply patterns to the path.
* Second, trying to apply patterns to the path with final slash (need to micromatch to support «directory/**» patterns).
*/
DeepFilter.prototype.isMatchToPatterns = function (filepath, patternsRe) {
return patternUtils.matchAny(filepath, patternsRe) || patternUtils.matchAny(filepath + '/', patternsRe);
};
return DeepFilter;
}());
exports.default = DeepFilter;

View File

@@ -0,0 +1,28 @@
/// <reference types="node" />
import * as readdir from '@mrmlnc/readdir-enhanced';
import Reader from './reader';
import FileSystemStream from '../adapters/fs-stream';
import { ITask } from '../managers/tasks';
import { EntryItem } from '../types/entries';
export default class ReaderAsync extends Reader<Promise<EntryItem[]>> {
/**
* Returns FileSystem adapter.
*/
readonly fsAdapter: FileSystemStream;
/**
* Use async API to read entries for Task.
*/
read(task: ITask): Promise<EntryItem[]>;
/**
* Returns founded paths.
*/
api(root: string, task: ITask, options: readdir.Options): NodeJS.ReadableStream;
/**
* Api for dynamic tasks.
*/
dynamicApi(root: string, options: readdir.Options): NodeJS.ReadableStream;
/**
* Api for static tasks.
*/
staticApi(task: ITask, options: readdir.Options): NodeJS.ReadableStream;
}

View File

@@ -0,0 +1,75 @@
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var readdir = require("@mrmlnc/readdir-enhanced");
var reader_1 = require("./reader");
var fs_stream_1 = require("../adapters/fs-stream");
var ReaderAsync = /** @class */ (function (_super) {
__extends(ReaderAsync, _super);
function ReaderAsync() {
return _super !== null && _super.apply(this, arguments) || this;
}
Object.defineProperty(ReaderAsync.prototype, "fsAdapter", {
/**
* Returns FileSystem adapter.
*/
get: function () {
return new fs_stream_1.default(this.options);
},
enumerable: true,
configurable: true
});
/**
* Use async API to read entries for Task.
*/
ReaderAsync.prototype.read = function (task) {
var _this = this;
var root = this.getRootDirectory(task);
var options = this.getReaderOptions(task);
var entries = [];
return new Promise(function (resolve, reject) {
var stream = _this.api(root, task, options);
stream.on('error', function (err) {
_this.isEnoentCodeError(err) ? resolve([]) : reject(err);
stream.pause();
});
stream.on('data', function (entry) { return entries.push(_this.transform(entry)); });
stream.on('end', function () { return resolve(entries); });
});
};
/**
* Returns founded paths.
*/
ReaderAsync.prototype.api = function (root, task, options) {
if (task.dynamic) {
return this.dynamicApi(root, options);
}
return this.staticApi(task, options);
};
/**
* Api for dynamic tasks.
*/
ReaderAsync.prototype.dynamicApi = function (root, options) {
return readdir.readdirStreamStat(root, options);
};
/**
* Api for static tasks.
*/
ReaderAsync.prototype.staticApi = function (task, options) {
return this.fsAdapter.read(task.patterns, options.filter);
};
return ReaderAsync;
}(reader_1.default));
exports.default = ReaderAsync;

View File

@@ -0,0 +1,27 @@
/// <reference types="node" />
import * as readdir from '@mrmlnc/readdir-enhanced';
import Reader from './reader';
import FileSystemStream from '../adapters/fs-stream';
import { ITask } from '../managers/tasks';
export default class ReaderStream extends Reader<NodeJS.ReadableStream> {
/**
* Returns FileSystem adapter.
*/
readonly fsAdapter: FileSystemStream;
/**
* Use stream API to read entries for Task.
*/
read(task: ITask): NodeJS.ReadableStream;
/**
* Returns founded paths.
*/
api(root: string, task: ITask, options: readdir.Options): NodeJS.ReadableStream;
/**
* Api for dynamic tasks.
*/
dynamicApi(root: string, options: readdir.Options): NodeJS.ReadableStream;
/**
* Api for static tasks.
*/
staticApi(task: ITask, options: readdir.Options): NodeJS.ReadableStream;
}

View File

@@ -0,0 +1,83 @@
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var stream = require("stream");
var readdir = require("@mrmlnc/readdir-enhanced");
var reader_1 = require("./reader");
var fs_stream_1 = require("../adapters/fs-stream");
var TransformStream = /** @class */ (function (_super) {
__extends(TransformStream, _super);
function TransformStream(reader) {
var _this = _super.call(this, { objectMode: true }) || this;
_this.reader = reader;
return _this;
}
TransformStream.prototype._transform = function (entry, _encoding, callback) {
callback(null, this.reader.transform(entry));
};
return TransformStream;
}(stream.Transform));
var ReaderStream = /** @class */ (function (_super) {
__extends(ReaderStream, _super);
function ReaderStream() {
return _super !== null && _super.apply(this, arguments) || this;
}
Object.defineProperty(ReaderStream.prototype, "fsAdapter", {
/**
* Returns FileSystem adapter.
*/
get: function () {
return new fs_stream_1.default(this.options);
},
enumerable: true,
configurable: true
});
/**
* Use stream API to read entries for Task.
*/
ReaderStream.prototype.read = function (task) {
var _this = this;
var root = this.getRootDirectory(task);
var options = this.getReaderOptions(task);
var transform = new TransformStream(this);
var readable = this.api(root, task, options);
return readable
.once('error', function (err) { return _this.isEnoentCodeError(err) ? null : transform.emit('error', err); })
.pipe(transform);
};
/**
* Returns founded paths.
*/
ReaderStream.prototype.api = function (root, task, options) {
if (task.dynamic) {
return this.dynamicApi(root, options);
}
return this.staticApi(task, options);
};
/**
* Api for dynamic tasks.
*/
ReaderStream.prototype.dynamicApi = function (root, options) {
return readdir.readdirStreamStat(root, options);
};
/**
* Api for static tasks.
*/
ReaderStream.prototype.staticApi = function (task, options) {
return this.fsAdapter.read(task.patterns, options.filter);
};
return ReaderStream;
}(reader_1.default));
exports.default = ReaderStream;

View File

@@ -0,0 +1,27 @@
import * as readdir from '@mrmlnc/readdir-enhanced';
import Reader from './reader';
import FileSystemSync from '../adapters/fs-sync';
import { ITask } from '../managers/tasks';
import { Entry, EntryItem } from '../types/entries';
export default class ReaderSync extends Reader<EntryItem[]> {
/**
* Returns FileSystem adapter.
*/
readonly fsAdapter: FileSystemSync;
/**
* Use sync API to read entries for Task.
*/
read(task: ITask): EntryItem[];
/**
* Returns founded paths.
*/
api(root: string, task: ITask, options: readdir.Options): Entry[];
/**
* Api for dynamic tasks.
*/
dynamicApi(root: string, options: readdir.Options): Entry[];
/**
* Api for static tasks.
*/
staticApi(task: ITask, options: readdir.Options): Entry[];
}

View File

@@ -0,0 +1,74 @@
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var readdir = require("@mrmlnc/readdir-enhanced");
var reader_1 = require("./reader");
var fs_sync_1 = require("../adapters/fs-sync");
var ReaderSync = /** @class */ (function (_super) {
__extends(ReaderSync, _super);
function ReaderSync() {
return _super !== null && _super.apply(this, arguments) || this;
}
Object.defineProperty(ReaderSync.prototype, "fsAdapter", {
/**
* Returns FileSystem adapter.
*/
get: function () {
return new fs_sync_1.default(this.options);
},
enumerable: true,
configurable: true
});
/**
* Use sync API to read entries for Task.
*/
ReaderSync.prototype.read = function (task) {
var root = this.getRootDirectory(task);
var options = this.getReaderOptions(task);
try {
var entries = this.api(root, task, options);
return entries.map(this.transform, this);
}
catch (err) {
if (this.isEnoentCodeError(err)) {
return [];
}
throw err;
}
};
/**
* Returns founded paths.
*/
ReaderSync.prototype.api = function (root, task, options) {
if (task.dynamic) {
return this.dynamicApi(root, options);
}
return this.staticApi(task, options);
};
/**
* Api for dynamic tasks.
*/
ReaderSync.prototype.dynamicApi = function (root, options) {
return readdir.readdirSyncStat(root, options);
};
/**
* Api for static tasks.
*/
ReaderSync.prototype.staticApi = function (task, options) {
return this.fsAdapter.read(task.patterns, options.filter);
};
return ReaderSync;
}(reader_1.default));
exports.default = ReaderSync;

View File

@@ -0,0 +1,39 @@
/// <reference types="node" />
import micromatch = require('micromatch');
import DeepFilter from './filters/deep';
import EntryFilter from './filters/entry';
import { IOptions } from '../managers/options';
import { ITask } from '../managers/tasks';
import { Options as IReaddirOptions } from '@mrmlnc/readdir-enhanced';
import { Entry, EntryItem } from '../types/entries';
export default abstract class Reader<T> {
readonly options: IOptions;
readonly entryFilter: EntryFilter;
readonly deepFilter: DeepFilter;
private readonly micromatchOptions;
constructor(options: IOptions);
/**
* The main logic of reading the directories that must be implemented by each providers.
*/
abstract read(_task: ITask): T;
/**
* Returns root path to scanner.
*/
getRootDirectory(task: ITask): string;
/**
* Returns options for reader.
*/
getReaderOptions(task: ITask): IReaddirOptions;
/**
* Returns options for micromatch.
*/
getMicromatchOptions(): micromatch.Options;
/**
* Returns transformed entry.
*/
transform(entry: Entry): EntryItem;
/**
* Returns true if error has ENOENT code.
*/
isEnoentCodeError(err: NodeJS.ErrnoException): boolean;
}

View File

@@ -0,0 +1,68 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
var deep_1 = require("./filters/deep");
var entry_1 = require("./filters/entry");
var pathUtil = require("../utils/path");
var Reader = /** @class */ (function () {
function Reader(options) {
this.options = options;
this.micromatchOptions = this.getMicromatchOptions();
this.entryFilter = new entry_1.default(options, this.micromatchOptions);
this.deepFilter = new deep_1.default(options, this.micromatchOptions);
}
/**
* Returns root path to scanner.
*/
Reader.prototype.getRootDirectory = function (task) {
return path.resolve(this.options.cwd, task.base);
};
/**
* Returns options for reader.
*/
Reader.prototype.getReaderOptions = function (task) {
return {
basePath: task.base === '.' ? '' : task.base,
filter: this.entryFilter.getFilter(task.positive, task.negative),
deep: this.deepFilter.getFilter(task.positive, task.negative),
sep: '/'
};
};
/**
* Returns options for micromatch.
*/
Reader.prototype.getMicromatchOptions = function () {
return {
dot: this.options.dot,
nobrace: !this.options.brace,
noglobstar: !this.options.globstar,
noext: !this.options.extension,
nocase: !this.options.case,
matchBase: this.options.matchBase
};
};
/**
* Returns transformed entry.
*/
Reader.prototype.transform = function (entry) {
if (this.options.absolute && !path.isAbsolute(entry.path)) {
entry.path = pathUtil.makeAbsolute(this.options.cwd, entry.path);
}
if (this.options.markDirectories && entry.isDirectory()) {
entry.path += '/';
}
var item = this.options.stats ? entry : entry.path;
if (this.options.transform === null) {
return item;
}
return this.options.transform(item);
};
/**
* Returns true if error has ENOENT code.
*/
Reader.prototype.isEnoentCodeError = function (err) {
return err.code === 'ENOENT';
};
return Reader;
}());
exports.default = Reader;

View File

@@ -0,0 +1,8 @@
/// <reference types="node" />
import * as fs from 'fs';
export interface IEntry extends fs.Stats {
path: string;
depth: number;
}
export declare type EntryItem = string | IEntry;
export declare type Entry = IEntry;

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,3 @@
export declare type Pattern = string;
export declare type PatternRe = RegExp;
export declare type PatternsGroup = Record<string, Pattern[]>;

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,4 @@
/**
* Flatten nested arrays (max depth is 2) into a non-nested array of non-array items.
*/
export declare function flatten<T>(items: T[][]): T[];

View File

@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Flatten nested arrays (max depth is 2) into a non-nested array of non-array items.
*/
function flatten(items) {
return items.reduce(function (collection, item) { return [].concat(collection, item); }, []);
}
exports.flatten = flatten;

View File

@@ -0,0 +1,12 @@
/**
* Returns «true» if the last partial of the path starting with a period.
*/
export declare function isDotDirectory(filepath: string): boolean;
/**
* Convert a windows-like path to a unix-style path.
*/
export declare function normalize(filepath: string): string;
/**
* Returns normalized absolute path of provided filepath.
*/
export declare function makeAbsolute(cwd: string, filepath: string): string;

View File

@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
/**
* Returns «true» if the last partial of the path starting with a period.
*/
function isDotDirectory(filepath) {
return path.basename(filepath).startsWith('.');
}
exports.isDotDirectory = isDotDirectory;
/**
* Convert a windows-like path to a unix-style path.
*/
function normalize(filepath) {
return filepath.replace(/\\/g, '/');
}
exports.normalize = normalize;
/**
* Returns normalized absolute path of provided filepath.
*/
function makeAbsolute(cwd, filepath) {
if (path.isAbsolute(filepath)) {
return normalize(filepath);
}
var fullpath = path.resolve(cwd, filepath);
return normalize(fullpath);
}
exports.makeAbsolute = makeAbsolute;

View File

@@ -0,0 +1,74 @@
import micromatch = require('micromatch');
import { Pattern, PatternRe } from '../types/patterns';
/**
* Return true for static pattern.
*/
export declare function isStaticPattern(pattern: Pattern): boolean;
/**
* Return true for pattern that looks like glob.
*/
export declare function isDynamicPattern(pattern: Pattern): boolean;
/**
* Convert a windows «path» to a unix-style «path».
*/
export declare function unixifyPattern(pattern: Pattern): Pattern;
/**
* Returns negative pattern as positive pattern.
*/
export declare function convertToPositivePattern(pattern: Pattern): Pattern;
/**
* Returns positive pattern as negative pattern.
*/
export declare function convertToNegativePattern(pattern: Pattern): Pattern;
/**
* Return true if provided pattern is negative pattern.
*/
export declare function isNegativePattern(pattern: Pattern): boolean;
/**
* Return true if provided pattern is positive pattern.
*/
export declare function isPositivePattern(pattern: Pattern): boolean;
/**
* Extracts negative patterns from array of patterns.
*/
export declare function getNegativePatterns(patterns: Pattern[]): Pattern[];
/**
* Extracts positive patterns from array of patterns.
*/
export declare function getPositivePatterns(patterns: Pattern[]): Pattern[];
/**
* Extract base directory from provided pattern.
*/
export declare function getBaseDirectory(pattern: Pattern): string;
/**
* Return true if provided pattern has globstar.
*/
export declare function hasGlobStar(pattern: Pattern): boolean;
/**
* Return true if provided pattern ends with slash and globstar.
*/
export declare function endsWithSlashGlobStar(pattern: Pattern): boolean;
/**
* Returns «true» when pattern ends with a slash and globstar or the last partial of the pattern is static pattern.
*/
export declare function isAffectDepthOfReadingPattern(pattern: Pattern): boolean;
/**
* Return naive depth of provided pattern without depth of the base directory.
*/
export declare function getNaiveDepth(pattern: Pattern): number;
/**
* Return max naive depth of provided patterns without depth of the base directory.
*/
export declare function getMaxNaivePatternsDepth(patterns: Pattern[]): number;
/**
* Make RegExp for provided pattern.
*/
export declare function makeRe(pattern: Pattern, options: micromatch.Options): PatternRe;
/**
* Convert patterns to regexps.
*/
export declare function convertPatternsToRe(patterns: Pattern[], options: micromatch.Options): PatternRe[];
/**
* Returns true if the entry match any of the given RegExp's.
*/
export declare function matchAny(entry: string, patternsRe: PatternRe[]): boolean;

View File

@@ -0,0 +1,148 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
var globParent = require("glob-parent");
var isGlob = require("is-glob");
var micromatch = require("micromatch");
var GLOBSTAR = '**';
/**
* Return true for static pattern.
*/
function isStaticPattern(pattern) {
return !isDynamicPattern(pattern);
}
exports.isStaticPattern = isStaticPattern;
/**
* Return true for pattern that looks like glob.
*/
function isDynamicPattern(pattern) {
return isGlob(pattern);
}
exports.isDynamicPattern = isDynamicPattern;
/**
* Convert a windows «path» to a unix-style «path».
*/
function unixifyPattern(pattern) {
return pattern.replace(/\\/g, '/');
}
exports.unixifyPattern = unixifyPattern;
/**
* Returns negative pattern as positive pattern.
*/
function convertToPositivePattern(pattern) {
return isNegativePattern(pattern) ? pattern.slice(1) : pattern;
}
exports.convertToPositivePattern = convertToPositivePattern;
/**
* Returns positive pattern as negative pattern.
*/
function convertToNegativePattern(pattern) {
return '!' + pattern;
}
exports.convertToNegativePattern = convertToNegativePattern;
/**
* Return true if provided pattern is negative pattern.
*/
function isNegativePattern(pattern) {
return pattern.startsWith('!') && pattern[1] !== '(';
}
exports.isNegativePattern = isNegativePattern;
/**
* Return true if provided pattern is positive pattern.
*/
function isPositivePattern(pattern) {
return !isNegativePattern(pattern);
}
exports.isPositivePattern = isPositivePattern;
/**
* Extracts negative patterns from array of patterns.
*/
function getNegativePatterns(patterns) {
return patterns.filter(isNegativePattern);
}
exports.getNegativePatterns = getNegativePatterns;
/**
* Extracts positive patterns from array of patterns.
*/
function getPositivePatterns(patterns) {
return patterns.filter(isPositivePattern);
}
exports.getPositivePatterns = getPositivePatterns;
/**
* Extract base directory from provided pattern.
*/
function getBaseDirectory(pattern) {
return globParent(pattern);
}
exports.getBaseDirectory = getBaseDirectory;
/**
* Return true if provided pattern has globstar.
*/
function hasGlobStar(pattern) {
return pattern.indexOf(GLOBSTAR) !== -1;
}
exports.hasGlobStar = hasGlobStar;
/**
* Return true if provided pattern ends with slash and globstar.
*/
function endsWithSlashGlobStar(pattern) {
return pattern.endsWith('/' + GLOBSTAR);
}
exports.endsWithSlashGlobStar = endsWithSlashGlobStar;
/**
* Returns «true» when pattern ends with a slash and globstar or the last partial of the pattern is static pattern.
*/
function isAffectDepthOfReadingPattern(pattern) {
var basename = path.basename(pattern);
return endsWithSlashGlobStar(pattern) || isStaticPattern(basename);
}
exports.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern;
/**
* Return naive depth of provided pattern without depth of the base directory.
*/
function getNaiveDepth(pattern) {
var base = getBaseDirectory(pattern);
var patternDepth = pattern.split('/').length;
var patternBaseDepth = base.split('/').length;
/**
* This is a hack for pattern that has no base directory.
*
* This is related to the `*\something\*` pattern.
*/
if (base === '.') {
return patternDepth - patternBaseDepth;
}
return patternDepth - patternBaseDepth - 1;
}
exports.getNaiveDepth = getNaiveDepth;
/**
* Return max naive depth of provided patterns without depth of the base directory.
*/
function getMaxNaivePatternsDepth(patterns) {
return patterns.reduce(function (max, pattern) {
var depth = getNaiveDepth(pattern);
return depth > max ? depth : max;
}, 0);
}
exports.getMaxNaivePatternsDepth = getMaxNaivePatternsDepth;
/**
* Make RegExp for provided pattern.
*/
function makeRe(pattern, options) {
return micromatch.makeRe(pattern, options);
}
exports.makeRe = makeRe;
/**
* Convert patterns to regexps.
*/
function convertPatternsToRe(patterns, options) {
return patterns.map(function (pattern) { return makeRe(pattern, options); });
}
exports.convertPatternsToRe = convertPatternsToRe;
/**
* Returns true if the entry match any of the given RegExp's.
*/
function matchAny(entry, patternsRe) {
return patternsRe.some(function (patternRe) { return patternRe.test(entry); });
}
exports.matchAny = matchAny;