├── .github └── FUNDING.yml ├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── DOCUMENTATION.md ├── LICENSE ├── README.md ├── example ├── contents │ ├── dir │ │ ├── another │ │ │ └── file │ │ └── file │ ├── file │ └── file.ext └── index.js ├── lib └── index.js ├── package.json └── test ├── contents ├── dir │ ├── another │ │ └── file │ └── file ├── file └── file.ext └── index.js /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: ionicabizau 2 | patreon: ionicabizau 3 | open_collective: ionicabizau 4 | custom: https://www.buymeacoffee.com/h96wwchmy -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.swo 3 | *~ 4 | *.log 5 | node_modules 6 | *.env 7 | .DS_Store 8 | package-lock.json 9 | .bloggify/* 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 4 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # 🌟 Contributing 2 | 3 | Want to contribute to this project? Great! Please read these quick steps to streamline the process and avoid unnecessary tasks. ✨ 4 | 5 | ## 💬 Discuss Changes 6 | Start by opening an issue in the repository using the [bug tracker][1]. Describe your proposed contribution or the bug you've found. If relevant, include platform info and screenshots. 🖼️ 7 | 8 | Wait for feedback before proceeding unless the fix is straightforward, like a typo. 📝 9 | 10 | ## 🔧 Fixing Issues 11 | 12 | Fork the project and create a branch for your fix, naming it `some-great-feature` or `some-issue-fix`. Commit changes while following the [code style][2]. If the project has tests, add one. ✅ 13 | 14 | If a `package.json` or `bower.json` exists, add yourself to the `contributors` array; create it if it doesn't. 🙌 15 | 16 | ```json 17 | { 18 | "contributors": [ 19 | "Your Name (http://your.website)" 20 | ] 21 | } 22 | ``` 23 | 24 | ## 📬 Creating a Pull Request 25 | Open a pull request and reference the initial issue (e.g., *fixes #*). Provide a clear title and consider adding visual aids for clarity. 📊 26 | 27 | ## ⏳ Wait for Feedback 28 | Your contributions will be reviewed. If feedback is given, update your branch as needed, and the pull request will auto-update. 🔄 29 | 30 | ## 🎉 Everyone Is Happy! 31 | Your contributions will be merged, and everyone will appreciate your effort! 😄❤️ 32 | 33 | Thanks! 🤩 34 | 35 | [1]: /issues 36 | [2]: https://github.com/IonicaBizau/code-style -------------------------------------------------------------------------------- /DOCUMENTATION.md: -------------------------------------------------------------------------------- 1 | ## Documentation 2 | 3 | You can see below the API reference of this module. 4 | 5 | ### isThere 6 | 7 | Checks if a file or directory exists on given path. 8 | Use without the new keyword. 9 | 10 | #### Params 11 | 12 | - **String** `path`: The path to the file or directory. 13 | - **Function** `callback`: The callback function called with a boolean value representing if the file or directory exists. If this parameter is not a 14 | function, the function will run synchronously and return the value. 15 | 16 | #### Return 17 | - **isThere|Boolean** The `isThere` function if the `callback` parameter was provided, otherwise a boolean value indicating if the file/directory 18 | exists or not. 19 | 20 | ### `isThere.directory(path, callback)` 21 | Checks if the path exists and it is a directory. 22 | 23 | #### Params 24 | 25 | - **String** `path`: The path to the directory. 26 | - **Function** `callback`: The callback function called with a boolean value representing if the directory exists. If this parameter is not a 27 | function, the function will run synchronously and return the value. 28 | 29 | #### Return 30 | - **isThere|Boolean** The `isThere` function if the `callback` parameter was provided, otherwise a boolean value indicating if the directory exists or not. 31 | 32 | ### `isThere.file(path, callback)` 33 | Check if the path exists and it is a file. 34 | 35 | #### Params 36 | 37 | - **String** `path`: The path to the file. 38 | - **Function** `callback`: The callback function called with a boolean value representing if the file exists. If this parameter is not a 39 | function, the function will run synchronously and return the value. 40 | 41 | #### Return 42 | - **isThere|Boolean** The `isThere` function if the `callback` parameter was provided, otherwise a boolean value indicating if the file exists or not. 43 | 44 | ### `isThere.promises()` 45 | The promises interface. 46 | 47 | It exports the following methods: 48 | 49 | - `isThere.promises.exists` 50 | - `isThere.promises.file` 51 | - `isThere.promises.directory` 52 | 53 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-25 Ionică Bizău (https://ionicabizau.net) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | [![is-there](http://i.imgur.com/ZHzpvvE.png)](#) 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | # is-there 23 | 24 | [![Support me on Patreon][badge_patreon]][patreon] [![Buy me a book][badge_amazon]][amazon] [![PayPal][badge_paypal_donate]][paypal-donations] [![Ask me anything](https://img.shields.io/badge/ask%20me-anything-1abc9c.svg)](https://github.com/IonicaBizau/ama) [![Travis](https://img.shields.io/travis/IonicaBizau/node-is-there.svg)](https://travis-ci.org/IonicaBizau/node-is-there/) [![Version](https://img.shields.io/npm/v/is-there.svg)](https://www.npmjs.com/package/is-there) [![Downloads](https://img.shields.io/npm/dt/is-there.svg)](https://www.npmjs.com/package/is-there) [![Get help on Codementor](https://cdn.codementor.io/badges/get_help_github.svg)](https://www.codementor.io/@johnnyb?utm_source=github&utm_medium=button&utm_term=johnnyb&utm_campaign=github) 25 | 26 | Buy Me A Coffee 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | > Check if a file or directory exists in a given path. 35 | 36 | 37 | 38 | 39 | 40 | 41 | ## Why? `fs.exists` already does the job! 42 | 43 | 44 | Because `fs.exists` and `fs.existsSync` ~~will be~~ are deprecated and in some cases we still need them! 45 | 46 | > `fs.exists()` is an anachronism and exists only for historical reasons. There should almost never be a reason to use it in your own code. 47 | > In particular, checking if a file exists before opening it is an anti-pattern that leaves you vulnerable to race conditions: another process may remove the file between the calls to `fs.exists()` and `fs.open()`. Just open the file and handle the error when it's not there. 48 | > **`fs.exists()` will be deprecated.** 49 | > ([Source](http://nodejs.org/api/fs.html#fs_fs_exists_path_callback), emphasis added) 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | ## :cloud: Installation 64 | 65 | ```sh 66 | # Using npm 67 | npm install --save is-there 68 | 69 | # Using yarn 70 | yarn add is-there 71 | ``` 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | ## :clipboard: Example 86 | 87 | 88 | 89 | ```js 90 | const IsThere = require("is-there"); 91 | 92 | // Sync 93 | console.log(IsThere(`${__dirname}/contents/file`)) 94 | // => true 95 | console.log(IsThere.directory(`${__dirname}/contents/dir`)) 96 | 97 | // Callback 98 | IsThere.file(`${__dirname}/contents/not_found`, exists => { 99 | console.log(exists) 100 | // => false 101 | }) 102 | 103 | // Promises 104 | IsThere.promises.directory(`${__dirname}/contents/dir`).then(exists => { 105 | console.log(exists) 106 | // => true 107 | }).catch(console.error) 108 | ``` 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | ## :question: Get Help 122 | 123 | There are few ways to get help: 124 | 125 | 126 | 127 | 1. Please [post questions on Stack Overflow](https://stackoverflow.com/questions/ask). You can open issues with questions, as long you add a link to your Stack Overflow question. 128 | 2. For bug reports and feature requests, open issues. :bug: 129 | 3. For direct and quick help, you can [use Codementor](https://www.codementor.io/johnnyb). :rocket: 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | ## :memo: Documentation 138 | 139 | 140 | ### isThere 141 | 142 | Checks if a file or directory exists on given path. 143 | Use without the new keyword. 144 | 145 | #### Params 146 | 147 | - **String** `path`: The path to the file or directory. 148 | - **Function** `callback`: The callback function called with a boolean value representing if the file or directory exists. If this parameter is not a 149 | function, the function will run synchronously and return the value. 150 | 151 | #### Return 152 | - **isThere|Boolean** The `isThere` function if the `callback` parameter was provided, otherwise a boolean value indicating if the file/directory 153 | exists or not. 154 | 155 | ### `isThere.directory(path, callback)` 156 | Checks if the path exists and it is a directory. 157 | 158 | #### Params 159 | 160 | - **String** `path`: The path to the directory. 161 | - **Function** `callback`: The callback function called with a boolean value representing if the directory exists. If this parameter is not a 162 | function, the function will run synchronously and return the value. 163 | 164 | #### Return 165 | - **isThere|Boolean** The `isThere` function if the `callback` parameter was provided, otherwise a boolean value indicating if the directory exists or not. 166 | 167 | ### `isThere.file(path, callback)` 168 | Check if the path exists and it is a file. 169 | 170 | #### Params 171 | 172 | - **String** `path`: The path to the file. 173 | - **Function** `callback`: The callback function called with a boolean value representing if the file exists. If this parameter is not a 174 | function, the function will run synchronously and return the value. 175 | 176 | #### Return 177 | - **isThere|Boolean** The `isThere` function if the `callback` parameter was provided, otherwise a boolean value indicating if the file exists or not. 178 | 179 | ### `isThere.promises()` 180 | The promises interface. 181 | 182 | It exports the following methods: 183 | 184 | - `isThere.promises.exists` 185 | - `isThere.promises.file` 186 | - `isThere.promises.directory` 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | ## :yum: How to contribute 202 | Have an idea? Found a bug? See [how to contribute][contributing]. 203 | 204 | 205 | ## :sparkling_heart: Support my projects 206 | I open-source almost everything I can, and I try to reply to everyone needing help using these projects. Obviously, 207 | this takes time. You can integrate and use these projects in your applications *for free*! You can even change the source code and redistribute (even resell it). 208 | 209 | However, if you get some profit from this or just want to encourage me to continue creating stuff, there are few ways you can do it: 210 | 211 | 212 | - Starring and sharing the projects you like :rocket: 213 | - [![Buy me a book][badge_amazon]][amazon]—I love books! I will remember you after years if you buy me one. :grin: :book: 214 | - [![PayPal][badge_paypal]][paypal-donations]—You can make one-time donations via PayPal. I'll probably buy a ~~coffee~~ tea. :tea: 215 | - [![Support me on Patreon][badge_patreon]][patreon]—Set up a recurring monthly donation and you will get interesting news about what I'm doing (things that I don't share with everyone). 216 | - **Bitcoin**—You can send me bitcoins at this address (or scanning the code below): `1P9BRsmazNQcuyTxEqveUsnf5CERdq35V6` 217 | 218 | ![](https://i.imgur.com/z6OQI95.png) 219 | 220 | 221 | Thanks! :heart: 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | ## :dizzy: Where is this library used? 239 | If you are using this library in one of your projects, add it in this list. :sparkles: 240 | 241 | - `@abendi/typed-css-modules` 242 | - `@beisen/typed-css-modules` 243 | - `@ceoimon/typed-css-modules` 244 | - `@computerrock/node-sass-json-importer` 245 | - `@dasilvacontin/clothes` 246 | - `@density/node-sass-json-importer` 247 | - `@fiovex/typed-css-modules` 248 | - `@groooves/typed-css-modules` 249 | - `@indigotree/dart-sass-json-importer` 250 | - `@isysd/gpm` 251 | - `@miriamjs/wml` 252 | - `@mizdra/typed-css-modules` 253 | - `@mtsmfm/node-sass-json-importer` 254 | - `@onenexus/synergy-sass-importer` 255 | - `@raydeck/wml` 256 | - `@skbkontur/typed-css-modules` 257 | - `@spernigotti/node-sass-json-importer` 258 | - `a-csv` 259 | - `ajs` 260 | - `ali-oss-extra` 261 | - `artstack-downloader` 262 | - `be-goods` 263 | - `better-history` 264 | - `bible` 265 | - `bible.js` 266 | - `blah` 267 | - `bloggify` 268 | - `bloggify-actions` 269 | - `bloggify-cli` 270 | - `bower-license-webpack-plugin` 271 | - `bowerrc` 272 | - `caipi` 273 | - `caipi-cli` 274 | - `cdnjs-importer` 275 | - `cecil` 276 | - `confetti-cli` 277 | - `dryduck` 278 | - `emartech-node-sass-json-importer` 279 | - `engine-app` 280 | - `engine-composition-crud` 281 | - `engine-tools` 282 | - `envctl` 283 | - `f-watcher` 284 | - `fie-toolkit-nuke` 285 | - `fie-toolkit-nuke-test` 286 | - `find-file-in-dirs` 287 | - `firstant2gradle` 288 | - `fontify` 289 | - `friendly-typed-css-modules` 290 | - `fwatcher` 291 | - `gd-cli` 292 | - `generator-arwen` 293 | - `generator-atomus` 294 | - `generator-catena` 295 | - `generator-catena-angular-meteor-bootstrap` 296 | - `generator-catena-angular-meteor-material` 297 | - `generator-leptir` 298 | - `generator-leptir-angular-bootstrap` 299 | - `generator-leptir-angular-material` 300 | - `gif-cli` 301 | - `git-issues` 302 | - `git-stats` 303 | - `git-stats-importer` 304 | - `gpm` 305 | - `grunt-md5symlink` 306 | - `gulp-app-build-tasks` 307 | - `gulp-common-build-tasks` 308 | - `hakka-plugin-typed-css-modules` 309 | - `hal-rc` 310 | - `heroku-container-tools` 311 | - `heroku-docker` 312 | - `hg-plus` 313 | - `idea` 314 | - `image-to-ascii-cli` 315 | - `is-git-check` 316 | - `jisc_build` 317 | - `joomlascan` 318 | - `kaomojify` 319 | - `kaomojify-webpack-plugin` 320 | - `khoom` 321 | - `kotori-webpack-plugin` 322 | - `le-serf` 323 | - `machine-ip` 324 | - `mage-module-shard` 325 | - `mage-validator` 326 | - `mage-vaulthelper-couchbase` 327 | - `mage-vaulthelper-mysql` 328 | - `matanza` 329 | - `megadata` 330 | - `memories` 331 | - `merry-plugin-typed-css-modules` 332 | - `minecraft-manager` 333 | - `minipod` 334 | - `moneysavegb` 335 | - `mtsl` 336 | - `my613-cli` 337 | - `node-sass-json-importer` 338 | - `node-sass-token-importer` 339 | - `npm-interlink` 340 | - `obj2env-cli` 341 | - `parent-search` 342 | - `pawpy` 343 | - `payname` 344 | - `ramda-cli` 345 | - `rc-ts-scripts` 346 | - `rc-ts-tools` 347 | - `react-scripts-pro` 348 | - `react-scripts-pro6` 349 | - `react-scripts-pro7` 350 | - `react-scripts-pro8` 351 | - `reindex-cli` 352 | - `safe-file-write` 353 | - `singular_sake` 354 | - `sourcegate` 355 | - `sp-load` 356 | - `tester-init` 357 | - `tilda-init` 358 | - `tithe` 359 | - `ts-css-module` 360 | - `typed-css-interfaces` 361 | - `typed-css-modules` 362 | - `typed-css-modules-babel` 363 | - `typed-css-modules-fork` 364 | - `typed-css-modules-lf` 365 | - `unity-asset-sync` 366 | - `unity-link` 367 | - `uturi-caching` 368 | - `valkctl` 369 | - `valkyrja` 370 | - `viur-ignite-css` 371 | - `viur-ignite-html` 372 | - `viur-ignite-icons` 373 | - `viur-ignite-js` 374 | - `watchwoman` 375 | - `watchwomen` 376 | - `web-term` 377 | - `wlink` 378 | - `wml` 379 | - `wmls` 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | ## :scroll: License 392 | 393 | [MIT][license] © [Ionică Bizău][website] 394 | 395 | 396 | 397 | 398 | 399 | 400 | [license]: /LICENSE 401 | [website]: https://ionicabizau.net 402 | [contributing]: /CONTRIBUTING.md 403 | [docs]: /DOCUMENTATION.md 404 | [badge_patreon]: https://ionicabizau.github.io/badges/patreon.svg 405 | [badge_amazon]: https://ionicabizau.github.io/badges/amazon.svg 406 | [badge_paypal]: https://ionicabizau.github.io/badges/paypal.svg 407 | [badge_paypal_donate]: https://ionicabizau.github.io/badges/paypal_donate.svg 408 | [patreon]: https://www.patreon.com/ionicabizau 409 | [amazon]: http://amzn.eu/hRo9sIZ 410 | [paypal-donations]: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=RVXDDLKKLQRJW 411 | -------------------------------------------------------------------------------- /example/contents/dir/another/file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IonicaBizau/node-is-there/be35a631da8973a172faad21caeaf445b61b3ddf/example/contents/dir/another/file -------------------------------------------------------------------------------- /example/contents/dir/file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IonicaBizau/node-is-there/be35a631da8973a172faad21caeaf445b61b3ddf/example/contents/dir/file -------------------------------------------------------------------------------- /example/contents/file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IonicaBizau/node-is-there/be35a631da8973a172faad21caeaf445b61b3ddf/example/contents/file -------------------------------------------------------------------------------- /example/contents/file.ext: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IonicaBizau/node-is-there/be35a631da8973a172faad21caeaf445b61b3ddf/example/contents/file.ext -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | const IsThere = require("../lib"); 2 | 3 | // Sync 4 | console.log(IsThere(`${__dirname}/contents/file`)) 5 | // => true 6 | console.log(IsThere.directory(`${__dirname}/contents/dir`)) 7 | 8 | // Callback 9 | IsThere.file(`${__dirname}/contents/not_found`, exists => { 10 | console.log(exists) 11 | // => false 12 | }) 13 | 14 | // Promises 15 | IsThere.promises.directory(`${__dirname}/contents/dir`).then(exists => { 16 | console.log(exists) 17 | // => true 18 | }).catch(console.error) 19 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | const fs = require("fs") 4 | 5 | /** 6 | * isThere 7 | * Checks if a file or directory exists on given path. 8 | * Use without the new keyword. 9 | * 10 | * @functionisThere 11 | * @param {String} path The path to the file or directory. 12 | * @param {Function} callback The callback function called with a boolean value 13 | * representing if the file or directory exists. If this parameter is not a 14 | * function, the function will run synchronously and return the value. 15 | * @return {isThere|Boolean} The `isThere` function if the `callback` parameter 16 | * was provided, otherwise a boolean value indicating if the file/directory 17 | * exists or not. 18 | */ 19 | const isThere = (path, callback) => { 20 | // Async 21 | if (typeof callback === "function") { 22 | fs.stat(path, err => { 23 | callback(!err) 24 | }) 25 | return isThere 26 | } 27 | 28 | // Sync 29 | try { 30 | fs.statSync(path) 31 | return true 32 | } catch (err) { 33 | return false 34 | } 35 | } 36 | 37 | /** 38 | * isThere.directory 39 | * Checks if the path exists and it is a directory. 40 | * 41 | * @function isThere.directory 42 | * @memberOf isThere 43 | * @param {String} path The path to the directory. 44 | * @param {Function} callback The callback function called with a boolean value 45 | * representing if the directory exists. If this parameter is not a 46 | * function, the function will run synchronously and return the value. 47 | * @return {isThere|Boolean} The `isThere` function if the `callback` parameter 48 | * was provided, otherwise a boolean value indicating if the directory exists or not. 49 | */ 50 | isThere.directory = (path, callback) => { 51 | // Async 52 | if (typeof callback === "function") { 53 | fs.stat(path, (err, stats) => { 54 | const result = !!(stats && stats.isDirectory()) 55 | callback(result) 56 | }) 57 | return isThere 58 | } 59 | 60 | // Sync 61 | try { 62 | return fs.statSync(path).isDirectory() 63 | } catch (_err) { 64 | return false 65 | } 66 | 67 | return false 68 | } 69 | 70 | /** 71 | * isThere.file 72 | * Check if the path exists and it is a file. 73 | * 74 | * @function isThere.file 75 | * @memberOf isThere 76 | * @param {String} path The path to the file. 77 | * @param {Function} callback The callback function called with a boolean value 78 | * representing if the file exists. If this parameter is not a 79 | * function, the function will run synchronously and return the value. 80 | * @return {isThere|Boolean} The `isThere` function if the `callback` parameter 81 | * was provided, otherwise a boolean value indicating if the file exists or not. 82 | */ 83 | isThere.file = function(path, callback) { 84 | // Async 85 | if (typeof callback === "function") { 86 | fs.stat(path, (err, stats) => { 87 | const result = !!(stats && stats.isFile()) 88 | callback(result) 89 | }) 90 | return isThere 91 | } 92 | 93 | // Sync 94 | try { 95 | return fs.statSync(path).isFile() 96 | } catch (_err) { 97 | return false 98 | } 99 | 100 | return false 101 | } 102 | 103 | /** 104 | * isThere.promises 105 | * The promises interface. 106 | * 107 | * It exports the following methods: 108 | * 109 | * - `isThere.promises.exists` 110 | * - `isThere.promises.file` 111 | * - `isThere.promises.directory` 112 | * 113 | * @function isThere.promises 114 | * @memberOf isThere 115 | */ 116 | const promisify = fn => { 117 | return path => new Promise(res => fn(path, res)) 118 | } 119 | 120 | isThere.promises = { 121 | exists: promisify(isThere) 122 | , file: promisify(isThere.file) 123 | , directory: promisify(isThere.directory) 124 | } 125 | 126 | module.exports = isThere 127 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "is-there", 3 | "version": "4.5.2", 4 | "description": "Check if a file or directory exists in a given path.", 5 | "main": "lib/index.js", 6 | "directories": { 7 | "example": "example", 8 | "test": "test" 9 | }, 10 | "scripts": { 11 | "test": "mocha test" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git@github.com:IonicaBizau/node-is-there.git" 16 | }, 17 | "keywords": [ 18 | "fs", 19 | "exists", 20 | "file", 21 | "directory" 22 | ], 23 | "author": "Ionică Bizău (https://ionicabizau.net)", 24 | "contributors": [ 25 | "Kevin Harrison " 26 | ], 27 | "license": "MIT", 28 | "bugs": { 29 | "url": "https://github.com/IonicaBizau/node-is-there/issues" 30 | }, 31 | "homepage": "https://github.com/IonicaBizau/node-is-there", 32 | "dependencies": {}, 33 | "devDependencies": { 34 | "mocha": "^7.1.2" 35 | }, 36 | "blah": { 37 | "h_img": "http://i.imgur.com/ZHzpvvE.png", 38 | "description": [ 39 | { 40 | "h2": "Why? `fs.exists` already does the job!" 41 | }, 42 | { 43 | "p": "Because `fs.exists` and `fs.existsSync` ~~will be~~ are deprecated and in some cases we still need them!" 44 | }, 45 | { 46 | "blockquote": [ 47 | "`fs.exists()` is an anachronism and exists only for historical reasons. There should almost never be a reason to use it in your own code.", 48 | "In particular, checking if a file exists before opening it is an anti-pattern that leaves you vulnerable to race conditions: another process may remove the file between the calls to `fs.exists()` and `fs.open()`. Just open the file and handle the error when it's not there.", 49 | "**`fs.exists()` will be deprecated.**", 50 | "([Source](http://nodejs.org/api/fs.html#fs_fs_exists_path_callback), emphasis added)" 51 | ] 52 | } 53 | ] 54 | }, 55 | "files": [ 56 | "bin/", 57 | "app/", 58 | "lib/", 59 | "dist/", 60 | "src/", 61 | "scripts/", 62 | "resources/", 63 | "menu/", 64 | "cli.js", 65 | "index.js", 66 | "index.d.ts", 67 | "package-lock.json", 68 | "bloggify.js", 69 | "bloggify.json", 70 | "bloggify/" 71 | ] 72 | } -------------------------------------------------------------------------------- /test/contents/dir/another/file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IonicaBizau/node-is-there/be35a631da8973a172faad21caeaf445b61b3ddf/test/contents/dir/another/file -------------------------------------------------------------------------------- /test/contents/dir/file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IonicaBizau/node-is-there/be35a631da8973a172faad21caeaf445b61b3ddf/test/contents/dir/file -------------------------------------------------------------------------------- /test/contents/file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IonicaBizau/node-is-there/be35a631da8973a172faad21caeaf445b61b3ddf/test/contents/file -------------------------------------------------------------------------------- /test/contents/file.ext: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IonicaBizau/node-is-there/be35a631da8973a172faad21caeaf445b61b3ddf/test/contents/file.ext -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | const IsThere = require("../lib") 2 | , Assert = require("assert") 3 | 4 | describe('#path', () => { 5 | before(() => { 6 | // Paths to test 7 | PATHS = [ 8 | // exist 9 | ["dir", true] 10 | , ["dir/another", true] 11 | , ["dir/another/file", true] 12 | , ["dir/file", true] 13 | , ["file", true] 14 | , ["file.ext", true] 15 | // don't exist 16 | , ["foo", false] 17 | , ["foo/bar", false] 18 | , ["foo.bar", false] 19 | , ["foo/bar.foo", false] 20 | ].map((c) => { 21 | return [__dirname + "/contents/" + c[0], c[1]] 22 | }) 23 | }) 24 | 25 | // Sync 26 | it("should check the file/directory existence synchronously", cb => { 27 | PATHS.forEach((c) => { 28 | Assert.equal(IsThere(c[0]), c[1]) 29 | }) 30 | cb() 31 | }) 32 | 33 | // Async 34 | it("should check the file/directory existence asynchronously", cb => { 35 | function doSeq(i) { 36 | i = i || 0 37 | var cPath = PATHS[i] 38 | if (!cPath) { return cb() } 39 | IsThere(cPath[0], (exists) => { 40 | Assert.equal(exists, cPath[1]) 41 | doSeq(i + 1) 42 | }) 43 | } 44 | doSeq() 45 | }) 46 | 47 | it("should support promises", cb => { 48 | function doSeq(i) { 49 | i = i || 0 50 | var cPath = PATHS[i] 51 | if (!cPath) { return cb() } 52 | IsThere.promises.exists(cPath[0]).then(exists => { 53 | Assert.equal(exists, cPath[1]) 54 | doSeq(i + 1) 55 | }) 56 | } 57 | doSeq() 58 | }) 59 | }) 60 | 61 | describe('#directory', () => { 62 | before(() => { 63 | // Paths to test 64 | PATHS = [ 65 | // exist 66 | ["dir", true] 67 | , ["dir/another", true] 68 | , ["dir/another/file", false] 69 | , ["dir/file", false] 70 | , ["file", false] 71 | , ["file.ext", false] 72 | // don't exist 73 | , ["foo", false] 74 | , ["foo/bar", false] 75 | , ["foo.bar", false] 76 | , ["foo/bar.foo", false] 77 | ].map((c) => { 78 | return [__dirname + "/contents/" + c[0], c[1]] 79 | }) 80 | }) 81 | 82 | // Sync 83 | it("should check the directory existence synchronously", cb => { 84 | PATHS.forEach((c) => { 85 | Assert.equal(IsThere.directory(c[0]), c[1]) 86 | }) 87 | cb() 88 | }) 89 | 90 | // Async 91 | it("should check the directory existence asynchronously", cb => { 92 | function doSeq(i) { 93 | i = i || 0 94 | var cPath = PATHS[i] 95 | if (!cPath) { return cb() } 96 | IsThere.directory(cPath[0], (exists) => { 97 | Assert.equal(exists, cPath[1]) 98 | doSeq(i + 1) 99 | }) 100 | } 101 | doSeq() 102 | }) 103 | 104 | it("should support promises", cb => { 105 | function doSeq(i) { 106 | i = i || 0 107 | var cPath = PATHS[i] 108 | if (!cPath) { return cb() } 109 | IsThere.promises.directory(cPath[0]).then(exists => { 110 | Assert.equal(exists, cPath[1]) 111 | doSeq(i + 1) 112 | }) 113 | } 114 | doSeq() 115 | }) 116 | }) 117 | 118 | describe('#file', () => { 119 | before(() => { 120 | // Paths to test 121 | PATHS = [ 122 | // exist 123 | ["dir", false] 124 | , ["dir/another", false] 125 | , ["dir/another/file", true] 126 | , ["dir/file", true] 127 | , ["file", true] 128 | , ["file.ext", true] 129 | // don't exist 130 | , ["foo", false] 131 | , ["foo/bar", false] 132 | , ["foo.bar", false] 133 | , ["foo/bar.foo", false] 134 | ].map((c) => { 135 | return [__dirname + "/contents/" + c[0], c[1]] 136 | }) 137 | }) 138 | 139 | // Sync 140 | it("should check the file existence synchronously", cb => { 141 | PATHS.forEach((c) => { 142 | Assert.equal(IsThere.file(c[0]), c[1]) 143 | }) 144 | cb() 145 | }) 146 | 147 | // Async 148 | it("should check the file existence asynchronously", cb => { 149 | function doSeq(i) { 150 | i = i || 0 151 | var cPath = PATHS[i] 152 | if (!cPath) { return cb() } 153 | IsThere.file(cPath[0], (exists) => { 154 | Assert.equal(exists, cPath[1]) 155 | doSeq(i + 1) 156 | }) 157 | } 158 | doSeq() 159 | }) 160 | 161 | it("should support promises", cb => { 162 | function doSeq(i) { 163 | i = i || 0 164 | var cPath = PATHS[i] 165 | if (!cPath) { return cb() } 166 | IsThere.promises.file(cPath[0]).then(exists => { 167 | Assert.equal(exists, cPath[1]) 168 | doSeq(i + 1) 169 | }) 170 | } 171 | doSeq() 172 | }) 173 | }) 174 | --------------------------------------------------------------------------------