Skip to content

Commit

Permalink
feat: support fs.exists async function (#65)
Browse files Browse the repository at this point in the history
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
	- Added a badge in the `README.md` to welcome pull requests.
- Introduced a new asynchronous function `exists` to check for file
existence.
- Expanded the module's public API by exporting all functionalities from
the `fs.js` module.

- **Tests**
- Added unit tests for the `exists` function, covering various scenarios
including file existence checks and error handling.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
fengmk2 authored Dec 22, 2024
1 parent 153e3ff commit eb95f36
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 1 deletion.
1 change: 0 additions & 1 deletion .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ jobs:
name: Node.js
uses: node-modules/github-actions/.github/workflows/node-test.yml@master
with:
os: 'ubuntu-latest'
version: '16, 18, 20, 22, 23'
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
[![Test coverage][codecov-image]][codecov-url]
[![npm download][download-image]][download-url]
[![Node.js Version](https://img.shields.io/node/v/utility.svg?style=flat)](https://nodejs.org/en/download/)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://makeapullrequest.com)

[npm-image]: https://img.shields.io/npm/v/utility.svg?style=flat-square
[npm-url]: https://npmjs.org/package/utility
Expand Down
17 changes: 17 additions & 0 deletions src/fs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Stats } from 'node:fs';
import { stat } from 'node:fs/promises';

/**
* Check if a file exists.
* Returns the file stats if it exists, or `false` if it doesn't.
*/
export async function exists(file: string): Promise<Stats | false> {
try {
return await stat(file);
} catch (err: any) {
if (err.code === 'ENOENT') {
return false;
}
throw err;
}
}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export * from './string.js';
export * from './optimize.js';
export * from './object.js';
export * from './timeout.js';
export * from './fs.js';
54 changes: 54 additions & 0 deletions test/fs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { strict as assert } from 'node:assert';
import path from 'node:path';
import { Stats } from 'node:fs';
import { fileURLToPath } from 'node:url';
import * as utility from '../src/index.js';
import { exists } from '../src/index.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

describe('test/fs.test.ts', () => {
describe('exists()', () => {
it('should work', async () => {
let stats = await exists(__filename);
assert(stats instanceof Stats);
assert(stats.size > 0, 'stats.size > 0');
assert.equal(stats.isFile(), true);
assert.equal(stats.isDirectory(), false);

stats = await utility.exists(__dirname);
assert(stats instanceof Stats);
// assert(stats.size > 0, 'stats.size > 0');
assert.equal(stats.isDirectory(), true);
assert.equal(stats.isFile(), false);
assert.equal(await exists(__dirname + '/nonexistent'), false);
});

it('should throw error on Linux', async () => {
if (process.platform !== 'linux') {
return;
}
await assert.rejects(async () => {
await exists('/root/../../../../../etc/passwd');
}, (err: any) => {
// Error: EACCES: permission denied, stat '/root/../../../../../etc/passwd'
assert.equal(err.code, 'EACCES');
return true;
});
});

it.skip('should throw error on win32', async () => {
if (process.platform !== 'win32') {
return;
}
await assert.rejects(async () => {
await exists('C:\\Windows\\System32\\drivers\\etc\\hosts');
}, (err: any) => {
// Error: EACCES: permission denied, stat 'C:\Windows\System32\drivers\etc\hosts'
assert.equal(err.code, 'EPERM');
return true;
});
});
});
});

0 comments on commit eb95f36

Please sign in to comment.