Skip to content

Commit

Permalink
Accept URL as cwd (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
fisker committed Feb 8, 2022
1 parent db9962c commit f348f3c
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 5 deletions.
7 changes: 5 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import path from 'node:path';
import {fileURLToPath} from 'node:url';
import {locatePath, locatePathSync} from 'locate-path';

const toPath = urlOrPath => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath;

export const findUpStop = Symbol('findUpStop');

export async function findUpMultiple(name, options = {}) {
let directory = path.resolve(options.cwd || '');
let directory = path.resolve(toPath(options.cwd) || '');
const {root} = path.parse(directory);
const stopAt = path.resolve(directory, options.stopAt || root);
const limit = options.limit || Number.POSITIVE_INFINITY;
Expand Down Expand Up @@ -48,7 +51,7 @@ export async function findUpMultiple(name, options = {}) {
}

export function findUpMultipleSync(name, options = {}) {
let directory = path.resolve(options.cwd || '');
let directory = path.resolve(toPath(options.cwd) || '');
const {root} = path.parse(directory);
const stopAt = options.stopAt || root;
const limit = options.limit || Number.POSITIVE_INFINITY;
Expand Down
24 changes: 24 additions & 0 deletions index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {findUp, findUpSync, findUpMultiple, findUpMultipleSync, findUpStop, path

expectType<Promise<string | undefined>>(findUp('unicorn.png'));
expectType<Promise<string | undefined>>(findUp('unicorn.png', {cwd: ''}));
expectType<Promise<string | undefined>>(findUp('unicorn.png', {cwd: new URL('file:///path/to/cwd/')}));
expectType<Promise<string | undefined>>(findUp(['rainbow.png', 'unicorn.png']));
expectType<Promise<string | undefined>>(findUp(['rainbow.png', 'unicorn.png'], {cwd: ''}));
expectType<Promise<string | undefined>>(findUp(['rainbow.png', 'unicorn.png'], {allowSymlinks: true}));
Expand All @@ -14,20 +15,23 @@ expectError(findUp(['rainbow.png', 'unicorn.png'], {concurrency: 1}));

expectType<Promise<string | undefined>>(findUp(() => 'unicorn.png'));
expectType<Promise<string | undefined>>(findUp(() => 'unicorn.png', {cwd: ''}));
expectType<Promise<string | undefined>>(findUp(() => 'unicorn.png', {cwd: new URL('file:///path/to/cwd/')}));
expectType<Promise<string | undefined>>(findUp(() => 'unicorn.png', {allowSymlinks: true}));
expectType<Promise<string | undefined>>(findUp(() => 'unicorn.png', {allowSymlinks: false}));
expectType<Promise<string | undefined>>(findUp(() => 'unicorn.png', {type: 'file'}));
expectType<Promise<string | undefined>>(findUp(() => 'unicorn.png', {type: 'directory'}));
expectType<Promise<string | undefined>>(findUp(() => 'unicorn.png', {stopAt: 'foo'}));
expectType<Promise<string | undefined>>(findUp(() => undefined));
expectType<Promise<string | undefined>>(findUp(() => undefined, {cwd: ''}));
expectType<Promise<string | undefined>>(findUp(() => undefined, {cwd: new URL('file:///path/to/cwd/')}));
expectType<Promise<string | undefined>>(findUp(() => undefined, {allowSymlinks: true}));
expectType<Promise<string | undefined>>(findUp(() => undefined, {allowSymlinks: false}));
expectType<Promise<string | undefined>>(findUp(() => undefined, {type: 'file'}));
expectType<Promise<string | undefined>>(findUp(() => undefined, {type: 'directory'}));
expectType<Promise<string | undefined>>(findUp(() => undefined, {stopAt: 'foo'}));
expectType<Promise<string | undefined>>(findUp((): typeof findUpStop => findUpStop));
expectType<Promise<string | undefined>>(findUp((): typeof findUpStop => findUpStop, {cwd: ''}));
expectType<Promise<string | undefined>>(findUp((): typeof findUpStop => findUpStop, {cwd: new URL('file:///path/to/cwd/')}));
expectType<Promise<string | undefined>>(findUp((): typeof findUpStop => findUpStop, {stopAt: 'foo'}));
expectType<Promise<string | undefined>>(findUp(async () => 'unicorn.png'));
expectType<Promise<string | undefined>>(findUp(async () => 'unicorn.png', {cwd: ''}));
Expand All @@ -38,6 +42,7 @@ expectType<Promise<string | undefined>>(findUp(async () => 'unicorn.png', {type:
expectType<Promise<string | undefined>>(findUp(async () => 'unicorn.png', {stopAt: 'foo'}));
expectType<Promise<string | undefined>>(findUp(async () => undefined));
expectType<Promise<string | undefined>>(findUp(async () => undefined, {cwd: ''}));
expectType<Promise<string | undefined>>(findUp(async () => undefined, {cwd: new URL('file:///path/to/cwd/')}));
expectType<Promise<string | undefined>>(findUp(async () => undefined, {allowSymlinks: true}));
expectType<Promise<string | undefined>>(findUp(async () => undefined, {allowSymlinks: false}));
expectType<Promise<string | undefined>>(findUp(async () => undefined, {type: 'file'}));
Expand All @@ -46,6 +51,7 @@ expectType<Promise<string | undefined>>(findUp(async () => undefined, {stopAt: '

expectType<Promise<string | undefined>>(findUp(async (): Promise<typeof findUpStop> => findUpStop));
expectType<Promise<string | undefined>>(findUp(async (): Promise<typeof findUpStop> => findUpStop, {cwd: ''}));
expectType<Promise<string | undefined>>(findUp(async (): Promise<typeof findUpStop> => findUpStop, {cwd: new URL('file:///path/to/cwd/')}));
expectType<Promise<string | undefined>>(findUp(async (): Promise<typeof findUpStop> => findUpStop, {allowSymlinks: true}));
expectType<Promise<string | undefined>>(findUp(async (): Promise<typeof findUpStop> => findUpStop, {allowSymlinks: false}));
expectType<Promise<string | undefined>>(findUp(async (): Promise<typeof findUpStop> => findUpStop, {type: 'file'}));
Expand All @@ -54,8 +60,10 @@ expectType<Promise<string | undefined>>(findUp(async (): Promise<typeof findUpSt

expectType<Promise<string[]>>(findUpMultiple('unicorn.png'));
expectType<Promise<string[]>>(findUpMultiple('unicorn.png', {cwd: ''}));
expectType<Promise<string[]>>(findUpMultiple('unicorn.png', {cwd: new URL('file:///path/to/cwd/')}));
expectType<Promise<string[]>>(findUpMultiple(['rainbow.png', 'unicorn.png']));
expectType<Promise<string[]>>(findUpMultiple(['rainbow.png', 'unicorn.png'], {cwd: ''}));
expectType<Promise<string[]>>(findUpMultiple(['rainbow.png', 'unicorn.png'], {cwd: new URL('file:///path/to/cwd/')}));
expectType<Promise<string[]>>(findUpMultiple(['rainbow.png', 'unicorn.png'], {allowSymlinks: true}));
expectType<Promise<string[]>>(findUpMultiple(['rainbow.png', 'unicorn.png'], {allowSymlinks: false}));
expectType<Promise<string[]>>(findUpMultiple(['rainbow.png', 'unicorn.png'], {type: 'file'}));
Expand All @@ -65,30 +73,35 @@ expectError(findUpMultiple(['rainbow.png', 'unicorn.png'], {concurrency: 1}));

expectType<Promise<string[]>>(findUpMultiple(() => 'unicorn.png'));
expectType<Promise<string[]>>(findUpMultiple(() => 'unicorn.png', {cwd: ''}));
expectType<Promise<string[]>>(findUpMultiple(() => 'unicorn.png', {cwd: new URL('file:///path/to/cwd/')}));
expectType<Promise<string[]>>(findUpMultiple(() => 'unicorn.png', {allowSymlinks: true}));
expectType<Promise<string[]>>(findUpMultiple(() => 'unicorn.png', {allowSymlinks: false}));
expectType<Promise<string[]>>(findUpMultiple(() => 'unicorn.png', {type: 'file'}));
expectType<Promise<string[]>>(findUpMultiple(() => 'unicorn.png', {type: 'directory'}));
expectType<Promise<string[]>>(findUpMultiple(() => 'unicorn.png', {stopAt: 'foo'}));
expectType<Promise<string[]>>(findUpMultiple(() => undefined));
expectType<Promise<string[]>>(findUpMultiple(() => undefined, {cwd: ''}));
expectType<Promise<string[]>>(findUpMultiple(() => undefined, {cwd: new URL('file:///path/to/cwd/')}));
expectType<Promise<string[]>>(findUpMultiple(() => undefined, {allowSymlinks: true}));
expectType<Promise<string[]>>(findUpMultiple(() => undefined, {allowSymlinks: false}));
expectType<Promise<string[]>>(findUpMultiple(() => undefined, {type: 'file'}));
expectType<Promise<string[]>>(findUpMultiple(() => undefined, {type: 'directory'}));
expectType<Promise<string[]>>(findUpMultiple(() => undefined, {stopAt: 'foo'}));
expectType<Promise<string[]>>(findUpMultiple((): typeof findUpStop => findUpStop));
expectType<Promise<string[]>>(findUpMultiple((): typeof findUpStop => findUpStop, {cwd: ''}));
expectType<Promise<string[]>>(findUpMultiple((): typeof findUpStop => findUpStop, {cwd: new URL('file:///path/to/cwd/')}));
expectType<Promise<string[]>>(findUpMultiple((): typeof findUpStop => findUpStop, {stopAt: 'foo'}));
expectType<Promise<string[]>>(findUpMultiple(async () => 'unicorn.png'));
expectType<Promise<string[]>>(findUpMultiple(async () => 'unicorn.png', {cwd: ''}));
expectType<Promise<string[]>>(findUpMultiple(async () => 'unicorn.png', {cwd: new URL('file:///path/to/cwd/')}));
expectType<Promise<string[]>>(findUpMultiple(async () => 'unicorn.png', {allowSymlinks: true}));
expectType<Promise<string[]>>(findUpMultiple(async () => 'unicorn.png', {allowSymlinks: false}));
expectType<Promise<string[]>>(findUpMultiple(async () => 'unicorn.png', {type: 'file'}));
expectType<Promise<string[]>>(findUpMultiple(async () => 'unicorn.png', {type: 'directory'}));
expectType<Promise<string[]>>(findUpMultiple(async () => 'unicorn.png', {stopAt: 'foo'}));
expectType<Promise<string[]>>(findUpMultiple(async () => undefined));
expectType<Promise<string[]>>(findUpMultiple(async () => undefined, {cwd: ''}));
expectType<Promise<string[]>>(findUpMultiple(async () => undefined, {cwd: new URL('file:///path/to/cwd/')}));
expectType<Promise<string[]>>(findUpMultiple(async () => undefined, {allowSymlinks: true}));
expectType<Promise<string[]>>(findUpMultiple(async () => undefined, {allowSymlinks: false}));
expectType<Promise<string[]>>(findUpMultiple(async () => undefined, {type: 'file'}));
Expand All @@ -97,6 +110,7 @@ expectType<Promise<string[]>>(findUpMultiple(async () => undefined, {stopAt: 'fo

expectType<Promise<string[]>>(findUpMultiple(async (): Promise<typeof findUpStop> => findUpStop));
expectType<Promise<string[]>>(findUpMultiple(async (): Promise<typeof findUpStop> => findUpStop, {cwd: ''}));
expectType<Promise<string[]>>(findUpMultiple(async (): Promise<typeof findUpStop> => findUpStop, {cwd: new URL('file:///path/to/cwd/')}));
expectType<Promise<string[]>>(findUpMultiple(async (): Promise<typeof findUpStop> => findUpStop, {allowSymlinks: true}));
expectType<Promise<string[]>>(findUpMultiple(async (): Promise<typeof findUpStop> => findUpStop, {allowSymlinks: false}));
expectType<Promise<string[]>>(findUpMultiple(async (): Promise<typeof findUpStop> => findUpStop, {type: 'file'}));
Expand All @@ -105,8 +119,10 @@ expectType<Promise<string[]>>(findUpMultiple(async (): Promise<typeof findUpStop

expectType<string | undefined>(findUpSync('unicorn.png'));
expectType<string | undefined>(findUpSync('unicorn.png', {cwd: ''}));
expectType<string | undefined>(findUpSync('unicorn.png', {cwd: new URL('file:///path/to/cwd/')}));
expectType<string | undefined>(findUpSync(['rainbow.png', 'unicorn.png']));
expectType<string | undefined>(findUpSync(['rainbow.png', 'unicorn.png'], {cwd: ''}));
expectType<string | undefined>(findUpSync(['rainbow.png', 'unicorn.png'], {cwd: new URL('file:///path/to/cwd/')}));
expectType<string | undefined>(findUpSync(['rainbow.png', 'unicorn.png'], {allowSymlinks: true}));
expectType<string | undefined>(findUpSync(['rainbow.png', 'unicorn.png'], {allowSymlinks: false}));
expectType<string | undefined>(findUpSync(['rainbow.png', 'unicorn.png'], {type: 'file'}));
Expand All @@ -115,49 +131,57 @@ expectType<string | undefined>(findUpSync(['rainbow.png', 'unicorn.png'], {stopA

expectType<string | undefined>(findUpSync(() => 'unicorn.png'));
expectType<string | undefined>(findUpSync(() => 'unicorn.png', {cwd: ''}));
expectType<string | undefined>(findUpSync(() => 'unicorn.png', {cwd: new URL('file:///path/to/cwd/')}));
expectType<string | undefined>(findUpSync(() => 'unicorn.png', {allowSymlinks: true}));
expectType<string | undefined>(findUpSync(() => 'unicorn.png', {allowSymlinks: false}));
expectType<string | undefined>(findUpSync(() => 'unicorn.png', {type: 'file'}));
expectType<string | undefined>(findUpSync(() => 'unicorn.png', {type: 'directory'}));
expectType<string | undefined>(findUpSync(() => 'unicorn.png', {stopAt: 'foo'}));
expectType<string | undefined>(findUpSync(() => undefined));
expectType<string | undefined>(findUpSync(() => undefined, {cwd: ''}));
expectType<string | undefined>(findUpSync(() => undefined, {cwd: new URL('file:///path/to/cwd/')}));
expectType<string | undefined>(findUpSync(() => undefined, {allowSymlinks: true}));
expectType<string | undefined>(findUpSync(() => undefined, {allowSymlinks: false}));
expectType<string | undefined>(findUpSync(() => undefined, {type: 'file'}));
expectType<string | undefined>(findUpSync(() => undefined, {type: 'directory'}));
expectType<string | undefined>(findUpSync(() => undefined, {stopAt: 'foo'}));
expectType<string | undefined>(findUpSync((): typeof findUpStop => findUpStop));
expectType<string | undefined>(findUpSync((): typeof findUpStop => findUpStop, {cwd: ''}));
expectType<string | undefined>(findUpSync((): typeof findUpStop => findUpStop, {cwd: new URL('file:///path/to/cwd/')}));
expectType<string | undefined>(findUpSync((): typeof findUpStop => findUpStop, {type: 'file'}));
expectType<string | undefined>(findUpSync((): typeof findUpStop => findUpStop, {type: 'directory'}));
expectType<string | undefined>(findUpSync((): typeof findUpStop => findUpStop, {stopAt: 'foo'}));

expectType<string[]>(findUpMultipleSync('unicorn.png'));
expectType<string[]>(findUpMultipleSync('unicorn.png', {cwd: ''}));
expectType<string[]>(findUpMultipleSync('unicorn.png', {cwd: new URL('file:///path/to/cwd/')}));
expectType<string[]>(findUpMultipleSync(['rainbow.png', 'unicorn.png']));
expectType<string[]>(findUpMultipleSync(['rainbow.png', 'unicorn.png'], {cwd: ''}));
expectType<string[]>(findUpMultipleSync(['rainbow.png', 'unicorn.png'], {cwd: new URL('file:///path/to/cwd/')}));
expectType<string[]>(findUpMultipleSync(['rainbow.png', 'unicorn.png'], {allowSymlinks: true}));
expectType<string[]>(findUpMultipleSync(['rainbow.png', 'unicorn.png'], {allowSymlinks: false}));
expectType<string[]>(findUpMultipleSync(['rainbow.png', 'unicorn.png'], {type: 'file'}));
expectType<string[]>(findUpMultipleSync(['rainbow.png', 'unicorn.png'], {type: 'directory'}));
expectType<string[]>(findUpMultipleSync(['rainbow.png', 'unicorn.png'], {stopAt: 'foo'}));
expectType<string[]>(findUpMultipleSync(() => 'unicorn.png'));
expectType<string[]>(findUpMultipleSync(() => 'unicorn.png', {cwd: ''}));
expectType<string[]>(findUpMultipleSync(() => 'unicorn.png', {cwd: new URL('file:///path/to/cwd/')}));
expectType<string[]>(findUpMultipleSync(() => 'unicorn.png', {allowSymlinks: true}));
expectType<string[]>(findUpMultipleSync(() => 'unicorn.png', {allowSymlinks: false}));
expectType<string[]>(findUpMultipleSync(() => 'unicorn.png', {type: 'file'}));
expectType<string[]>(findUpMultipleSync(() => 'unicorn.png', {type: 'directory'}));
expectType<string[]>(findUpMultipleSync(() => 'unicorn.png', {stopAt: 'foo'}));
expectType<string[]>(findUpMultipleSync(() => undefined));
expectType<string[]>(findUpMultipleSync(() => undefined, {cwd: ''}));
expectType<string[]>(findUpMultipleSync(() => undefined, {cwd: new URL('file:///path/to/cwd/')}));
expectType<string[]>(findUpMultipleSync(() => undefined, {allowSymlinks: true}));
expectType<string[]>(findUpMultipleSync(() => undefined, {allowSymlinks: false}));
expectType<string[]>(findUpMultipleSync(() => undefined, {type: 'file'}));
expectType<string[]>(findUpMultipleSync(() => undefined, {type: 'directory'}));
expectType<string[]>(findUpMultipleSync(() => undefined, {stopAt: 'foo'}));
expectType<string[]>(findUpMultipleSync((): typeof findUpStop => findUpStop));
expectType<string[]>(findUpMultipleSync((): typeof findUpStop => findUpStop, {cwd: ''}));
expectType<string[]>(findUpMultipleSync((): typeof findUpStop => findUpStop, {cwd: new URL('file:///path/to/cwd/')}));
expectType<string[]>(findUpMultipleSync((): typeof findUpStop => findUpStop, {type: 'file'}));
expectType<string[]>(findUpMultipleSync((): typeof findUpStop => findUpStop, {type: 'directory'}));
expectType<string[]>(findUpMultipleSync((): typeof findUpStop => findUpStop, {stopAt: 'foo'}));
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"path"
],
"dependencies": {
"locate-path": "^7.0.0",
"locate-path": "^7.1.0",
"path-exists": "^5.0.0"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ Type: `object`

##### cwd

Type: `string`\
Type: `URL | string`\
Default: `process.cwd()`

The directory to start from.
Expand Down
16 changes: 15 additions & 1 deletion test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import process from 'node:process';
import {promisify} from 'node:util';
import fs from 'node:fs';
import path from 'node:path';
import {fileURLToPath} from 'node:url';
import {fileURLToPath, pathToFileURL} from 'node:url';
import test from 'ava';
import isPathInside from 'is-path-inside';
import tempy from 'tempy';
Expand Down Expand Up @@ -49,6 +49,10 @@ absolute.barDirQux = path.join(absolute.fixtureDirectory, name.fooDirectory, nam
absolute.fileLink = path.join(absolute.fixtureDirectory, name.fileLink);
absolute.directoryLink = path.join(absolute.fixtureDirectory, name.directoryLink);

const url = {
fixtureDirectory: pathToFileURL(absolute.fixtureDirectory),
};

// Create a disjoint directory, used for the not-found tests
test.beforeEach(t => {
const temporaryDirectory = tempy.directory();
Expand Down Expand Up @@ -123,6 +127,11 @@ test('async (child file, custom cwd)', async t => {
});

t.is(foundPath, absolute.baz);

const foundPath2 = await findUp(name.baz, {
cwd: url.fixtureDirectory,
});
t.is(foundPath2, foundPath);
});

test('sync (child file, custom cwd)', t => {
Expand All @@ -131,6 +140,11 @@ test('sync (child file, custom cwd)', t => {
});

t.is(foundPath, absolute.baz);

const foundPath2 = findUpSync(name.baz, {
cwd: url.fixtureDirectory,
});
t.is(foundPath2, foundPath);
});

test('async (child file, array, custom cwd)', async t => {
Expand Down

0 comments on commit f348f3c

Please sign in to comment.