Skip to content

Commit

Permalink
feat: add withGlobFunction method
Browse files Browse the repository at this point in the history
  • Loading branch information
43081j authored and thecodrr committed Sep 26, 2024
1 parent 35f1047 commit a3b213c
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 10 deletions.
23 changes: 23 additions & 0 deletions __tests__/fdir.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import mock from "mock-fs";
import { test, beforeEach, TestContext, vi } from "vitest";
import path, { sep } from "path";
import { convertSlashes } from "../src/utils";
import picomatch from "picomatch";

beforeEach(() => {
mock.restore();
Expand Down Expand Up @@ -445,6 +446,28 @@ for (const type of apiTypes) {
t.expect(globFunction).toHaveBeenCalled();
t.expect(files.every((file) => file.endsWith(".js"))).toBeTruthy();
});

test(`[${type}] crawl files that match using a picomatch`, async (t) => {
const globFunction = picomatch;
const api = new fdir({globFunction})
.withBasePath()
.glob("**/*.js")
.crawl("node_modules");
const files = await api[type]();
t.expect(files.every((file) => file.endsWith(".js"))).toBeTruthy();
});

test(`[${type}] using withGlobFunction to set glob`, async (t) => {
const globFunction = vi.fn((glob: string | string[], input: string) => {
return (test: string): boolean => test === input;
});
new fdir()
.withBasePath()
.withGlobFunction(globFunction)
.globWithOptions(["**/*.js"], "bleep")
.crawl("node_modules");
t.expect(globFunction).toHaveBeenCalledWith(["**/*.js"], "bleep");
});
}

test(`[async] crawl directory & use abort signal to abort`, async (t) => {
Expand Down
20 changes: 13 additions & 7 deletions src/builder/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ try {
// do nothing
}

const defaultGlobParams: [PicomatchOptions] = [{dot: true}];

export class Builder<
TReturnType extends Output = PathsOutput,
TGlobFunction extends GlobFunction = typeof picomatch
TGlobFunction = typeof picomatch
> {
private readonly globCache: Record<string, Matcher> = {};
private options: Options<TGlobFunction> = {
Expand All @@ -36,9 +34,11 @@ export class Builder<
pathSeparator: sep,
filters: [],
};
private globFunction?: TGlobFunction;

constructor(options?: Partial<Options<TGlobFunction>>) {
this.options = { ...this.options, ...options };
this.globFunction = this.options.globFunction;
}

group(): Builder<GroupOutput, TGlobFunction> {
Expand Down Expand Up @@ -128,6 +128,12 @@ export class Builder<
return new APIBuilder<TReturnType>(root || ".", this.options);
}

withGlobFunction<TFunc>(fn: TFunc) {
// cast this since we don't have the new type params yet
this.globFunction = fn as unknown as TGlobFunction;
return this as unknown as Builder<TReturnType, TFunc>;
}

/**
* @deprecated Pass options using the constructor instead:
* ```ts
Expand All @@ -142,23 +148,23 @@ export class Builder<
}

glob(...patterns: string[]) {
if (this.options.globFunction) {
if (this.globFunction) {
return this.globWithOptions(patterns);
}
return this.globWithOptions(
patterns,
...defaultGlobParams as unknown as GlobParams<TGlobFunction>
...[{dot: true}] as unknown as GlobParams<TGlobFunction>
);
}

globWithOptions(patterns: string[]): Builder<TReturnType, TGlobFunction>;
globWithOptions(patterns: string[], ...options: GlobParams<TGlobFunction>): Builder<TReturnType, TGlobFunction>;
globWithOptions(patterns: string[], ...options: GlobParams<TGlobFunction>|[]) {
const globFn = this.options.globFunction || (pm as TGlobFunction|null);
const globFn = (this.globFunction || pm) as GlobFunction | null;
/* c8 ignore next 5 */
if (!globFn) {
throw new Error(
`Please install picomatch: "npm i picomatch" to use glob matching.`
'Please specify a glob function to use glob matching.'
);
}

Expand Down
6 changes: 3 additions & 3 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export type ResultCallback<TOutput extends Output> = (
export type FilterPredicate = (path: string, isDirectory: boolean) => boolean;
export type ExcludePredicate = (dirName: string, dirPath: string) => boolean;
export type PathSeparator = "/" | "\\";
export type Options<TGlobFunction extends GlobFunction = GlobFunction> = {
export type Options<TGlobFunction = unknown> = {
includeBasePath?: boolean;
includeDirs?: boolean;
normalizePath?: boolean;
Expand All @@ -65,8 +65,8 @@ export type Options<TGlobFunction extends GlobFunction = GlobFunction> = {

export type GlobMatcher = (test: string) => boolean;
export type GlobFunction =
((glob: string | string[], ...params: never[]) => GlobMatcher);
export type GlobParams<T extends GlobFunction> =
((glob: string | string[], ...params: unknown[]) => GlobMatcher);
export type GlobParams<T> =
T extends (globs: string|string[], ...params: infer TParams extends unknown[]) => GlobMatcher
? TParams
: [];

0 comments on commit a3b213c

Please sign in to comment.