From 9a9cf1e53f3033f465d682487c3e23bd61696c37 Mon Sep 17 00:00:00 2001 From: Dimitri Benin Date: Sun, 3 Mar 2019 13:09:30 +0000 Subject: [PATCH] Add TypeScript definition (#111) --- index.d.ts | 123 ++++++++++++++++++++++++++++++++++++++++++++++++ index.js | 5 +- index.test-d.ts | 95 +++++++++++++++++++++++++++++++++++++ package.json | 7 ++- 4 files changed, 227 insertions(+), 3 deletions(-) create mode 100644 index.d.ts create mode 100644 index.test-d.ts diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..8715113 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,123 @@ +import {IOptions as NodeGlobOptions} from 'glob'; +import {Options as FastGlobOptions} from 'fast-glob'; + +export type ExpandDirectoriesOption = + | boolean + | ReadonlyArray + | {files: ReadonlyArray; extensions: ReadonlyArray}; + +export interface GlobbyOptions extends FastGlobOptions { + /** + * If set to `true`, `globby` will automatically glob directories for you. If you define an `Array` it will only glob files that matches the patterns inside the `Array`. You can also define an `Object` with `files` and `extensions` like in the example below. + * + * Note that if you set this option to `false`, you won't get back matched directories unless you set `onlyFiles: false`. + * + * @default true + * + * @example + * + * import globby from 'globby'; + * + * (async () => { + * const paths = await globby('images', { + * expandDirectories: { + * files: ['cat', 'unicorn', '*.jpg'], + * extensions: ['png'] + * } + * }); + * console.log(paths); + * //=> ['cat.png', 'unicorn.png', 'cow.jpg', 'rainbow.jpg'] + * })(); + */ + readonly expandDirectories?: ExpandDirectoriesOption; + + /** + * Respect ignore patterns in `.gitignore` files that apply to the globbed files. + * + * @default false + */ + readonly gitignore?: boolean; +} + +/** + * @param patterns - See supported `minimatch` [patterns](https://github.com/isaacs/minimatch#usage). + * @param options - See the [`fast-glob` options](https://github.com/mrmlnc/fast-glob#options-1) in addition to the ones in this package. + * @returns A `Promise` of matching paths. + */ +export default function globby( + patterns: string | ReadonlyArray, + options?: GlobbyOptions +): Promise; + +/** + * @param patterns - See supported `minimatch` [patterns](https://github.com/isaacs/minimatch#usage). + * @param options - See the [`fast-glob` options](https://github.com/mrmlnc/fast-glob#options-1) in addition to the ones in this package. + * @returns An `Array` of matching paths. + */ +export function sync( + patterns: string | ReadonlyArray, + options?: GlobbyOptions +): string[]; + +export interface GlobTask { + readonly pattern: string; + readonly options: GlobbyOptions; +} + +/** + * Note that you should avoid running the same tasks multiple times as they contain a file system cache. Instead, run this method each time to ensure file system changes are taken into consideration. + * + * @param patterns - See supported `minimatch` [patterns](https://github.com/isaacs/minimatch#usage). + * @param options - See the [`fast-glob` options](https://github.com/mrmlnc/fast-glob#options-1) in addition to the ones in this package. + * @returns An `Array` in the format `{ pattern: string, options: Object }`, which can be passed as arguments to [`fast-glob`](https://github.com/mrmlnc/fast-glob). This is useful for other globbing-related packages. + */ +export function generateGlobTasks( + patterns: string | ReadonlyArray, + options?: GlobbyOptions +): GlobTask[]; + +/** + * Note that the options affect the results. If `noext: true` is set, then `+(a|b)` will not be considered a magic pattern. If the pattern has a brace expansion, like `a/{b/c,x/y}`, then that is considered magical, unless `nobrace: true` is set. + * + * This function is backed by [`node-glob`](https://github.com/isaacs/node-glob#globhasmagicpattern-options). + * + * @param patterns - See supported `minimatch` [patterns](https://github.com/isaacs/minimatch#usage). + * @param options - See the [`node-glob` options](https://github.com/isaacs/node-glob#globhasmagicpattern-options). + * @returns A boolean of whether there are any special glob characters in the `patterns`. + */ +export function hasMagic( + patterns: string | ReadonlyArray, + options?: NodeGlobOptions +): boolean; + +export interface GitignoreOptions { + readonly cwd?: string; + readonly ignore?: ReadonlyArray; +} + +export type FilterFunction = (path: string) => boolean; + +export interface Gitignore { + (options?: GitignoreOptions): Promise; + + /** + * @returns A filter function indicating whether a given path is ignored via a `.gitignore` file. + */ + sync(options?: GitignoreOptions): FilterFunction; +} + +/** + * `.gitignore` files matched by the ignore config are not used for the resulting filter function. + * + * @returns A `Promise` for a filter function indicating whether a given path is ignored via a `.gitignore` file. + * + * @example + * + * import {gitignore} from 'globby'; + * + * (async () => { + * const isIgnored = await gitignore(); + * console.log(isIgnored('some/file')); + * })(); + */ +export const gitignore: Gitignore; diff --git a/index.js b/index.js index c2d785a..8cf5cf8 100644 --- a/index.js +++ b/index.js @@ -75,7 +75,7 @@ const globToTask = task => glob => { }; }; -module.exports = (patterns, options) => { +const globby = (patterns, options) => { let globTasks; try { @@ -106,6 +106,9 @@ module.exports = (patterns, options) => { }); }; +module.exports = globby; +module.exports.default = globby; + module.exports.sync = (patterns, options) => { const globTasks = generateGlobTasks(patterns, options); diff --git a/index.test-d.ts b/index.test-d.ts new file mode 100644 index 0000000..aee3a39 --- /dev/null +++ b/index.test-d.ts @@ -0,0 +1,95 @@ +import {expectType} from 'tsd-check'; +import globby, { + GlobTask, + FilterFunction, + sync as globbySync, + generateGlobTasks, + hasMagic, + gitignore +} from '.'; + +// Globby +expectType>(globby('*.tmp')); +expectType>(globby(['a.tmp', '*.tmp', '!{c,d,e}.tmp'])); + +expectType>(globby('*.tmp', {expandDirectories: false})); +expectType>( + globby('*.tmp', {expandDirectories: ['a*', 'b*']}) +); +expectType>( + globby('*.tmp', { + expandDirectories: { + files: ['a', 'b'], + extensions: ['tmp'] + } + }) +); +expectType>(globby('*.tmp', {gitignore: true})); +expectType>(globby('*.tmp', {ignore: ['**/b.tmp']})); + +// Globby (sync) +expectType(globbySync('*.tmp')); +expectType(globbySync(['a.tmp', '*.tmp', '!{c,d,e}.tmp'])); + +expectType(globbySync('*.tmp', {expandDirectories: false})); +expectType(globbySync('*.tmp', {expandDirectories: ['a*', 'b*']})); +expectType( + globbySync('*.tmp', { + expandDirectories: { + files: ['a', 'b'], + extensions: ['tmp'] + } + }) +); +expectType(globbySync('*.tmp', {gitignore: true})); +expectType(globbySync('*.tmp', {ignore: ['**/b.tmp']})); + +// GenerateGlobTasks +expectType(generateGlobTasks('*.tmp')); +expectType(generateGlobTasks(['a.tmp', '*.tmp', '!{c,d,e}.tmp'])); + +expectType(generateGlobTasks('*.tmp', {expandDirectories: false})); +expectType( + generateGlobTasks('*.tmp', {expandDirectories: ['a*', 'b*']}) +); +expectType( + generateGlobTasks('*.tmp', { + expandDirectories: { + files: ['a', 'b'], + extensions: ['tmp'] + } + }) +); +expectType(generateGlobTasks('*.tmp', {gitignore: true})); +expectType(generateGlobTasks('*.tmp', {ignore: ['**/b.tmp']})); + +// HasMagic +expectType(hasMagic('**')); +expectType(hasMagic(['**', 'path1', 'path2'])); +expectType(hasMagic(['**', 'path1', 'path2'], {noext: true})); + +// Gitignore +expectType>(gitignore()); +expectType>( + gitignore({ + cwd: __dirname + }) +); +expectType>( + gitignore({ + ignore: ['**/b.tmp'] + }) +); + +// Gitignore (sync) +expectType(gitignore.sync()); +expectType( + gitignore.sync({ + cwd: __dirname + }) +); +expectType( + gitignore.sync({ + ignore: ['**/b.tmp'] + }) +); diff --git a/package.json b/package.json index 5f57eb8..a975550 100644 --- a/package.json +++ b/package.json @@ -14,11 +14,12 @@ }, "scripts": { "bench": "npm update glob-stream fast-glob && matcha bench.js", - "test": "xo && ava" + "test": "xo && ava && tsd-check" }, "files": [ "index.js", - "gitignore.js" + "gitignore.js", + "index.d.ts" ], "keywords": [ "all", @@ -55,6 +56,7 @@ "git" ], "dependencies": { + "@types/glob": "^7.1.1", "array-union": "^1.0.2", "dir-glob": "^2.2.1", "fast-glob": "^2.2.6", @@ -69,6 +71,7 @@ "globby": "sindresorhus/globby#master", "matcha": "^0.7.0", "rimraf": "^2.6.3", + "tsd-check": "^0.3.0", "xo": "^0.24.0" }, "xo": {