Skip to content

Commit

Permalink
feat: add synchronous methods (#3)
Browse files Browse the repository at this point in the history
This adds synchronous equivalents to each of the exposed functions.

Unfortunately, we have to duplicate code a little but this will come in
useful in some sync-only places like ESLint.
  • Loading branch information
43081j authored Mar 9, 2024
1 parent be42187 commit 1ddbb6a
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 1 deletion.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ parameter:
await findPackage(process.cwd()); // Returns the JSON of the package if found
```

Synchronous methods also exist:

```ts
findPackageSync(process.cwd()); // returns the package

findPackagePathSync(process.cwd()); // returns the package path
```

## License

MIT
55 changes: 55 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {walkUp} from 'walk-up-path';
import {resolve} from 'node:path';
import {stat, readFile} from 'node:fs/promises';
import {statSync, readFileSync} from 'node:fs';

/**
* Determines if a file exists or not
Expand All @@ -16,6 +17,20 @@ async function fileExists(path: string): Promise<boolean> {
}
}

/**
* Synchronously determines if a file exists or not
* @param {string} path Path of the file
* @return {boolean}
*/
function fileExistsSync(path: string): boolean {
try {
const stats = statSync(path);
return stats.isFile();
} catch (_err) {
return false;
}
}

/**
* Finds the path of the first `package.json` encountered when traversing
* the file system upwards from the specified `cwd`.
Expand Down Expand Up @@ -57,3 +72,43 @@ export async function findPackage(cwd: string): Promise<Package | null> {
return null;
}
}

/**
* Synchronously Finds the path of the first `package.json` encountered when
* traversing the file system upwards from the specified `cwd`.
* @param {string} cwd Current/starting directory
* @return {string|null}
*/
export function findPackagePathSync(cwd: string): string | null {
for (const path of walkUp(cwd)) {
const packagePath = resolve(path, 'package.json');
const hasPackageJson = fileExistsSync(packagePath);

if (hasPackageJson) {
return packagePath;
}
}

return null;
}

/**
* Synchronously finds and returns the contents of the first `package.json`
* encountered when traversing the file system upwards from the specified `cwd`.
* @param {string} cwd Current/starting directory
* @return {Package | null}
*/
export function findPackageSync(cwd: string): Package | null {
const packagePath = findPackagePathSync(cwd);

if (!packagePath) {
return null;
}

try {
const source = readFileSync(packagePath, {encoding: 'utf8'});
return JSON.parse(source);
} catch (_err) {
return null;
}
}
27 changes: 26 additions & 1 deletion src/test/main_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import assert from 'node:assert';
import {test} from 'node:test';
import {fileURLToPath} from 'node:url';
import {join as joinPath} from 'node:path';
import {findPackage, findPackagePath} from '../main.js';
import {
findPackage,
findPackagePath,
findPackageSync,
findPackagePathSync
} from '../main.js';

const currentDir = fileURLToPath(new URL('../../', import.meta.url));
const rootPackagePath = joinPath(currentDir, 'package.json');
Expand Down Expand Up @@ -71,3 +76,23 @@ test('findPackage', async (t) => {
assert.equal(await findPackage(fixturePath), null);
});
});

test('findPackagePathSync', async (t) => {
await t.test('finds package in cwd', () => {
const fixturePath = joinPath(currentDir, 'test/fixtures/simple-package');
const packagePath = joinPath(
currentDir,
'test/fixtures/simple-package/package.json'
);
assert.equal(findPackagePathSync(fixturePath), packagePath);
});
});

test('findPackageSync', async (t) => {
await t.test('finds package in simple tree', () => {
const fixturePath = joinPath(currentDir, 'test/fixtures/simple-package');
const result = findPackageSync(fixturePath);

assert.equal(result!.name, 'simple-package');
});
});

0 comments on commit 1ddbb6a

Please sign in to comment.