thecodrr / fdir

⚡ The fastest directory crawler & globbing library for NodeJS. Crawls 1m files in < 1s
https://thecodrr.github.io/fdir/
MIT License
1.46k stars 51 forks source link

feat: allow custom glob functions other than picomatch #98

Open 43081j opened 2 months ago

43081j commented 2 months ago

This allows you to pass in your own globFunction rather than picomatch, so we're not forcing a choice here (someone may want to use a simpler library or a newer picomatch).

Example:

function globFunction(
  patterns: string | string[],
) {
  return (test) => {
    // some glob match logic
  };
}

const api = new fdir({globFunction})
  .glob('*.js')
  .crawl(cwd);
const files = await api.withPromise();

benchmark seems to be about the same as before on my machine

this also means the options stay strongly typed for whatever glob function you use i think. some example of that:

interface GlobOptions {
  x: number;
}

declare function globFunction(patterns: string|string[], options?: GlobOptions): GlobMatcher;

const api = new fdir({globFunction});

api.globWithOptions(
  ['*.js'],
  {
    x: 100, // works
    y: 200, // errors, since `GlobOptions` has no such prop
  }
);
43081j commented 2 months ago

happy to update so we have a setter too if that works!

we can have withGlobFunction or some such thing which sets the same property

will wait and see what @thecodrr thinks 👍

43081j commented 2 months ago

should be sorted now 👍

i loosened the types on the way in to unknown and infer the strong types when you call globWithOptions

reason for this is because picomatch exports a conditional type which confuses inference here (we end up with it having a return type of never because the compiler can't infer it)

43081j commented 1 month ago

@thecodrr any chance you can take another look at this?

thecodrr commented 1 month ago

@43081j super busy right now but will take a look tomorrow!

43081j commented 1 month ago

all good. let me know if you need any help

same with the other roadmap stuff you wanted to get done, happy to help

SuperchupuDev commented 3 weeks ago

the documentation.md file should be updated with the new options i think? looks like you missed that

thecodrr commented 3 weeks ago

I think before this can be merged, we should test the API with some other glob matching libraries and see how compatible & easy this is to use. The glob & globWithOptions functions were designed to be very picomatch specific so I am not sure if the current design and implementation still makes sense if other libraries are used.

43081j commented 3 weeks ago

That's true, I'll try it out when I get chance

The types do infer the options parameter but maybe we don't need to do that, and can just rely on people binding it in (instead of having globWithOptions)

43081j commented 2 weeks ago

@thecodrr I tried this with zeptomatch:

 const globFunction = (glob: string) => (path: string): boolean => zeptomatch(glob, path);
 const api = new fdir({globFunction})
   .glob("**/*.js")
   .crawl("node_modules");
 const files = await api.withPromise();

the glob function looks funky here just because zeptomatch doesn't return a factory function, but that's all good. it seems to work fine 👍