vfile-find-up
Advanced tools
Comparing version 6.0.0 to 6.1.0
@@ -1,26 +0,5 @@ | ||
export const INCLUDE: 1 | ||
export const BREAK: 4 | ||
export const findUp: { | ||
( | ||
test: Test, | ||
cwd: string, | ||
callback: (error: Error | null, files: Array<VFile>) => void | ||
): void | ||
( | ||
test: Test, | ||
callback: (error: Error | null, files: Array<VFile>) => void | ||
): void | ||
(test: Test, cwd?: string): Promise<Array<VFile>> | ||
} | ||
export const findUpOne: { | ||
( | ||
test: Test, | ||
cwd: string, | ||
callback: (error: Error | null, file?: VFile) => void | ||
): void | ||
(test: Test, callback: (error: Error | null, file?: VFile) => void): void | ||
(test: Test, cwd?: string): Promise<VFile> | ||
} | ||
export type VFile = import('vfile').VFile | ||
export type Test = string | Assert | Array<string | Assert> | ||
export type Assert = (file: VFile) => number | boolean | void | ||
export type Assert = import('./lib/index.js').Assert | ||
export type Callback = import('./lib/index.js').Callback | ||
export type CallbackOne = import('./lib/index.js').CallbackOne | ||
export type Test = import('./lib/index.js').Test | ||
export {BREAK, INCLUDE, findUp, findUpOne} from './lib/index.js' |
242
index.js
/** | ||
* @typedef {import('vfile').VFile} VFile | ||
* @typedef {string|Assert|Array.<string|Assert>} Test | ||
* @typedef {(file: VFile) => number|boolean|void} Assert | ||
* @typedef {import('./lib/index.js').Assert} Assert | ||
* @typedef {import('./lib/index.js').Callback} Callback | ||
* @typedef {import('./lib/index.js').CallbackOne} CallbackOne | ||
* @typedef {import('./lib/index.js').Test} Test | ||
*/ | ||
import fs from 'fs' | ||
import path from 'path' | ||
import {toVFile} from 'to-vfile' | ||
export const INCLUDE = 1 | ||
export const BREAK = 4 | ||
export const findUp = | ||
/** | ||
* @type {{ | ||
* (test: Test, cwd: string, callback: (error: Error|null, files: Array.<VFile>) => void): void | ||
* (test: Test, callback: (error: Error|null, files: Array.<VFile>) => void): void | ||
* (test: Test, cwd?: string): Promise.<Array.<VFile>> | ||
* }} | ||
*/ | ||
( | ||
/** | ||
* Find a files or directories upwards. | ||
* | ||
* @param {Test} test | ||
* @param {string} cwd | ||
* @param {(error: Error|null, files: Array.<VFile>) => void} callback | ||
* @returns {unknown} | ||
*/ | ||
function (test, cwd, callback) { | ||
return find(test, cwd, callback) | ||
} | ||
) | ||
export const findUpOne = | ||
/** | ||
* @type {{ | ||
* (test: Test, cwd: string, callback: (error: Error|null, file?: VFile) => void): void | ||
* (test: Test, callback: (error: Error|null, file?: VFile) => void): void | ||
* (test: Test, cwd?: string): Promise.<VFile> | ||
* }} | ||
*/ | ||
( | ||
/** | ||
* Find a file or a directory upwards. | ||
* | ||
* @param {Test} test | ||
* @param {string} cwd | ||
* @param {(error: Error|null, file?: VFile) => void} callback | ||
* @returns {unknown} | ||
*/ | ||
function (test, cwd, callback) { | ||
return find(test, cwd, callback, true) | ||
} | ||
) | ||
/** | ||
* Find applicable files. | ||
* | ||
* @param {Test} test | ||
* @param {string|((error: Error|null, result?: VFile|Array.<VFile>) => void)} cwd | ||
* @param {null|undefined|((error: Error|null, result?: VFile|Array.<VFile>) => void)} cb | ||
* @param {boolean} [one] | ||
* @returns {Promise.<VFile|Array.<VFile>>} | ||
*/ | ||
function find(test, cwd, cb, one) { | ||
/** @type {Array.<VFile>} */ | ||
var results = [] | ||
/** @type {string} */ | ||
var current | ||
/** @type {Assert} */ | ||
var assert = convert(test) | ||
/** @type {string} */ | ||
var base | ||
/** @type {(error: Error|null, result?: VFile|Array.<VFile>) => void} */ | ||
var callback | ||
if (typeof cwd === 'string') { | ||
base = cwd | ||
callback = cb | ||
} else { | ||
base = null | ||
callback = cwd | ||
} | ||
current = base ? path.resolve(base) : process.cwd() | ||
if (!callback) { | ||
return new Promise(executor) | ||
} | ||
executor(resolve) | ||
/** | ||
* @param {VFile|Array.<VFile>} result | ||
*/ | ||
function resolve(result) { | ||
callback(null, result) | ||
} | ||
/** | ||
* @param {(x: VFile|Array.<VFile>) => void} resolve | ||
*/ | ||
function executor(resolve) { | ||
once(current) | ||
/** | ||
* Test a file and check what should be done with the resulting file. | ||
* | ||
* @param {string} filePath | ||
* @returns {boolean} | ||
*/ | ||
function handle(filePath) { | ||
var file = toVFile(filePath) | ||
var result = Number(assert(file)) | ||
if ((result & INCLUDE) === INCLUDE) { | ||
if (one) { | ||
resolve(file) | ||
return true | ||
} | ||
results.push(file) | ||
} | ||
if ((result & BREAK) === BREAK) { | ||
resolve(one ? null : results) | ||
return true | ||
} | ||
} | ||
/** | ||
* Check one directory. | ||
* | ||
* @param {string} child | ||
* @returns {void} | ||
*/ | ||
function once(child) { | ||
if (handle(current) === true) { | ||
return | ||
} | ||
fs.readdir(current, function (error, entries) { | ||
var index = -1 | ||
/** @type {string} */ | ||
var entry | ||
if (error) { | ||
entries = [] | ||
} | ||
while (++index < entries.length) { | ||
entry = entries[index] | ||
if ( | ||
entry !== child && | ||
handle(path.resolve(current, entry)) === true | ||
) { | ||
return | ||
} | ||
} | ||
child = current | ||
current = path.dirname(current) | ||
if (current === child) { | ||
resolve(one ? null : results) | ||
return | ||
} | ||
once(path.basename(child)) | ||
}) | ||
} | ||
} | ||
} | ||
/** | ||
* Convert `test` | ||
* | ||
* @param {Test} test | ||
* @returns {Assert} | ||
*/ | ||
function convert(test) { | ||
return typeof test === 'function' | ||
? test | ||
: typeof test === 'string' | ||
? testString(test) | ||
: multiple(test) | ||
} | ||
/** | ||
* Check multiple tests. | ||
* | ||
* @param {Array.<string|Assert>} test | ||
* @returns {Assert} | ||
*/ | ||
function multiple(test) { | ||
/** @type {Array.<Assert>} */ | ||
var tests = [] | ||
var index = -1 | ||
while (++index < test.length) { | ||
tests[index] = convert(test[index]) | ||
} | ||
return check | ||
/** @type {Assert} */ | ||
function check(file) { | ||
var index = -1 | ||
/** @type {number|boolean|void} */ | ||
var result | ||
while (++index < tests.length) { | ||
result = tests[index](file) | ||
if (result) { | ||
return result | ||
} | ||
} | ||
return false | ||
} | ||
} | ||
/** | ||
* Wrap a string given as a test. | ||
* | ||
* @param {string} test | ||
* @returns {Assert} | ||
*/ | ||
function testString(test) { | ||
return check | ||
/** @type {Assert} */ | ||
function check(file) { | ||
return test === file.basename || test === file.extname | ||
} | ||
} | ||
export {BREAK, INCLUDE, findUp, findUpOne} from './lib/index.js' |
{ | ||
"name": "vfile-find-up", | ||
"version": "6.0.0", | ||
"version": "6.1.0", | ||
"description": "vfile utility to find one or more files by searching the file system upwards", | ||
@@ -33,2 +33,3 @@ "license": "MIT", | ||
"files": [ | ||
"lib/", | ||
"index.d.ts", | ||
@@ -42,19 +43,17 @@ "index.js" | ||
"devDependencies": { | ||
"@types/tape": "^4.0.0", | ||
"@types/node": "^18.0.0", | ||
"c8": "^7.0.0", | ||
"prettier": "^2.0.0", | ||
"remark-cli": "^9.0.0", | ||
"remark-preset-wooorm": "^8.0.0", | ||
"rimraf": "^3.0.0", | ||
"tape": "^5.0.0", | ||
"remark-cli": "^11.0.0", | ||
"remark-preset-wooorm": "^9.0.0", | ||
"type-coverage": "^2.0.0", | ||
"typescript": "^4.0.0", | ||
"xo": "^0.39.0" | ||
"xo": "^0.53.0" | ||
}, | ||
"scripts": { | ||
"prepack": "npm run build && npm run format", | ||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage", | ||
"build": "tsc --build --clean && tsc --build && type-coverage", | ||
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", | ||
"test-api": "node test/index.js", | ||
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test/index.js", | ||
"test-api": "node --conditions development test/index.js", | ||
"test-coverage": "c8 --check-coverage --100 --reporter lcov npm run test-api", | ||
"test": "npm run build && npm run format && npm run test-coverage" | ||
@@ -73,4 +72,3 @@ }, | ||
"rules": { | ||
"no-var": "off", | ||
"prefer-arrow-callback": "off" | ||
"no-bitwise": "off" | ||
} | ||
@@ -77,0 +75,0 @@ }, |
217
readme.md
@@ -10,11 +10,39 @@ # vfile-find-up | ||
Find [vfile][]s by searching the file system upwards. | ||
[vfile][] utility to find files by searching the file system upwards. | ||
## Contents | ||
* [What is this?](#what-is-this) | ||
* [When should I use this?](#when-should-i-use-this) | ||
* [Install](#install) | ||
* [Use](#use) | ||
* [API](#api) | ||
* [`findUp(tests[, path][, callback])`](#finduptests-path-callback) | ||
* [`findUpOne(test[, path][, callback])`](#finduponetest-path-callback) | ||
* [`BREAK`](#break) | ||
* [`INCLUDE`](#include) | ||
* [`Assert`](#assert) | ||
* [`Callback`](#callback) | ||
* [`CallbackOne`](#callbackone) | ||
* [`Test`](#test) | ||
* [Types](#types) | ||
* [Compatibility](#compatibility) | ||
* [Contribute](#contribute) | ||
* [License](#license) | ||
## What is this? | ||
This utility lets you find one or many files upwards. | ||
## When should I use this? | ||
You can use this utility if you want to find, say, a config file. | ||
If you instead want to find files downwards, such as all markdown files in a | ||
folder, you can use [`vfile-find-down`][vfile-find-down]. | ||
## Install | ||
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c): | ||
Node 12+ is needed to use it and it must be `import`ed instead of `require`d. | ||
This package is [ESM only][esm]. | ||
In Node.js (version 14.14+ and 16.0+), install with [npm][]: | ||
[npm][]: | ||
```sh | ||
@@ -29,3 +57,3 @@ npm install vfile-find-up | ||
findUp('package.json', console.log) | ||
console.log(await findUp('package.json')) | ||
``` | ||
@@ -36,3 +64,3 @@ | ||
```js | ||
null [ VFile { | ||
[ VFile { | ||
data: {}, | ||
@@ -46,4 +74,7 @@ messages: [], | ||
This package exports the following identifiers: `findUp`, `findUpOne`, `INCLUDE`, | ||
`BREAK`. | ||
This package exports the identifiers | ||
[`BREAK`][api-break], | ||
[`INCLUDE`][api-include], | ||
[`findUp`][api-find-up], and | ||
[`findUpOne`][api-find-up-one]. | ||
There is no default export. | ||
@@ -53,52 +84,132 @@ | ||
Search for `tests` upwards. | ||
Calls callback with either an error or an array of files passing `tests`. | ||
Note: Virtual Files are not read (their `contents` is not populated). | ||
Find files or folders upwards. | ||
##### Sigantures | ||
> 👉 **Note**: files are not read (their `value` is not populated). | ||
* `(tests: Test, path?: string, callback: Callback): void` | ||
* `(tests: Test, path?: string): Promise.<Array.<VFile>>` | ||
###### Signatures | ||
##### Parameters | ||
* `(test[, path], callback) => void` | ||
* `(test[, path]) => Promise<Array<VFile>>` | ||
###### `tests` | ||
###### Parameters | ||
Things to search for (`string`, `Function`, or `Array.<tests>`). | ||
* `test` ([`Test`][api-test]) | ||
— things to search for | ||
* `paths` (`string`, default: `process.cwd()`) | ||
— place to search from | ||
* `callback` ([`Callback`][api-callback], optional) | ||
— callback called when done | ||
If a `string` is passed in, the `basename` or `extname` of files must match it | ||
for them to be included. | ||
###### Returns | ||
If an array is passed in, any test must match a given file for it to be | ||
included. | ||
Nothing when `callback` is given (`void`), otherwise a promise that resolves to | ||
files ([`Array<VFile>`][vfile]). | ||
Otherwise, they must be [`function`][test]. | ||
### `findUpOne(test[, path][, callback])` | ||
###### `path` | ||
Find the first file or folder upwards. | ||
Place to searching from (`string`, default: `process.cwd()`). | ||
> 👉 **Note**: files are not read (their `value` is not populated). | ||
###### `callback` | ||
###### Signatures | ||
Function called with all matching files (`function cb(err[, files])`). | ||
* `(test[, path], callback) => void` | ||
* `(test[, path]) => Promise<VFile>` | ||
### `findUpOne(tests[, path][, callback])` | ||
###### Parameters | ||
Like `findUp`, but either calls `callback` with the first found file, or `null` | ||
or without callback resolves to a file or `null`. | ||
* `test` ([`Test`][api-test]) | ||
— things to search for | ||
* `path` (`string`, default: `process.cwd()`) | ||
— place to search from | ||
* `callback` ([`CallbackOne`][api-callback-one], optional) | ||
— callback called when done | ||
### `function test(file)` | ||
###### Returns | ||
Check whether a virtual file should be included. | ||
Called with a [vfile][]. | ||
Nothing when `callback` is given (`void`), otherwise a promise that resolves to | ||
a file ([`VFile | null`][vfile]). | ||
##### Returns | ||
### `BREAK` | ||
* `true` or `INCLUDE` — Include the file in the results | ||
* `BREAK` — Stop searching for files | ||
* anything else is ignored: the file is not included | ||
Stop searching (`number`). | ||
The different flags can be combined by using the pipe operator: | ||
`INCLUDE | BREAK`. | ||
### `INCLUDE` | ||
Include this file (`number`). | ||
### `Assert` | ||
Handle a file (TypeScript type). | ||
###### Parameters | ||
* `file` ([`VFile`][vfile]) | ||
— file to handle | ||
###### Returns | ||
How to handle this file (`boolean | number`, optional). | ||
`true` is treated as `INCLUDE`. | ||
### `Callback` | ||
Callback called when done (TypeScript type). | ||
###### Parameters | ||
* `error` (`Error | null`) | ||
— error; errors are currently never passed | ||
* `files` ([`Array<VFile>`][vfile]) | ||
— files | ||
###### Returns | ||
Nothing (`void`). | ||
### `CallbackOne` | ||
Callback called when done finding one file (TypeScript type). | ||
###### Parameters | ||
* `error` (`Error | null`) | ||
— error; errors are currently never passed | ||
* `file` ([`VFile | null`][vfile]) | ||
— file | ||
###### Returns | ||
Nothing (`void`). | ||
### `Test` | ||
Things to search for (TypeScript type). | ||
For strings, the `basename` or `extname` of files must match them. | ||
For arrays, any test in them must match. | ||
###### Type | ||
```ts | ||
type Test = Array<Assert | string> | Assert | string | ||
``` | ||
## Types | ||
This package is fully typed with [TypeScript][]. | ||
It exports the additional types | ||
[`Assert`][api-assert], | ||
[`Callback`][api-callback], | ||
[`CallbackOne`][api-callback-one], and | ||
[`Test`][api-test]. | ||
## Compatibility | ||
Projects maintained by the unified collective are compatible with all maintained | ||
versions of Node.js. | ||
As of now, that is Node.js 14.14+ and 16.0+. | ||
Our projects sometimes work with older versions, but this is not guaranteed. | ||
## Contribute | ||
@@ -144,9 +255,13 @@ | ||
[contributing]: https://github.com/vfile/.github/blob/HEAD/contributing.md | ||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c | ||
[support]: https://github.com/vfile/.github/blob/HEAD/support.md | ||
[typescript]: https://www.typescriptlang.org | ||
[contributing]: https://github.com/vfile/.github/blob/main/contributing.md | ||
[support]: https://github.com/vfile/.github/blob/main/support.md | ||
[health]: https://github.com/vfile/.github | ||
[coc]: https://github.com/vfile/.github/blob/HEAD/code-of-conduct.md | ||
[coc]: https://github.com/vfile/.github/blob/main/code-of-conduct.md | ||
@@ -159,2 +274,18 @@ [license]: license | ||
[test]: #function-testfile | ||
[vfile-find-down]: https://github.com/vfile/vfile-find-down | ||
[api-break]: #break | ||
[api-include]: #include | ||
[api-find-up]: #finduptests-path-callback | ||
[api-find-up-one]: #finduponetest-path-callback | ||
[api-assert]: #assert | ||
[api-callback]: #callback | ||
[api-callback-one]: #callbackone | ||
[api-test]: #test |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
19378
8
7
377
285
1