{"_id":"@marionebl/sander","_rev":"6466","name":"@marionebl/sander","description":"Promise-based power tool for common filesystem tasks","dist-tags":{"latest":"0.6.1"},"maintainers":[{"name":"marionebl","email":"root@mario-nebl.de"}],"time":{"modified":"2021-06-03T09:56:54.000Z","created":"2017-08-27T14:35:51.919Z","0.6.1":"2017-08-27T14:35:51.919Z"},"users":{},"author":{"name":"Rich Harris"},"repository":{"type":"git","url":"git+https://github.com/rich-harris/sander.git"},"versions":{"0.6.1":{"name":"@marionebl/sander","description":"Promise-based power tool for common filesystem tasks","author":{"name":"Rich Harris"},"version":"0.6.1","license":"MIT","repository":{"type":"git","url":"git+https://github.com/rich-harris/sander.git"},"dependencies":{"mkdirp":"^0.5.1","rimraf":"^2.5.2","graceful-fs":"^4.1.3"},"main":"dist/sander.cjs.js","jsnext:main":"dist/sander.es.js","devDependencies":{"buffer-crc32":"^0.2.5","mocha":"^3.2.0","rollup":"^0.36.4","rollup-plugin-buble":"^0.14.0"},"scripts":{"test":"mocha","pretest":"npm run build","build":"rollup -c","prepublish":"npm test"},"files":["dist","README.md"],"gitHead":"cac06032df04cce75aed334e1ec1a331387a9243","bugs":{"url":"https://github.com/rich-harris/sander/issues"},"homepage":"https://github.com/rich-harris/sander#readme","_id":"@marionebl/sander@0.6.1","_shasum":"1958965874f24bc51be48875feb50d642fc41f7b","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.11.2","_npmUser":{"name":"marionebl","email":"hello@mario-nebl.de"},"dist":{"shasum":"1958965874f24bc51be48875feb50d642fc41f7b","size":21263,"noattachment":false,"key":"/@marionebl/sander/-/@marionebl/sander-0.6.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/@marionebl/sander/download/@marionebl/sander-0.6.1.tgz"},"maintainers":[{"name":"marionebl","email":"root@mario-nebl.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/sander-0.6.1.tgz_1503844550833_0.8365021017380059"},"directories":{},"publish_time":1503844551919,"_cnpm_publish_time":1503844551919,"_hasShrinkwrap":false}},"readme":"# sander\n\nA Promise-based power tool for common filesystem tasks in node.js.\n\n## Installation\n\n```bash\nnpm install sander\n```\n\n## Another wrapper around `fs`? Really?\n\nYup. Working with the low-level `fs` API is the fastest road to callback hell, and while a lot of the existing `fs` wrappers add a whole load of missing features, they don't really mitigate the fundamental suckiness of working with the filesystem in a painful, imperative way, which forces you to handle errors at every step of the journey towards the centre of the node.js [pyramid of doom](http://stackoverflow.com/search?q=pyramid+of+doom).\n\n**Enough! Manual filing is tedious - you need a power tool.** Instead of writing this...\n\n```js\nvar path = require( 'path' ),\n    fs = require( 'fs' ),\n    mkdirp = require( 'mkdirp' );\n\nvar dest = path.resolve( basedir, filename );\n\nmkdirp( path.dirname( dest ), function ( err ) {\n  if ( err ) throw err;\n\n  fs.writeFile( dest, data, function ( err ) {\n    if ( err ) throw err;\n    doTheNextThing();\n  });\n});\n```\n\n...write this:\n\n```js\nvar sander = require( 'sander' );\nsander.writeFile( basedir, filename, data ).then( doTheNextThing );\n```\n\nIt uses [graceful-fs](https://github.com/isaacs/node-graceful-fs) rather than the built-in `fs` module, to eliminate [EMFILE](http://blog.izs.me/post/56827866110/wtf-is-emfile-and-why-does-it-happen-to-me) from the list of things you have to worry about.\n\n\n## Conventions\n\n### Promises\n\nAll async methods (those whose `fs` equivalents would take a callback, e.g. `sander.readFile`) return a Promise. If you're not familiar with Promises, [read up on them on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) - they're coming in ES6 and are already supported in many browsers, and I guarantee they'll make your life easier.\n\n(Node doesn't natively support promises yet - we're using [es6-promise](https://github.com/jakearchibald/es6-promise) for maximum compatibility. For convenience, the `Promise` constructor is exposed as `sander.Promise`.)\n\n### Intermediate folder creation\n\nWhen writing files and folders, intermediate folders are automatically created as necessary. (I've never encountered a situation where I wanted an `ENOENT` error instead of having this be done for me.)\n\n### Automatic path resolution\n\nWherever appropriate, method arguments are joined together with `path.resolve()` - so the following are equivalent:\n\n```js\nsander.readFile( 'foo', 'bar', 'baz' );\nsander.readFile( path.resolve( 'foo', 'bar', 'baz' ) );\nsander.readFile( 'foo/bar/baz' ); // or 'foo\\bar\\baz' on Windows\n```\n\n### Methods that involve two paths\n\nSome operations, such as renaming files, require two paths to be specified. The convention for handling this in sander is as follows:\n\n```js\nsander.rename( basedir, oldname ).to( basedir, newname );\n```\n\n\n\n## Methods\n\n### `fs` methods\n\nIn addition to the extra methods (listed below), all `fs` methods have `sander` equivalents. The synchronous methods (those ending `Sync`) are the same as the `fs` originals except that path resolution and intermediate folder creation are automatically handled (see [conventions](#conventions), above). All async methods return a promise.\n\nFor more information about what these methods do, consult the [node documentation](http://nodejs.org/api/fs.html).\n\nIn the list below, `...paths` indicates you can use one or more strings in sequence, as per the [automatic path resolution](#automatic-path-resolution) convention. An `fd` argument refers to a file descriptor, which you'd generate with `sander.open()` or `sander.openSync()`. Arguments wrapped in `[]` characters are optional.\n\n```js\nsander.appendFile(...paths, data, [options])\nsander.appendFileSync(...paths, data, [options])\nsander.chmod(...paths, {mode: mode})\nsander.chmodSync(...paths, {mode: mode})\nsander.chown(...paths, uid, gid)\nsander.chownSync(...paths, uid, gid)\nsander.close(fd)\nsander.closeSync(fd)\nsander.createReadStream(...paths, [options])\nsander.createWriteStream(...paths, [options])\nsander.exists(...paths)\nsander.existsSync(...paths)\nsander.fchmod(fd, {mode: mode})\nsander.fchmodSync(fd, {mode: mode})\nsander.fchown(fd, uid, gid)\nsander.fchownSync(fd, uid, gid)\nsander.fstat(fd)\nsander.fstatSync(fd)\nsander.fsync(fd)\nsander.fsyncSync(fd)\nsander.ftruncate(fd, len)\nsander.ftruncateSync(fd, len)\nsander.futimes(fd, atime, mtime)\nsander.futimesSync(fd, atime, mtime)\nsander.lchmod(...paths, {mode: mode})\nsander.lchmodSync(...paths, {mode: mode})\nsander.lchown(...paths, uid, gid)\nsander.lchownSync(...paths, uid, gid)\nsander.link(...paths).to(...paths)\nsander.linkSync(...paths).to(...paths)\nsander.lstat(...paths)\nsander.lstatSync(...paths)\nsander.mkdir(...paths, [{mode: mode}])\nsander.mkdirSync(...paths, [{mode: mode}])\nsander.open(...paths, flags, [{mode: mode}])\nsander.openSync(...paths, flags, [{mode: mode}])\nsander.read(fd, buffer, offset, length, position)\nsander.readSync(fd, buffer, offset, length, position)\nsander.readdir(...paths)\nsander.readdirSync(...paths)\nsander.readFile(...paths, [options])\nsander.readFileSync(...paths, [options])\nsander.readlink(...paths)\nsander.readlinkSync(...paths)\nsander.realpath(...paths, [cache])\nsander.realpathSync(...paths, [cache])\nsander.rename(...paths).to(...paths)\nsander.renameSync(...paths).to(...paths)\nsander.rmdir(...paths)\nsander.rmdirSync(...paths)\nsander.stat(...paths)\nsander.statSync(...paths)\nsander.symlink(...paths).to(...paths, [{type: type}])\nsander.symlinkSync(...paths).to(...paths, [{type: type}])\nsander.truncate(...paths, len)\nsander.truncateSync(...paths, len)\nsander.unlink(...paths)\nsander.unlinkSync(...paths)\nsander.utimes(...paths, atime, mtime)\nsander.utimesSync(...paths, atime, mtime)\nsander.unwatchFile(...paths, [listener])\nsander.watch(...paths, [options], [listener])\nsander.watchFile(...paths, [options], listener)\nsander.write(fd, buffer, offset, length, position)\nsander.writeSync(fd, buffer, offset, length, position)\nsander.writeFile(...paths, data, [options])\nsander.writeFileSync(...paths, data, [options])\n```\n\nNote that with the `chmod`/`fchmod`/`lchmod`/`symlink`/`mkdir`/`open` methods (and their synchronous equivalents), the `mode` and `type` arguments must be passed as objects with a `mode` or `type` property. This is so that sander knows which arguments should be treated as parts of a path (because they're strings) and which shouldn't.\n\nThe same is true for methods like `readFile` - whereas in node you can do `fs.readFile('path/to/file.txt', 'utf-8')` if you want to specify utf-8 encoding, with sander the final argument should be a `{encoding: 'utf-8'}` object.\n\n\n### Extra methods\n\n```js\n// Copy a file using streams. `readOptions` is passed to `fs.createReadStream`,\n// while `writeOptions` is passed to `fs.createWriteStream`\nsander.copyFile(...paths, [readOptions]).to(...paths, [writeOptions])\n\n// Copy a file synchronously. `readOptions`, is passed to `fs.readFileSync`,\n// while `writeOptions` is passed to `fs.writeFileSync`\nsander.copyFileSync(...paths, [readOptions]).to(...paths, [writeOptions])\n\n// Copy a directory, recursively. `readOptions` and `writeOptions` are\n// treated as per `sander.copyFile[Sync]`\nsander.copydir(...paths, [readOptions]).to(...paths, [writeOptions])\nsander.copydirSync(...paths, [readOptions]).to(...paths, [writeOptions])\n\n// List contents of a directory, recursively\nsander.lsr(...paths)\nsander.lsrSync(...paths)\n\n// Remove a directory and its contents\nsander.rimraf(...paths)\nsander.rimrafSync(...paths)\n\n// Symlink a file or directory, unless we're on Windows in which\n// case fall back to copying to avoid permissions issues\nsander.symlinkOrCopy(...paths).to(...paths);\nsander.symlinkOrCopySync(...paths).to(...paths);\n```\n\n\n### License\n\nMIT\n\n","_attachments":{},"homepage":"https://github.com/rich-harris/sander#readme","bugs":{"url":"https://github.com/rich-harris/sander/issues"},"license":"MIT"}