├── .editorconfig ├── .gitignore ├── .jshintrc ├── .npmignore ├── .travis.yml ├── License ├── README.md ├── changelog.md ├── lib └── index.js ├── package.json └── test └── all.test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | # Change these settings to your own preference 10 | indent_style = tab 11 | indent_size = 4 12 | 13 | # We recommend you to keep these unchanged 14 | end_of_line = lf 15 | charset = utf-8 16 | trim_trailing_whitespace = true 17 | insert_final_newline = true 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | coverage 4 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | // enforcing options 3 | "bitwise":true, 4 | "camelcase":true, 5 | "curly":false, 6 | "eqeqeq":false, 7 | "es3":false, 8 | "forin":false, 9 | "freeze":true, 10 | "immed":true, 11 | "indent":1, 12 | "latedef":"nofunc", 13 | "newcap":true, 14 | "noarg":true, 15 | "noempty":true, 16 | "nonbsp":true, 17 | "nonew":true, 18 | "plusplus":false, 19 | "quotmark":false, 20 | "undef":true, 21 | "unused":"strict", 22 | "strict":false, 23 | //"maxparams":false, 24 | //"maxdepth":false, 25 | //"maxstatements":false, 26 | //"maxcomplexity":false, 27 | //"maxlen":false, 28 | "-W041":false, // suppress "Use '===' to compare with '0'" errors 29 | 30 | // relaxing options 31 | "asi":false, 32 | "boss":false, 33 | "debug":false, 34 | "eqnull":false, 35 | "esversion":6, 36 | "evil":false, 37 | "expr":false, 38 | "funcscope":false, 39 | "globalstrict":false, 40 | "iterator":false, 41 | "lastsemic":false, 42 | "laxbreak":false, 43 | "laxcomma":false, 44 | "loopfunc":true, 45 | //"maxerr":false, 46 | "moz":false, 47 | "multistr":false, 48 | "notypeof":false, 49 | "proto":false, 50 | "scripturl":false, 51 | "shadow":false, 52 | "sub":false, 53 | "supernew":false, 54 | "validthis":false, 55 | "noyield":false, 56 | 57 | // environment options 58 | "node":true, 59 | 60 | "globals": { 61 | }, 62 | 63 | "predef": [ 64 | "-Promise" 65 | ] 66 | } 67 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test 2 | coverage 3 | .editorconfig 4 | .gitignore 5 | .jshintrc 6 | .npmignore 7 | .travis.yml 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | script: 2 | - "npm test" 3 | 4 | language: node_js 5 | 6 | node_js: 7 | - "4" 8 | - "6" 9 | 10 | branches: 11 | except: 12 | - /^v\d+\./ 13 | 14 | matrix: 15 | fast_finish: true 16 | include: 17 | - node_js: "4" 18 | env: COVERAGE=true 19 | allow_failures: 20 | - env: COVERAGE=true 21 | 22 | sudo: false 23 | -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Overlook Motel (theoverlookmotel@gmail.com) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fs-extra-promise.js 2 | 3 | # Node file system library and fs-extra module promisified with bluebird 4 | 5 | ## Current status 6 | 7 | [![NPM version](https://img.shields.io/npm/v/fs-extra-promise.svg)](https://www.npmjs.com/package/fs-extra-promise) 8 | [![Build Status](https://img.shields.io/travis/overlookmotel/fs-extra-promise/master.svg)](http://travis-ci.org/overlookmotel/fs-extra-promise) 9 | [![Dependency Status](https://img.shields.io/david/overlookmotel/fs-extra-promise.svg)](https://david-dm.org/overlookmotel/fs-extra-promise) 10 | [![Dev dependency Status](https://img.shields.io/david/dev/overlookmotel/fs-extra-promise.svg)](https://david-dm.org/overlookmotel/fs-extra-promise) 11 | [![Coverage Status](https://img.shields.io/coveralls/overlookmotel/fs-extra-promise/master.svg)](https://coveralls.io/r/overlookmotel/fs-extra-promise) 12 | 13 | API is stable. No tests at present but it seems to work fine! 14 | 15 | ## Usage 16 | 17 | This module is a drop-in replacement for the [native node file system module](http://nodejs.org/api/fs.html) and the augmented [fs-extra](https://www.npmjs.org/package/fs-extra) module. 18 | 19 | Additionally, it creates promisified versions of all `fs`'s and `fs-extra`'s async methods, using [bluebird](https://www.npmjs.org/package/bluebird). These methods are named the same as the original `fs`/`fs-extra` methods with `'Async'` added to the end of the method names. 20 | 21 | So instead of: 22 | 23 | ```js 24 | var fs = require('fs'); 25 | fs.readFile(path, function(err, data) { 26 | console.log(data); 27 | }); 28 | ``` 29 | 30 | You can now: 31 | 32 | ```js 33 | var fs = require('fs-extra-promise'); 34 | fs.readFileAsync(path).then(function(data) { 35 | console.log(data); 36 | }); 37 | ``` 38 | 39 | All original `fs` and `fs-extra` methods are included unmodified. 40 | 41 | ### `isDirectory()` methods 42 | 43 | For convenience, additional methods `isDirectory()`, `isDirectorySync()` and `isDirectoryAsync()` are provided. 44 | 45 | These are are shortcuts for doing `fs.stat()` followed by running `isDirectory()` on the result returned by `stat()`. 46 | 47 | ### `usePromise()` method 48 | 49 | Creates a new instance of `fs-extra-promise`, which uses the Promise implementation provided. 50 | 51 | ```js 52 | var Bluebird = require('bluebird'); 53 | var fs = require('fs-extra-promise').usePromise(Bluebird); 54 | 55 | // now use `fs-extra-promise` in the usual way 56 | var promise = fs.readFileAsync(path); 57 | 58 | console.log(promise instanceof Bluebird); // true 59 | ``` 60 | 61 | This can be useful for: 62 | 63 | * using a different version of [bluebird](https://www.npmjs.com/package/bluebird) 64 | * using a Promise implementation that supports `cls` 65 | * using an augmented version of Bluebird like [bluebird-extra](https://www.npmjs.org/package/bluebird-extra) 66 | 67 | ### `useFs()` method 68 | 69 | Creates a new instance of `fs-extra-promise`, promisifying the provide version of [fs-extra](https://www.npmjs.org/package/fs-extra). 70 | 71 | Most useful if you want to use a specific version of [fs-extra](https://www.npmjs.org/package/fs-extra). 72 | 73 | ```js 74 | var fs = require('fs-extra-promise').useFs(require('fs-extra')); 75 | ``` 76 | 77 | ## Tests 78 | 79 | Use `npm test` to run the tests. Use `npm run cover` to check coverage. 80 | 81 | There aren't any tests at present, except for running jshint on the code. 82 | 83 | ## Changelog 84 | 85 | See [changelog.md](https://github.com/overlookmotel/fs-extra-promise/blob/master/changelog.md) 86 | 87 | ## Issues 88 | 89 | If you discover a bug, please raise an issue on Github. https://github.com/overlookmotel/fs-extra-promise/issues 90 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.0.1 4 | 5 | * Initial release 6 | 7 | ## 0.1.0 8 | 9 | * Expose Promise object so it can be augmented (e.g. by bluebird-extra module) 10 | 11 | ## 0.1.1 12 | 13 | * Updated fs-extra dependency to v0.18.2 14 | * Updated bluebird dependency to v2.9.24 15 | * Travis runs tests against node 0.10 and 0.12 16 | * Travis runs on new container infrastructure 17 | 18 | ## 0.1.2 19 | 20 | * Update fs-extra dependency 21 | * Update bluebird dependency 22 | * Update dev dependencies 23 | * Run jshint on tests 24 | * Test code coverage & Travis sends to coveralls 25 | * README badges use shields.io 26 | 27 | ## 0.1.3 28 | 29 | * Disable Travis dependency cache 30 | 31 | ## 0.2.0 32 | 33 | * Update fs-extra dependency 34 | 35 | ## 0.2.1 36 | 37 | * Update fs-extra dependency 38 | * Update bluebird dependency 39 | * Update dev dependencies 40 | * Change `main` in package.json to `./lib/index` (closes #6) 41 | 42 | ## 0.3.0 43 | 44 | * `usePromise` method 45 | * Update bluebird dependency 46 | * Update dev dependencies 47 | * README update 48 | 49 | Breaking changes: 50 | 51 | * Now creates a new instance of `fs` rather than adding methods to the global `fs-extra` module 52 | 53 | ## 0.3.1 54 | 55 | * Update fs-extra dependency 56 | * `usePromise` method anonymous function 57 | * License update 58 | 59 | ## 0.4.0 60 | 61 | * `.useFs()` method 62 | * Update `fs-extra` dependency to v0.30.0 63 | * Update `bluebird` dependency to v3.4.0 64 | * Update dev dependencies 65 | * Change `main` in package.json to `./lib/` (closes #7) 66 | * JSDoc comments 67 | * README update 68 | * Replace `Makefile` with npm scripts 69 | * Travis tests against node v4 + v6 70 | * Update `.npmignore` 71 | * Update license 72 | 73 | ## 0.4.1 74 | 75 | * Update `bluebird` dependency to v3.4.6 76 | * Update dev dependencies 77 | * Ignore `.DS_Store` in `.gitignore` 78 | * Travis CI runs on all branches (to enable `greenkeeper.io`) 79 | 80 | ## 1.0.0 81 | 82 | * Update `fs-extra` dependency to v2.1.2 83 | * Update `bluebird` dependency to v3.5.0 84 | * Drop support for Node versions before 4.0 85 | * Fix: Do not promisify `createWriteStream` method 86 | * Refactor to ES6 + code style 87 | * Skip Travis CI runs on release tags 88 | * Update license 89 | 90 | ## 1.0.1 91 | 92 | * Update dev dependencies 93 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | /* -------------------- 2 | * fs-extra-promise 3 | * ------------------*/ 4 | 5 | 'use strict'; 6 | 7 | // Modules 8 | const fs = require('fs-extra'), 9 | Promise = require('bluebird'); 10 | 11 | // Exports 12 | 13 | /** 14 | * Factory to create promisified version of fs-extra. 15 | * Adds promisified methods for all async methods. 16 | * e.g. `fs.readFile(path, cb)` becomes `fs.readFileAsync(path)` 17 | * All original methods of `fs` and `fs-extra` modules are left untouched. 18 | * NB does not mutate `fs-extra` module - returns a new instance with extra methods added. 19 | * 20 | * @param {Object} fs - `fs-extra` module 21 | * @param {Object} Promise - Bluebird implementation to use 22 | * @returns {Object} - `fsExtra` with promisified methods added 23 | */ 24 | const factory = function(fs, Promise) { 25 | // Clone fs-extra 26 | const fsOriginal = fs; 27 | fs = {}; 28 | for (let methodName in fsOriginal) { 29 | fs[methodName] = fsOriginal[methodName]; 30 | } 31 | 32 | // Extend fs with isDirectory and isDirectorySync methods 33 | fs.isDirectory = (path, callback) => { 34 | fs.stat(path, (err, stats) => { 35 | if (err) { 36 | callback(err); 37 | } else { 38 | callback(null, stats.isDirectory()); 39 | } 40 | }); 41 | }; 42 | 43 | fs.isDirectorySync = path => fs.statSync(path).isDirectory(); 44 | 45 | // Promisify all methods 46 | // (except those ending with 'Sync', classes and various methods which do not use a callback) 47 | for (let methodName in fs) { 48 | let method = fs[methodName]; 49 | 50 | if (typeof method != 'function') continue; 51 | if (methodName.slice(-4) == 'Sync') continue; 52 | if (methodName.match(/^[A-Z]/)) continue; 53 | if (['exists', 'watch', 'watchFile', 'unwatchFile', 'createReadStream', 'createWriteStream'].indexOf(methodName) != -1) continue; 54 | 55 | fs[methodName + 'Async'] = Promise.promisify(method); 56 | } 57 | 58 | // Create fs.existsAsync() 59 | // fs.exists() is asynchronous but does not call callback with usual node (err, result) signature - uses just (result) 60 | fs.existsAsync = path => new Promise(resolve => fs.exists(path, resolve)); 61 | 62 | // Use methods to set Promise used internally (e.g. could use bluebird-extra module) 63 | // and version of `fs-extra` being promisified 64 | 65 | /** 66 | * Returns new instance of `fs-extra-promise` using the Promise implementation provided. 67 | * @param {Object} Promise - Promise implementation to use 68 | * @returns {Object} - Promisified `fs-extra` 69 | */ 70 | fs.usePromise = Promise => factory(fsOriginal, Promise); 71 | 72 | /** 73 | * Returns new instance of `fs-extra-promise` using the `fs` implementation provided. 74 | * @param {Object} fs - Version of `fs-extra` to use 75 | * @returns {Object} - Promisified `fs-extra` 76 | */ 77 | fs.useFs = fs => factory(fs, Promise); 78 | 79 | // Return fs 80 | return fs; 81 | }; 82 | 83 | // Export fs promisified with bluebird 84 | module.exports = factory(fs, Promise); 85 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fs-extra-promise", 3 | "version": "1.0.1", 4 | "description": "Node file system library and fs-extra module promisified with bluebird", 5 | "main": "./lib/", 6 | "author": { 7 | "name": "Overlook Motel" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/overlookmotel/fs-extra-promise.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/overlookmotel/fs-extra-promise/issues" 15 | }, 16 | "dependencies": { 17 | "fs-extra": "^2.1.2", 18 | "bluebird": "^3.5.0" 19 | }, 20 | "devDependencies": { 21 | "mocha": "^3.2.0", 22 | "chai": "^3.5.0", 23 | "chai-as-promised": "^6.0.0", 24 | "jshint": "^2.9.4", 25 | "istanbul": "^0.4.5", 26 | "coveralls": "^2.13.0" 27 | }, 28 | "keywords": [ 29 | "fs", 30 | "fs-extra", 31 | "file", 32 | "promise", 33 | "bluebird", 34 | "extend" 35 | ], 36 | "scripts": { 37 | "test": "if [ $COVERAGE ]; then npm run coveralls; else npm run jshint && npm run test-main; fi", 38 | "jshint": "./node_modules/.bin/jshint lib test", 39 | "test-main": "./node_modules/mocha/bin/mocha --check-leaks --colors -t 10000 --reporter spec 'test/**/*.test.js'", 40 | "cover": "npm run cover-main && rm -rf coverage", 41 | "coveralls": "npm run cover-main && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage", 42 | "cover-main": "COVERAGE=true ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- -R spec 'test/**/*.test.js'" 43 | }, 44 | "engines": { 45 | "node": ">=4" 46 | }, 47 | "readmeFilename": "README.md", 48 | "license": "MIT" 49 | } 50 | -------------------------------------------------------------------------------- /test/all.test.js: -------------------------------------------------------------------------------- 1 | // -------------------- 2 | // fs-extra-promise 3 | // Tests 4 | // -------------------- 5 | 6 | // modules 7 | var chai = require('chai'), 8 | expect = chai.expect, 9 | promised = require('chai-as-promised'), 10 | fs = require('../lib/'); 11 | 12 | // init 13 | chai.use(promised); 14 | chai.config.includeStack = true; 15 | 16 | // tests 17 | 18 | /* jshint expr: true */ 19 | /* global describe, it */ 20 | 21 | describe('Tests', function() { 22 | it.skip('all features', function() { 23 | expect(fs).to.be.ok; 24 | }); 25 | }); 26 | --------------------------------------------------------------------------------