pax_global_header00006660000000000000000000000064146673065310014525gustar00rootroot0000000000000052 comment=b93c9779ca50a07b7bdbc10875f0ccc606f84600 medikoo-fs2-b93c977/000077500000000000000000000000001466730653100142155ustar00rootroot00000000000000medikoo-fs2-b93c977/.editorconfig000066400000000000000000000004561466730653100166770ustar00rootroot00000000000000# EditorConfig is awesome: http://EditorConfig.org # top-most EditorConfig file root = true [*] charset = utf-8 end_of_line = lf insert_final_newline = true indent_style = tab trim_trailing_whitespace = true [*.{md,yml}] indent_size = 2 indent_style = space [*.md] trim_trailing_whitespace = false medikoo-fs2-b93c977/.github/000077500000000000000000000000001466730653100155555ustar00rootroot00000000000000medikoo-fs2-b93c977/.github/FUNDING.yml000066400000000000000000000000201466730653100173620ustar00rootroot00000000000000github: medikoo medikoo-fs2-b93c977/.github/workflows/000077500000000000000000000000001466730653100176125ustar00rootroot00000000000000medikoo-fs2-b93c977/.github/workflows/integrate.yml000066400000000000000000000004021466730653100223130ustar00rootroot00000000000000# main only name: Integrate on: push: branches: [main] env: FORCE_COLOR: 1 jobs: _: uses: medikoo/github-actions-workflows/.github/workflows/no-tests-integrate.yml@main secrets: USER_GITHUB_TOKEN: ${{ secrets.USER_GITHUB_TOKEN }} medikoo-fs2-b93c977/.github/workflows/publish.yml000066400000000000000000000004721466730653100220060ustar00rootroot00000000000000# Version tags only name: Publish on: push: tags: - v[0-9]+.[0-9]+.[0-9]+ env: FORCE_COLOR: 1 jobs: _: uses: medikoo/github-actions-workflows/.github/workflows/publish.yml@main secrets: USER_GITHUB_TOKEN: ${{ secrets.USER_GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} medikoo-fs2-b93c977/.github/workflows/validate.yml000066400000000000000000000003011466730653100221200ustar00rootroot00000000000000# PR's only name: Validate on: pull_request: branches: [main] env: FORCE_COLOR: 1 jobs: _: uses: medikoo/github-actions-workflows/.github/workflows/no-tests-validate.yml@main medikoo-fs2-b93c977/.gitignore000066400000000000000000000000571466730653100162070ustar00rootroot00000000000000/node_modules npm-debug.log /package-lock.json medikoo-fs2-b93c977/.npmignore000066400000000000000000000000541466730653100162130ustar00rootroot00000000000000/.editorconfig /CHANGELOG.md /CHANGES /test medikoo-fs2-b93c977/CHANGELOG.md000066400000000000000000000236771466730653100160450ustar00rootroot00000000000000# Changelog All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. ## [0.3.10](https://github.com/medikoo/fs2/compare/v0.3.9...v0.3.10) (2024-09-08) ### Features - `emptyDirSync` util ([7ad4055](https://github.com/medikoo/fs2/commit/7ad40550dc80444245daff89b4fec462a97840bf)) - `isFile` util ([d4ceee8](https://github.com/medikoo/fs2/commit/d4ceee8b873cc6838af65f2e55f42d94c46b24ee)) - `unlinkSync` function ([b80d0cd](https://github.com/medikoo/fs2/commit/b80d0cd0645871b88e89d901863e7b4803bd3358)) - Allow empty directory at `copyDir` destination ([2b9bbd6](https://github.com/medikoo/fs2/commit/2b9bbd6438bb774b98151c24952d5be6f2c367d4)) - **Symlink:** - `--force` option ([5216782](https://github.com/medikoo/fs2/commit/5216782a293967511d5841639ef5e74136116f54)) - `--loose` option ([c87a45b](https://github.com/medikoo/fs2/commit/c87a45b91fc918c943c26337fe51488b79836e5e)) - Return`true` if symlink was created ([a522bd8](https://github.com/medikoo/fs2/commit/a522bd81529c8e3eb35c5a9151daf30cb4af9ea8)) ### Bug Fixes - Fix directory rename across different devices ([24d70e1](https://github.com/medikoo/fs2/commit/24d70e119f008b213475d1cb103dd4572978eeaa)) - **rmdir:** Ensure `--force` option empties directory contents ([23d3f3a](https://github.com/medikoo/fs2/commit/23d3f3ac765951c0130c146a092202f5f79bbf79)) - **Symlink:** Fix resolution of `linkPath` option ([0ee13f6](https://github.com/medikoo/fs2/commit/0ee13f65e7616587ee9351dd52f14e0bf19814f1)) ### Maintenance Improvements - Clear ESLint errors ([0696308](https://github.com/medikoo/fs2/commit/0696308f033d04a106334792101fb330576bb385)) 33124bbd74d94d60629e6fb5ce712a74e04871b8)) - Fix lint issues ([cd4e2c6](https://github.com/medikoo/fs2/commit/cd4e2c638026cedd77f418bf23c8de456c5455e7)) - Prettier ([b8188b2](https://github.com/medikoo/fs2/commit/b8188b2119996f8ff434348df1c32fc10433af1d)) - Refactor `rename` to ES2015+ ([553c799](https://github.com/medikoo/fs2/commit/553c799acc557224bdc3ef40849ad39dcf4bae2c)) - Refactor `symlink` to ES2015 ([5ff2670](https://github.com/medikoo/fs2/commit/5ff26708c54a3c299cb904dfa675ff32101402aa)) - Refactor to ES2015 ([ae2c181](https://github.com/medikoo/fs2/commit/ae2c181d1653952d6c2f1d95cbf7a37c34a47394)) - Refactor to ES2015 ([22e8cbe](https://github.com/medikoo/fs2/commit/22e8cbe6b121f5cf55191e1bf61774d2125e7c54)) - Refactor to ES2015 ([433fe9c](https://github.com/medikoo/fs2/commit/433fe9c34c644e7754f99f7b716ba1ee8b97737c)) - Refactor to ES2015+ ([dc2b946](https://github.com/medikoo/fs2/commit/dc2b946025ed03eec2f58c69e8e19a8446d1d84c)) - Respect ESLint rules ([5f7e4cd](https://github.com/medikoo/fs2/commit/5f7e4cd516f1958d8ed7a9507c3f3818814dbf58)) - Reuse `emptyDirSync` logic in `rmDirSync` ([6cd7026](https://github.com/medikoo/fs2/commit/6cd7026b9f66b961bbfdd411be997f3b648c16b7)) - Simplify configuration of `test` command ([3bced0e](https://github.com/medikoo/fs2/commit/3bced0e8f453ddbe5ca93bae2f0930cd9ba3934b)) - Simplify meta configuration ([65ae563](https://github.com/medikoo/fs2/commit/65ae5633540804664fc713208e4deb70ff28265f)) - To ES2015 ([b10e364](https://github.com/medikoo/fs2/commit/b10e36426dc7430834ccd4cafe975d8d051cd374)) - Upgrade `eslint` to v8 and `eslint-config-medikoo` to v4 ([11a7d11](https://github.com/medikoo/fs2/commit/11a7d11eee46f6e6d00a43f9c8ec5b4b39599e11)) ### [0.3.9](https://github.com/medikoo/fs2/compare/v0.3.8...v0.3.9) (2020-11-19) ### Features - rmdirSync util ([3c50c17](https://github.com/medikoo/fs2/commit/3c50c17198bd77e52c2889e3ce05161d790250a8)) ### [0.3.8](https://github.com/medikoo/fs2/compare/v0.3.7...v0.3.8) (2020-04-27) ### Bug Fixes - Fix `mode` normalization in `fs.access` ([00f2a52](https://github.com/medikoo/fs2/commit/00f2a52b139576b5b5adcec7c3c01bb84b905076)) ### [0.3.7](https://github.com/medikoo/fs2/compare/v0.3.6...v0.3.7) (2019-11-07) ### Features - 'silent' option for mkdir ([e3fe863](https://github.com/medikoo/fs2/commit/e3fe863)) ### [0.3.6](https://github.com/medikoo/fs2/compare/v0.3.5...v0.3.6) (2019-09-26) ### Bug Fixes - Ensure to not leave open file descriptors when write crashes ([cf8ef7e](https://github.com/medikoo/fs2/commit/cf8ef7e)) ### Features - Expose debug stats in descriptors handler ([cdcac3f](https://github.com/medikoo/fs2/commit/cdcac3f)) ### [0.3.5](https://github.com/medikoo/fs2/compare/v0.3.4...v0.3.5) (2019-07-10) ### Features - 'append' mode for chmod ([afa7aaa](https://github.com/medikoo/fs2/commit/afa7aaa)) ## [0.3.4](https://github.com/medikoo/fs2/compare/v0.3.3...v0.3.4) (2019-02-04) ### Features - 'force' option for copy ([85a3560](https://github.com/medikoo/fs2/commit/85a3560)) ## [0.3.3](https://github.com/medikoo/fs2/compare/v0.3.2...v0.3.3) (2019-02-04) ### Features - 'access' util ([d85f934](https://github.com/medikoo/fs2/commit/d85f934)) - hasAccess util ([8c53ea9](https://github.com/medikoo/fs2/commit/8c53ea9)) ## [0.3.2](https://github.com/medikoo/fs2/compare/v0.3.1...v0.3.2) (2019-02-04) ### Bug Fixes - readdir 'loose' option handling with depth: Infinity ([f2c19ac](https://github.com/medikoo/fs2/commit/f2c19ac)) ## [0.3.1](https://github.com/medikoo/fs2/compare/v0.3.0...v0.3.1) (2019-01-31) ### Features - **readdir:** loose option ([7b2a5e7](https://github.com/medikoo/fs2/commit/7b2a5e7)) # [0.3.0](https://github.com/medikoo/fs2/compare/v0.2.21...v0.3.0) (2019-01-07) ### Bug Fixes - Ensure git ignore resolution works as expected ([c5d68fb](https://github.com/medikoo/fs2/commit/c5d68fb)) ### BREAKING CHANGES - Due to switch to 'ignore' not supporting Node below v6, drop support for old verions of Node.js. ## [0.2.21](https://github.com/medikoo/fs2/compare/v0.2.20...v0.2.21) (2018-11-15) ### Bug Fixes - 'loose' option handling on windows ([3788ebf](https://github.com/medikoo/fs2/commit/3788ebf)) ## [0.2.20](https://github.com/medikoo/fs2/compare/v0.2.19...v0.2.20) (2018-11-07) ### Bug Fixes - **copyDir:** symlink copying ([c0e4a6f](https://github.com/medikoo/fs2/commit/c0e4a6f)) ## [0.2.19](https://github.com/medikoo/fs2/compare/v0.2.18...v0.2.19) (2018-10-31) ### Bug Fixes - **symlink:** for symlink we should not fully resolve link path ([ae17653](https://github.com/medikoo/fs2/commit/ae17653)) ## [0.2.18](https://github.com/medikoo/fs2/compare/v0.2.17...v0.2.18) (2018-10-31) ### Bug Fixes - remove problematic stream.destroy() ([ceb67b9](https://github.com/medikoo/fs2/commit/ceb67b9)) - **copy:** validate destination existence ([7662c1e](https://github.com/medikoo/fs2/commit/7662c1e)) - **copyDir:** fix duplicate file copying ([41ff83b](https://github.com/medikoo/fs2/commit/41ff83b)) ## [0.2.17](https://github.com/medikoo/fs2/compare/v0.2.16...v0.2.17) (2018-10-31) ### Bug Fixes - **copyDir:** throw if destination path exists ([812fdfb](https://github.com/medikoo/fs2/commit/812fdfb)) ## [0.2.16](https://github.com/medikoo/fs2/compare/v0.2.15...v0.2.16) (2018-10-31) ### Features - copyDir util ([2f45d62](https://github.com/medikoo/fs2/commit/2f45d62)) ## [0.2.15](https://github.com/medikoo/fs2/compare/v0.2.14...v0.2.15) (2018-10-25) ### Bug Fixes - **readlink:** improve loose option handling ([b54f193](https://github.com/medikoo/fs2/commit/b54f193)) - improve arguments handling ([c32f340](https://github.com/medikoo/fs2/commit/c32f340)) - **lstat:** fix loose option handling ([889b829](https://github.com/medikoo/fs2/commit/889b829)) ### Features - isDirectory util ([835b4a9](https://github.com/medikoo/fs2/commit/835b4a9)) ## [0.2.14](https://github.com/medikoo/fs2/compare/v0.2.13...v0.2.14) (2018-10-24) ### Bug Fixes - **readlink:** fix support for loose option on existing non-symlinks ([3c52970](https://github.com/medikoo/fs2/commit/3c52970)) ## [0.2.13](https://github.com/medikoo/fs2/compare/v0.2.12...v0.2.13) (2018-10-24) ### Bug Fixes - require path ([6aa87f7](https://github.com/medikoo/fs2/commit/6aa87f7)) ## [0.2.12](https://github.com/medikoo/fs2/compare/v0.2.11...v0.2.12) (2018-10-24) ### Features - readlink util ([c5c63c7](https://github.com/medikoo/fs2/commit/c5c63c7)) ## [0.2.11](https://github.com/medikoo/fs2/compare/v0.2.10...v0.2.11) (2018-10-23) ### Features - introduce realpath ([727e7b8](https://github.com/medikoo/fs2/commit/727e7b8)) ## [0.2.10](https://github.com/medikoo/fs2/compare/v0.2.9...v0.2.10) (2018-09-14) ### Bug Fixes - support for very old versions of Node.js ([73bc389](https://github.com/medikoo/fs2/commit/73bc389)) ### Features - rm util, removes either file or directory ([6733df6](https://github.com/medikoo/fs2/commit/6733df6)) ## [0.2.9](https://github.com/medikoo/fs2/compare/v0.2.8...v0.2.9) (2018-09-13) ### Features - support "loose" option in stat and lstat ([76306c4](https://github.com/medikoo/fs2/commit/76306c4)) ## [0.2.8](https://github.com/medikoo/fs2/compare/v0.2.7...v0.2.8) (2018-09-07) ### Features - support `intermediate` option in symlink ([5846d47](https://github.com/medikoo/fs2/commit/5846d47)) ## [0.2.7](https://github.com/medikoo/fs2/compare/v0.2.6...v0.2.7) (2017-09-05) ### Bug Fixes - bring back node v0.12 support ([370fa80](https://github.com/medikoo/fs2/commit/370fa80)) ## [0.2.6](https://github.com/medikoo/fs2/compare/v0.2.5...v0.2.6) (2017-06-19) ## [0.2.5](https://github.com/medikoo/fs2/compare/v0.2.4...v0.2.5) (2017-06-16) ### Features - "loose" option for fs.copy ([885cba7](https://github.com/medikoo/fs2/commit/885cba7)) - resolve successful copy with `true` ([72d4961](https://github.com/medikoo/fs2/commit/72d4961)) ## Old Changelog See `CHANGES` medikoo-fs2-b93c977/CHANGES000066400000000000000000000037631466730653100152210ustar00rootroot00000000000000For new changelog see CHANGELOG.md v0.2.4 -- 2017.03.15 * Fix race condition issues in readdir and mkdir * Fix desciptor limiter for Node.js at v1.2 and greater * In descriptor limiter aside of EMFILE errors handle also ENFILE errors * Support cross device rename v0.2.3 -- 2015.09.14 * Fix error handling in rmdir v0.2.2 -- 2015.09.10 * Add `appendFile` * Implement `intermediate` option support for `copy` * Implement `dirFilter` option support for `readdir` * Implement `intermediate` option support for `rename` * Assure that on files copy mode is preserved * Fix writeFile so override of mode is supported * Improve and generalise descriptors handler logic * Fix spelling of LICENSE * Configure lint scripts v0.2.1 -- 2014.04.27 * Update package.json to use latest 'tad' engine (fixes tests evaluation in v0.8) v0.2.0 -- 2014.04.27 * Move out main modules out of lib folder * 'loose' option for rmdir * 'loose' option for unlink * 'intermediate' option for writeFile * Fix race condition issues in readdir * Fix `unwatch` call in watchAlt * Add fs.rename * Add fs.symlink * Update internals to use latest versions of dependencies * Remove Makefile, it's cross environment package * Update documentation v0.1.5 -- 2013.04.10 * Improve stream and error handling in `copy` * Promise version of fs.stat v0.1.4 -- 2013.02.08 * Fix error handling in copy * Improve copy by allowing to pass options to underlying fs.createWriteStream v0.1.3 -- 2013.02.08 * Fix callback support in readdir * Improved error handling in findRoot * Added missing Licence (MIT) v0.1.2 -- 2013.01.16 * Promise version of rmdir with recursive and force options * Promise versions of lstat, chmod, lchmod, unlink * Fix global and relative rules matching in isIgnored * Use primitive memoization for isIgnored map v0.1.1 -- 2012.10.04 * Fixed few race condition cases * Better lock logic in _watch * Fix readdir test for Windows * Better error message in readFile v0.1.0 -- 2012.10.04 Initial version (derived from next package) medikoo-fs2-b93c977/LICENSE000066400000000000000000000014051466730653100152220ustar00rootroot00000000000000ISC License Copyright (c) 2012-2023, Mariusz Nowak, @medikoo, medikoo.com Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. medikoo-fs2-b93c977/README.md000066400000000000000000000305601466730653100155000ustar00rootroot00000000000000# fs2 ## Functions that complement and extend [fs](http://nodejs.org/api/all.html#all_file_system) package _Originally derived from [node-ext](https://github.com/medikoo/node-ext) package._ ## Installation $ npm install fs2 ## API ### access(path[, mode[, cb]]) _(fs2/access)_ Same as [fs.access](https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback). Returns promise. ### chmod(path, mode[, cb]) _(fs2/chmod)_ Same as [fs.chmod](http://nodejs.org/api/all.html#all_fs_lchmod_path_mode_callback). Returns promise. Not available on Windows. Extra options: - **append** - If set to true, then given mode is appended to file ### copy(src, dest[, options[, cb]]) _(fs2/copy)_ Copy file, returns promise but accepts as well regular callback. Eventual options are passed to underlying [fs.createWriteStream](http://nodejs.org/api/all.html#all_fs_createwritestream_path_options) Extra options: - **force** - Overwrite destination if exists - **loose** - Do not error if source file doesn't exits, abort and resolve with `null` instead. - **intermediate** - Whether to create directories recursively (if parent is not created), ### copyDir(src, dest[, options[, cb]]) _(fs2/copy-dir)_ Copy directory recursively, returns promise but accepts as well regular callback. Supported options: - **loose** - Do not error if file doesn't exits or is inaccessible, return _false_ instead. ### descriptorsHandler() _(fs2/descriptors-handler)_ Initializes _EMFILE_ errors prevention. **To be used only in main modules. Never require it in generic module that may be required in others** How it works? If limit of descriptors is reached it holds the calls to native functions and releases them when taken descriptors are freed. Internally it provides same solution as [fs-graceful](https://github.com/isaacs/node-graceful-fs) module with following differences: 1. Focuses only on file descriptors limit problem 2. Gives access to taken/available descriptors count and allows setting of limit by external module. Thanks to that we can also cover descriptors opened by fs.watch module ([watch](#watchpath) is bound to that module) 3. Covers readdir calls (which also happen to throw _EMFILE_ errors) 4. More bulletproof (I assume) error handling logic ### emptyDirSync(path[, options]) _(fs2/empty-dir-sync)_ Empty directory synchronously Supported options: - **recursive** - Attempt to empty directory content recursively (if not set, command will succeed only on removing top level directory files) ### hasAccess(path[, options[, cb]]) _(fs2/has-access)_ Conditional version of [`access`](#accesspath-mode-cb-fs2access). Returns promise. Supported options: - **mode** - Passed as `mode` argument to [`access`](#accesspath-mode-cb-fs2access) - **loose** - Do not error if file doesn't exits, resolve with `null` instead. ### isDirectory(path[, cb]) _(fs2/is-directory)_ Whether path points to a directory Resolves with `true` if provided path points to a directory, `false` if provided path points to a non-directory file, `null` if there's no file at path. Returns promise. ### isFile(path[, cb]) _(fs2/is-file)_ Whether path points to existing file Resolves with `true` if provided path points to a file, `false` if provided path points to existing non-directory file, `null` if there's no file at path. Returns promise. ### isIgnored(mode, path[, options[, cb]]) _(fs2/is-ignored)_ Whether file is ignored up to predefined rules. Returns promise but regular callback is also supported. Rules are decided by _mode_ argument. Currently only `git` mode is supported, in that case rules are searched in _.gitignore_ files (Rules have effect only if placed in valid _git_ repositories). Other modes can be easily configured by extending `_ignoreModes` module (See _lib/fs/\_ignore-modes_ directory to see how it's done). Supported options: - **globalRules** `string|array` - additional global rules. They will be matched as if placed in filesystem root directory, it means that any rules found in existing ignore files may override them. - **watch** `bool` - whether to watch for changes. If ignore state would change, returned promise would emit `change` event with new value (_true_/_false_) ### isSymlink(path[, options[, cb]]) _(fs2/is-symlink)_ Whether path points to a symlimk Resolves with `true` if provided path points to symlink, `false` if provided path points to a non-symlink file, `null` if there's no file at path. Returns promise. Additionally resultion can be fine tuned for specific needs with below options: Supported options: - **linkPath** `string` - Expected linkPath to which symlink should point. If provided and symlink points elsewhere `false` is returned. - **recursive** `bool` - whether check for matching `linkPath` should be applied to final path (so if symlink points to other symlink we check against the final path, and not linked symlink path) ### lchmod(path, mode[, cb]) _(fs2/lchmod)_ Same as [fs.lchmod](http://nodejs.org/api/all.html#all_fs_lchmod_path_mode_callback). Returns promise. Only available on Mac OS X. ### lstat(path[, cb]) _(fs2/lstat)_ Same as [fs.lstat](http://nodejs.org/api/all.html#all_fs_lstat_path_callback). Returns promise. ### mkdir(path[, options|mode[, cb]]) _(fs2/mkdir)_ Extended version of native _mkdir_. Returns promise Supported options: - **mode** - Reflects _mode_ in [native version](http://nodejs.org/api/all.html#all_fs_mkdir_path_mode_callback) - **intermediate** - Whether to create directories recursively (if parent is not created), reflects `mkir -p`, internal implementation inspired by [Substack's node-mkdirp](https://github.com/substack/node-mkdirp/) - **silent** - Do not throw error if directory already exists ### readFile(path[, options][, cb]) _(fs2/read-file)_ Extended version of native [fs.readFile](http://nodejs.org/api/all.html#all_fs_readfile_filename_encoding_callback). Returns promise Supported options: - **loose** - Do not error if file doesn't exits or is inaccessible, return _null_ instead. - **watch** - Whether to watch file for changes. Changes are emited via _change_ event on returned promise. If file was removed and _loose_ option is off, _end_ event is emitted and watcher is closed ### readdir(path[, options[, cb]]) _(fs2/readdir)_ Extended version of native [fs.readdir](http://nodejs.org/api/all.html#all_fs_readdir_path_callback). Returns promise Suported options: - **loose** `boolean`- Resolve with `null` (instead of error) if directory doesn't exist - **depth** `number`- Level of recurse into subdirectories. Defaults to _0_ which resembles behavior of native version. If you want to recurse without any nest limitation just provide _Infinity_ - **type** `object`- Which type of files should be returned. By default all files are returned. [Stats methods](http://nodejs.org/api/all.html#all_class_fs_stats) shows how many different types can be returned. To narrow it down provide a hash. e.g. `{ file: true, symbolicLink: true }`. - **pattern** `regexp`- Filter returned files by specific pattern. Pattern should be regular expression that would be matched against full path. - **watch** `bool` - Watch directory for changes. Changes are emitted on returned promise with `change` events. _event_ object states which files were added (`event.added`) and which were removed (`event.removed`), **_Starting from next release (v0.4) this functionality will most likely be provided as valid Node.js [stream](http://nodejs.org/api/all.html#all_stream)_** - **stream** `bool` - Whether to provide data continuously. Currently it's not provided as a [stream](http://nodejs.org/api/all.html#all_stream) per se (it would be starting from next release, v0.4), data is emited as `change` events on returned promise object, structure of _event_ objects described under _watch_ option - **ignoreRules** `string|array` - Whether to obey ignore rules found in ignore files. See _[fs.isIgnored](#isignoredmode-path-options-cb)_ for more information - **globalRules** `string|array` - Global rules that complement ignoreRules. See _[fs.isIgnored](#isignoredmode-path-options-cb)_ for more information. - **dirFilter** `function|regexp` - Filter out directories into which we should not recurse to. Can be provided as function which having directory name should return boolaen (`true` if we should recurse into directory), or as regex which if matches means that directory should be recurse into. Neverthless `depth` setting is supported unconditionally ### readlink(path[, options[, cb]]) _(fs2/readlink)_ Same as [fs.readlink](http://nodejs.org/api/all.html#fs_fs_readlink_path_options_callback). Returns promise. Supports `loose: true` option, which when passed, resolves with `null` (instead of exception) if file at path is not a symlink or it doesn't exist. ### realpath(path[, options[, cb]]) _(fs2/realpath)_ Same as [fs.realpath](http://nodejs.org/api/all.html#fs_fs_realpath_path_options_callback). Returns promise. Supports `loose: true` option, which when passed, resolves with `null` (instead of exception) if path doesn't exist ### rename(oldPath, newPath[, cb]) _(fs2/rename)_ Same as [fs.rename](http://nodejs.org/api/all.html#all_fs_rename_oldpath_newpath_callback). Returns promise. Supported options: - **intermediate** - Whether to create directories recursively (if parent is not created) ### rmdir(path[, options[, cb]]) _(fs2/rmdir)_ Extended version of native _rmdir_. Returns promise Supported options: - **recursive** - Attempt to remove directory with subdirectories recursively. - **force** - Attempt to remove other files within directory as well. - **loose** - Do not error if directory doesn't exist ### rmdirSync(path[, options]) _(fs2/rmdir-sync)_ Extended version of native _rmdirSynnc_. Supported options: - **recursive** - Attempt to remove directory with all its content recursively. ### stat(path[, cb]) _(fs2/stat)_ Same as [fs.stat](http://nodejs.org/api/all.html#all_fs_stat_path_callback). Returns promise. ### symlink(srcPath, dstPath[, type[, cb]]) _(fs2/symlink)_ Same as [fs.symlink](http://nodejs.org/api/all.html#all_fs_symlink_srcpath_dstpath_type_callback). Returns promise that resolves with `true` if symlink was created (`false` can be returned with `loose` option, when symlink already exists) Supported options: - **intermediate** - Attempt to create directory with subdirectories in which symlink is expected to be placed if they do not exist - **loose** - Do not error if same symlink at path already exists - **force** - If there's other file at the path, remove and retry to create symlink ### typeByStats(stats) _(fs2/type-by-stats)_ Returns type of file according to provided [stats](http://nodejs.org/api/all.html#all_class_fs_stats) object. ### unlink(path[, cb]) _(fs2/unlink)_ Same as [fs.unlink](http://nodejs.org/api/all.html#all_fs_unlink_path_callback). Returns promise. Supported options: - **loose** - Do not error if file doesn't exist ### unlinkSync(path) _(fs2/unlink-sync)_ Same as [fs.unlinkSync](http://nodejs.org/api/all.html#all_fs_unlink_path_callback), but with support for extra options. Supported options: - **loose** - Do not error if file doesn't exist ### watchPath(path) _(fs2/watch-path)_ Watch specific path for changes. It's about observing specific file path (not directory content). `change` events are emitted with event object where `event.type` says wether file was created, modified or removed. ### watch(path) _(fs2/watch)_ Watch file for changes. [fs.watch](http://nodejs.org/api/all.html#all_fs_watch_filename_options_listener) wrapper that works same way on every platform, always configured in _persistent: false_ mode. It's aware of open file descriptors limitations, if _EMFILE_ error is approach, switch to alternative mode that pings file stats (see [fs.watchFile](http://nodejs.org/api/all.html#all_fs_watchfile_filename_options_listener)) is made. ### writeFile(filename, data[, options|encoding[, callback]]) _(fs2/write-file)_ Same as native [fs.writeFile](http://nodejs.org/api/all.html#all_fs_writefile_filename_data_encoding_callback) but safe for simultaneous calls of write to same file (in such case current write will be abandonded, and new would be started). Supported options: - **encoding** - Reflects _encoding_ in [native version](http://nodejs.org/api/all.html#all_fs_writefile_filename_data_options_callback) - **intermediate** - In case directory doesn't exist, whether to create full directory path ## Tests [![Build Status](https://travis-ci.org/medikoo/fs2.png?branch=master)](https://travis-ci.org/medikoo/fs2) $ npm test medikoo-fs2-b93c977/access.js000066400000000000000000000016361466730653100160220ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , resolve = require("path").resolve , fs = require("fs"); var original = fs.access, defaultMode = (fs.constants || fs).R_OK; var access = function (path, mode) { var def = deferred(); original(path, mode, function (err, stats) { if (err) { def.reject(err); } else { def.resolve(stats); } }); return def.promise; }; access.returnsPromise = true; module.exports = function (path/*[, mode[, callback]]*/) { var mode, cb; path = resolve(String(path)); mode = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(mode)) { cb = mode; mode = defaultMode; } else if (isValue(mode)) { mode = Number(mode); } return access(path, mode).cb(cb); }; module.exports.returnsPromise = true; module.exports.access = access; medikoo-fs2-b93c977/append-file.js000066400000000000000000000030121466730653100167330ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , isString = require("es5-ext/string/is-string") , deferred = require("deferred") , pathUtils = require("path") , original = require("fs").appendFile , mkdir = require("./mkdir").mkdir , dirname = pathUtils.dirname , resolve = pathUtils.resolve; var _appendFile = function (path, data, options, pResolve, reject) { original(path, data, options, function (err) { var dir; if (!isValue(err)) { pResolve(null); return; } if (!options.intermediate) { reject(err); return; } if (err.code !== "ENOENT") { reject(err); return; } dir = dirname(path); if (dir === path) { reject(err); return; } mkdir(dir, { intermediate: true }).cb(function () { _appendFile(path, data, options, pResolve, reject); }, reject); }); }; var appendFile = function (path, data, options) { var def = deferred(); _appendFile(path, data, options, def.resolve, def.reject); return def.promise; }; appendFile.returnsPromise = true; module.exports = exports = function (path, data/*, options*/) { var cb, options; path = resolve(String(path)); options = arguments[2]; cb = arguments[3]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = isString(options) ? { encoding: options } : Object(options); } return appendFile(path, data, options).cb(cb); }; exports.returnsPromise = true; exports.appendFile = appendFile; medikoo-fs2-b93c977/chmod.js000066400000000000000000000024361466730653100156520ustar00rootroot00000000000000"use strict"; if (process.platform === "win32") { module.exports = null; return; } var isValue = require("type/value/is") , isObject = require("type/object/is") , isPlainFunction = require("type/plain-function/is") , deferred = require("deferred") , resolve = require("path").resolve , original = require("fs").chmod , lstat = require("./lstat").lstat; var bareChmod = function (path, mode) { var def = deferred(); original(path, mode, function (err, stats) { if (err) def.reject(err); else def.resolve(stats); }); return def.promise; }; var chmod = function (path, mode, options) { if (!options.append) return bareChmod(path, mode); return lstat(path).then(function (stats) { var targetMode = stats.mode | mode; if (targetMode === stats.mode) return stats; return bareChmod(path, targetMode); }); }; chmod.returnsPromise = true; module.exports = exports = function (path, mode/*, options, callback*/) { var options = arguments[2], callback = arguments[3]; if (!isValue(callback) && isPlainFunction(options)) { callback = options; options = {}; } else if (!isObject(options)) { options = {}; } return chmod(resolve(String(path)), mode, options).cb(callback); }; exports.returnsPromise = true; exports.chmod = chmod; medikoo-fs2-b93c977/commitlint.config.js000066400000000000000000000012361466730653100202000ustar00rootroot00000000000000"use strict"; module.exports = { rules: { "body-leading-blank": [2, "always"], "body-max-line-length": [2, "always", 72], "footer-leading-blank": [2, "always"], "footer-max-line-length": [2, "always", 72], "header-max-length": [2, "always", 72], "scope-case": [2, "always", "start-case"], "scope-enum": [2, "always", [""]], "subject-case": [2, "always", "sentence-case"], "subject-empty": [2, "never"], "subject-full-stop": [2, "never", "."], "type-case": [2, "always", "lower-case"], "type-empty": [2, "never"], "type-enum": [ 2, "always", ["build", "chore", "ci", "docs", "feat", "fix", "perf", "refactor", "style", "test"] ] } }; medikoo-fs2-b93c977/copy-dir.js000066400000000000000000000046151466730653100163070ustar00rootroot00000000000000"use strict"; const isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , startsWith = require("es5-ext/string/#/starts-with") , deferred = require("deferred") , path = require("path") , lstat = require("./lstat") , mkdir = require("./mkdir") , readdir = require("./readdir") , readlink = require("./readlink") , symlink = require("./symlink") , copyFile = require("./copy").copy; const copyDir = function (source, dest, options, sourceTop, destTop) { return readdir(source, { type: { directory: true, file: true, symbolicLink: true }, depth: Infinity })( files => deferred.map(files, relativePath => { const filename = path.resolve(source, relativePath); return lstat(filename)(stats => { if (stats.isDirectory()) { return mkdir(path.resolve(dest, relativePath), { intermediate: true }); } if (stats.isFile()) { return copyFile(filename, path.resolve(dest, relativePath), { intermediate: true }); } if (!stats.isSymbolicLink()) return null; return readlink(filename)(linkPath => { linkPath = path.resolve(path.dirname(filename), linkPath); const linkDirname = path.dirname(linkPath); if ( linkDirname === sourceTop || startsWith.call(linkDirname, sourceTop + path.sep) ) { linkPath = path.resolve(destTop, linkPath.slice(sourceTop.length + 1)); } return symlink( path.relative(path.dirname(path.resolve(dest, relativePath)), linkPath), path.resolve(dest, relativePath), { intermediate: true } ); }); }); }), error => { if (options.loose && error.code === "ENOENT") return false; throw error; } )(true); }; copyDir.returnsPromise = true; module.exports = exports = function (source, dest, options = null, cb = null) { if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } source = path.resolve(String(source)); dest = path.resolve(String(dest)); return lstat(dest, { loose: true })(stats => { if (stats && stats.isDirectory()) { return readdir(dest).then(filenames => { if (!filenames.length) return; throw new Error("Destination path is not empty"); }); } return null; })(() => copyDir(source, dest, options, source, dest)).cb(cb); }; exports.copyDir = copyDir; exports.returnsPromise = true; medikoo-fs2-b93c977/copy.js000066400000000000000000000062751466730653100155370ustar00rootroot00000000000000/* eslint max-lines: off */ // Copy file // Credit: Isaac Schlueter // http://groups.google.com/group/nodejs/msg/ef4de0b516f7d5b8 "use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , normalizeOptions = require("es5-ext/object/normalize-options") , d = require("d") , deferred = require("deferred") , fs = require("fs") , path = require("path") , mkdir = require("./mkdir") , rm = require("./rm") , unlink = require("./unlink"); var objHasOwnProperty = Object.prototype.hasOwnProperty , defineProperty = Object.defineProperty , dirname = path.dirname , resolve = path.resolve , createReadStream = fs.createReadStream , createWriteStream = fs.createWriteStream , stat = fs.stat; var fixOptions = function (options) { if (options.hasOwnProperty) return options; return defineProperty(options, "hasOwnProperty", d(objHasOwnProperty)); }; var copyFileWithMode = function (def, source, dest, options) { var read, write; var isReadDisposed = false; try { read = createReadStream(source); } catch (e) { return def.reject(e); } read.on("error", function (e) { if (isReadDisposed) return; if (options.loose && e.code === "ENOENT") def.resolve(unlink(dest, { loose: true })(false)); else def.reject(e); }); try { write = createWriteStream(dest, fixOptions(options)); } catch (e1) { read.destroy(); return def.reject(e1); } write.on("error", function (e) { isReadDisposed = true; read.destroy(); if (e.code === "ENOENT" && options.intermediate) { mkdir(dirname(resolve(dest)), { intermediate: true }).done(function () { options = normalizeOptions(options); delete options.intermediate; return copyFileWithMode(def, source, dest, options); }, def.reject); return; } def.reject(e); }); read.pipe(write); write.on("close", def.resolve.bind(def, true)); return def.promise; }; var copyFile = function (source, dest, options) { var def = deferred(); if (options.mode) { copyFileWithMode(def, source, dest, options); return def.promise; } stat(source, function (e, stats) { if (e) { if (options.loose && e.code === "ENOENT") { def.resolve(false); return; } def.reject(e); return; } options = normalizeOptions(options); options.mode = stats.mode; stat(dest, function (error) { if (!error) { if (options.force) { rm(dest, { recursive: true, force: true, loose: true }).then(function () { return copyFileWithMode(def, source, dest, options); }); } else { def.reject(new Error("Destinaton '" + dest + "' exists")); } } else if (error.code === "ENOENT") { copyFileWithMode(def, source, dest, options); } else { def.reject(error); } }); }); return def.promise; }; copyFile.returnsPromise = true; module.exports = exports = function (source, dest/*, options, cb*/) { var options = Object(arguments[2]), cb = arguments[3]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } return copyFile(String(source), String(dest), options).cb(cb); }; exports.copy = copyFile; exports.returnsPromise = true; medikoo-fs2-b93c977/descriptors-handler.js000066400000000000000000000071771466730653100205430ustar00rootroot00000000000000/* eslint max-lines: off */ "use strict"; var last = require("es5-ext/array/#/last") , defineLength = require("es5-ext/function/_define-length") , callable = require("es5-ext/object/valid-callable") , d = require("d") , memoize = require("memoizee") , fs = require("fs"); var max = Math.max , slice = Array.prototype.slice , limit = Infinity , count = 0 , queue = [] , debugStats = { fd: 0, unknown: 0 }; var release = function () { var data, fnCb; // eslint-disable-next-line no-unmodified-loop-condition while (count < limit && (data = queue.shift())) { try { data.fn.apply(data.context, data.args); } catch (e) { fnCb = last.call(data.args); if (typeof fnCb === "function") fnCb(e); } } }; var wrap = function (asyncFn, type) { var self; debugStats[type] = 0; callable(asyncFn); return (self = defineLength(function () { var openCount, args = arguments, context, cb = last.call(args); if (!exports.initialized || typeof cb !== "function") return asyncFn.apply(this, arguments); if (count >= limit) { queue.push({ fn: self, context: this, args: arguments }); return null; } openCount = count++; context = this; args = slice.call(args, 0, -1); args.push(function (err, resultIgnored) { --debugStats[type]; --count; if (err && (err.code === "EMFILE" || err.code === "ENFILE")) { if (limit > openCount) limit = openCount; queue.push({ fn: self, context: context, args: args }); release(); return; } release(); if (typeof cb === "function") cb.apply(this, arguments); }); ++debugStats[type]; return asyncFn.apply(this, args); }, asyncFn.length)); }; module.exports = exports = memoize(function () { var open = fs.open, openSync = fs.openSync, close = fs.close, closeSync = fs.closeSync; if (exports.initialized) return; fs.open = function (path, flags, mode, fnCb) { var openCount, args; if (count >= limit) { queue.push({ fn: fs.open, context: this, args: arguments }); return; } openCount = count++; args = arguments; fnCb = last.call(args); ++debugStats.fd; open(path, flags, mode, function (err, fd) { if (err) { --debugStats.fd; --count; if (err.code === "EMFILE" || err.code === "ENFILE") { if (limit > openCount) limit = openCount; queue.push({ fn: fs.open, context: this, args: args }); release(); return; } release(); } if (typeof fnCb === "function") fnCb(err, fd); }); }; fs.openSync = function (pathIgnored, flagsIgnored, modeIgnored) { var result = openSync.apply(this, arguments); ++debugStats.fd; ++count; return result; }; fs.close = function (fd, fnCb) { close(fd, function (err) { if (!err) { --debugStats.fd; --count; release(); } if (typeof fnCb === "function") fnCb(err); }); }; fs.closeSync = function (fd) { var result; result = closeSync(fd); --debugStats.fd; --count; release(); return result; }; fs.readdir = wrap(fs.readdir, "readdir"); // Needed for Node >=1.2 because of commit e65308053c fs.readFile = wrap(fs.readFile, "readFile"); Object.defineProperty(exports, "initialized", d("e", true)); }); Object.defineProperties(exports, { initialized: d("ce", false), limit: d.gs( function () { return limit; }, function (nLimit) { if (limit >= nLimit) limit = max(nLimit, 5); } ), available: d.gs(function () { return max(limit - count, 0); }), taken: d.gs(function () { return count; }), open: d(function () { ++debugStats.unknown; ++count; }), close: d(function () { --debugStats.unknown; --count; if (release) release(); }), wrap: d(wrap), debugStats: d(debugStats) }); medikoo-fs2-b93c977/empty-dir-sync.js000066400000000000000000000030031466730653100174330ustar00rootroot00000000000000"use strict"; const fs = require("fs") , path = require("path") , ensureString = require("type/string/ensure") , isObject = require("type/object/is") , toShortString = require("type/lib/to-short-string"); const emptyDirSync = (dirname, options) => { let errors; for (const basename of fs.readdirSync(dirname)) { const filename = path.resolve(dirname, basename); try { const stats = fs.statSync(filename); if (stats.isDirectory()) { if (options.recursive) emptyDirSync(filename, options); rmDirSync(filename); } else { fs.unlinkSync(filename); } } catch (error) { if (!errors) errors = []; if (error.errors) errors.push(...error.errors); else errors.push(Object.assign(error, { _filename: filename })); } } if (errors) { throw Object.assign(new Error("Could not empty dir"), { errors }); } }; module.exports = (dirnameInput, options = {}) => { const dirname = path.resolve(ensureString(dirnameInput)); if (!isObject(options)) options = {}; try { emptyDirSync(dirname, options); } catch (error) { if (!error.errors) throw error; let errorMessage = `Could not remove ${ toShortString(dirnameInput) } due to:\n- ${ error.errors.slice(0, 5).map(({ code, _filename }) => `${ code } on ${ _filename }`) }`; if (error.errors.length > 5) { errorMessage += `\nand ${ error.errors.length - 5 } other errors`; } throw Object.assign(new Error(errorMessage), { errors: error.errors }); } }; const rmDirSync = require("./rmdir-sync"); medikoo-fs2-b93c977/has-access.js000066400000000000000000000013461466730653100165710ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , resolve = require("path").resolve , access = require("./access"); module.exports = function (path/*[, options[, callback]]*/) { path = resolve(String(path)); var options = arguments[1], cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } options = Object(options); return access(path, options.mode) .then( function () { return true; }, function (error) { if (options.loose && (error.code === "ENOENT" || error.code === "ENOTDIR")) { return null; } if (error.code === "EACCES") return false; throw error; } ) .cb(cb); }; medikoo-fs2-b93c977/index.js000066400000000000000000000016061466730653100156650ustar00rootroot00000000000000"use strict"; module.exports = { appendFile: require("./append-file"), chmod: require("./chmod"), copy: require("./copy"), copyDir: require("./copy-dir"), descriptorsHandler: require("./descriptors-handler"), isDirectory: require("./is-directory"), isIgnored: require("./is-ignored"), isSymlink: require("./is-symlink"), lchmod: require("./lchmod"), lstat: require("./lstat"), mkdir: require("./mkdir"), readFile: require("./read-file"), readdir: require("./readdir"), readlink: require("./readlink"), realpath: require("./realpath"), rename: require("./rename"), rm: require("./rm"), rmdir: require("./rmdir"), rmdirSync: require("./rmdir-sync"), stat: require("./stat"), symlink: require("./symlink"), typeByStats: require("./type-by-stats"), unlink: require("./unlink"), watch: require("./watch"), watchPath: require("./watch-path"), writeFile: require("./write-file") }; medikoo-fs2-b93c977/is-directory.js000066400000000000000000000004151466730653100171700ustar00rootroot00000000000000"use strict"; const { lstat } = require("./lstat"); module.exports = function (path, callback = null) { return lstat(path, { loose: true })(stats => { if (stats) return stats.isDirectory(); return null; }).cb(callback); }; module.exports.returnsPromise = true; medikoo-fs2-b93c977/is-file.js000066400000000000000000000004101466730653100160760ustar00rootroot00000000000000"use strict"; const { lstat } = require("./lstat"); module.exports = function (path, callback = null) { return lstat(path, { loose: true })(stats => { if (stats) return stats.isFile(); return null; }).cb(callback); }; module.exports.returnsPromise = true; medikoo-fs2-b93c977/is-ignored.js000066400000000000000000000164031466730653100166170ustar00rootroot00000000000000/* eslint max-statements: off, max-lines: off */ "use strict"; const invoke = require("es5-ext/function/invoke") , noop = require("es5-ext/function/noop") , isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , forEach = require("es5-ext/object/for-each") , memoize = require("memoizee") , deferred = require("deferred") , ignore = require("ignore") , pathUtils = require("path") , modes = require("./lib/ignore-modes") , getMap = require("./lib/get-conf-file-map") , memoizeWatcher = require("./lib/memoize-watcher") , findRoot = require("./lib/find-root"); const { isArray } = Array , { push } = Array.prototype , { call } = Function.prototype , trim = call.bind(String.prototype.trim) , { dirname } = pathUtils , { resolve } = pathUtils , { sep } = pathUtils , { ConfMap } = getMap , eolRe = /(?:\r\n|[\n\r\u2028\u2029])/u; const prepareRules = function (data) { return data.map(trim).filter(Boolean).reverse(); }; const parseSrc = function (src) { return prepareRules(String(src).split(eolRe)); }; const compile = function (maps, result) { const data = (result.data = {}), paths = (result.paths = []); // Merge rules found in ignorefiles maps.forEach(map => { forEach(map.map, (rules, path) => { if (!rules.length) return; if (!data[path]) { paths.push(path); data[path] = []; } data[path].push(rules); }); }); result.paths.sort(); return result; }; const applyRules = function (rules, rootPath, path) { if (!rootPath.endsWith(sep)) rootPath += sep; if (!path.startsWith(rootPath)) return { value: false, target: path }; rules = rules .slice() .reverse() .filter(rule => !rule.startsWith("#")); const ig = ignore().add(rules); const testPath = path.slice(rootPath.length); let result = ig.ignores(testPath); if (!result) { const excludeRules = rules.filter(rule => rule.startsWith("!")); if (excludeRules.length) { const ig2 = ignore().add(excludeRules.map(rule => rule.slice(1))); if (!ig2.ignores(testPath)) result = null; } else { result = null; } } return { value: result, target: path }; }; const applyGlobalRules = function (path, rules) { // Check global rules const value = applyRules(rules, path.slice(0, path.indexOf(sep) + 1), path); return Boolean(value.value); }; const buildMap = function (lDirname, lGetMap, watch) { let promise, maps; const data = {}; lGetMap = lGetMap.map((getSubMap, index) => { const map = getSubMap(lDirname); if (watch) { map.on("change", targetMap => { if (maps) { maps[index] = targetMap; compile(maps, data); promise.emit("change", data); } }); } return map; }); if (lGetMap.length > 1) { promise = deferred.map(lGetMap)(result => { maps = result; return compile(maps, data); }); } else { promise = lGetMap[0](map => { maps = [map]; return compile(maps, data); }); } if (watch) { promise.close = function () { lGetMap.forEach(invoke("close")); }; } return promise; }; const IsIgnored = function (path, watch) { this.path = path; this.dirname = dirname(path); this.watch = watch; }; IsIgnored.prototype = { init(mapPromise) { this.mapPromise = mapPromise; this.promise = mapPromise(data => { this.data = data; return this.calculate(); }); if (this.watch) { mapPromise.on("change", () => { const value = this.calculate(); if (value !== this.promise.value) { this.promise.value = value; this.promise.emit("change", value, this.path); } }); this.promise.close = this.close.bind(this); } return this.promise; }, close() { this.mapPromise.close(); }, calculate() { let current, result = false; if (!this.data.paths) return false; // Apply rules current = this.path; this.data.paths.some(function (rulesPath, index) { if (rulesPath.length > this.dirname.length) return true; if (index) { const dirIgnored = this.data.paths .slice(0, index) .some(function (preRulesPath) { return this.data.data[preRulesPath].some( rules => applyRules(rules, preRulesPath, rulesPath).value, this ); }, this); if (dirIgnored) return false; } this.data.data[rulesPath].forEach(function (rules) { let data = applyRules(rules, rulesPath, current); if (data.value === false && current !== pathUtils) { data = applyRules(rules, rulesPath, this.path); } if (data.target !== current || isValue(data.value)) { result = data.value; } current = data.target; }, this); return false; }, this); return Boolean(result); } }; const isIgnored = function (mode, path, options) { let globalRules, getMapFns, promise; if (isValue(options.globalRules)) { globalRules = isArray(options.globalRules) ? options.globalRules : String(options.globalRules).split(eolRe); } const { watch } = options; const lIsIgnored = new IsIgnored(path, watch); const lDirname = lIsIgnored.dirname; if (mode) { getMapFns = []; if (!globalRules) globalRules = []; if (!isArray(mode)) { if (!modes[mode]) throw new Error(`Unknown mode '${ mode }'`); mode = [mode]; } mode.forEach(name => { const lMode = modes[name]; if (!lMode) throw new Error(`Unknown mode '${ name }'`); getMapFns.push(pathIgnored => getMap(lDirname, lMode, watch, parseSrc)); if (lMode.globalRules) push.apply(globalRules, lMode.globalRules); }); } if (globalRules) { globalRules = prepareRules(globalRules); if (applyGlobalRules(path, globalRules)) { promise = deferred(true); if (watch) promise.close = noop; return promise; } } if (!mode) { promise = deferred(false); if (watch) promise.close = noop; return promise; } return lIsIgnored.init(buildMap(lDirname, getMapFns, watch)); }; isIgnored.returnsPromise = true; module.exports = exports = function (mode, path, options = {}, cb = null) { path = resolve(String(path)); if (!cb) { if (isCallable(options)) { cb = options; options = {}; } } return isIgnored(mode, path, options).cb(cb); }; exports.returnsPromise = true; exports.isIgnored = isIgnored; exports.IsIgnored = IsIgnored; exports.applyGlobalRules = applyGlobalRules; exports.getIsIgnored = function (modeNames, globalRules, watch) { const mapGetters = []; if (!globalRules) globalRules = []; const memo = watch ? memoizeWatcher : memoize; modeNames.forEach(name => { const mode = modes[name]; if (!mode) throw new Error(`Unknown mode '${ name }'`); const isRoot = memo(mode[watch ? "isRootWatcher" : "isRoot"], { primitive: true }); const readRules = memo(getMap[watch ? "readRulesWatcher" : "readRules"], { primitive: true }); mapGetters.push(path => { const map = new ConfMap(path, watch); map.filename = mode.filename; map.readRules = readRules; map.parse = parseSrc; return map.init(findRoot(isRoot, path, { watch })); }); if (mode.globalRules) push.apply(globalRules, mode.globalRules); }); const build = memo(lDirname => buildMap(lDirname, mapGetters, watch), { primitive: true }); return { isIgnored(path) { const lIsIgnored = new IsIgnored(path, watch); return lIsIgnored.init(build(lIsIgnored.dirname)); }, globalRules: globalRules.length ? prepareRules(globalRules) : null }; }; medikoo-fs2-b93c977/is-symlink.js000066400000000000000000000023241466730653100166530ustar00rootroot00000000000000"use strict"; const isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , { dirname } = require("path") , { resolve } = require("path") , { readlink } = require("./readlink") , { realpath } = require("./realpath"); module.exports = function (path, options = {}, cb = null) { path = resolve(String(path)); if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = Object(options); } const expectedLinkPath = options.linkPath ? resolve(dirname(path), String(options.linkPath)) : null; return readlink(path, {})( linkPath => { if (!linkPath) return null; if (!expectedLinkPath) return true; if (!options.recursive) return resolve(dirname(path), linkPath) === expectedLinkPath; return realpath(path, { loose: true })(finalLinkPath => { if (!finalLinkPath) return false; return finalLinkPath === expectedLinkPath; }); }, error => { if (error.code === "ENOENT") return null; if (error.code === "EINVAL") return false; if (error.code === "ENOTDIR") return null; if (error.code === "UNKNOWN") return null; throw error; } ).cb(cb); }; module.exports.returnsPromise = true; medikoo-fs2-b93c977/lchmod.js000066400000000000000000000011251466730653100160200ustar00rootroot00000000000000"use strict"; var deferred = require("deferred") , resolve = require("path").resolve , original = require("fs").lchmod , lchmod; lchmod = function (path, mode) { var def = deferred(); original(path, mode, function (err, stats) { if (err) def.reject(err); else def.resolve(stats); }); return def.promise; }; lchmod.returnsPromise = true; if (original) { module.exports = exports = function (path, mode/*, callback*/) { return lchmod(resolve(String(path)), mode).cb(arguments[2]); }; exports.returnsPromise = true; exports.lchmod = lchmod; } else { module.exports = null; } medikoo-fs2-b93c977/lib/000077500000000000000000000000001466730653100147635ustar00rootroot00000000000000medikoo-fs2-b93c977/lib/buffer-from.js000066400000000000000000000003611466730653100175330ustar00rootroot00000000000000// Maintain support for very old versions of Node.js "use strict"; module.exports = Buffer.from ? Buffer.from : function (data, encoding) { // eslint-disable-next-line no-buffer-constructor return new Buffer(data, encoding); }; medikoo-fs2-b93c977/lib/find-root.js000066400000000000000000000050731466730653100172270ustar00rootroot00000000000000"use strict"; var invoke = require("es5-ext/function/invoke") , assign = require("es5-ext/object/assign") , isValue = require("es5-ext/object/is-value") , forEach = require("es5-ext/object/for-each") , deferred = require("deferred") , dirname = require("path").dirname; // eslint-disable-next-line no-empty-function var FindRoot = function () {}; FindRoot.prototype = { known: false, close: function () { if (this.promises) { forEach(this.promises, invoke("close")); this.known = true; delete this.promises; } if (!this.promise.resolved) { this.reject(new Error("Find root action cancelled")); } }, onvalue: function (value) { if (this.known) { return; } if (value) { this.known = true; if (this.watch && this.promise.resolved) { this.promise.value = this.path; this.promise.emit("change", this.path); } else { this.resolve(this.path); } } else { this.down(); } }, next: function () { var isRoot; isRoot = this.isRoot(this.path); if (this.watch) { this.promises[this.path] = isRoot; isRoot.on("change", this.onevent); } isRoot.done(this.onvalue); }, down: function () { var dir = dirname(this.path); if (dir === this.path) { this.known = true; this.path = ""; if (this.watch && this.promise.resolved) { this.promise.value = null; this.promise.emit("change", null); } else { this.resolve(null); } return; } this.path = dir; this.next(); }, onevent: function (value, path) { var dir; if (value) { if (!isValue(path)) throw new TypeError("Path must be provided"); this.path = path; dir = dirname(path); while (this.promises[dir]) { this.promises[dir].close(); delete this.promises[dir]; dir = dirname(dir); } this.known = true; // Race condition may occur, double check if (this.promise.value !== this.path) { this.promise.value = this.path; this.promise.emit("change", this.path); } } else { if (!this.known || path !== this.path) { return; } this.known = false; this.down(); } } }; module.exports = function (isRoot, path/*, options*/) { var findRoot, options; options = arguments[2]; findRoot = new FindRoot(); findRoot.isRoot = isRoot; findRoot.path = path; findRoot.onvalue = findRoot.onvalue.bind(findRoot); findRoot.onevent = findRoot.onevent.bind(findRoot); assign(findRoot, deferred()); findRoot.watch = options && options.watch; if (findRoot.watch) { findRoot.promises = {}; findRoot.promise.close = findRoot.close.bind(findRoot); } findRoot.next(); return findRoot.promise; }; medikoo-fs2-b93c977/lib/get-conf-file-map.js000066400000000000000000000125561466730653100205240ustar00rootroot00000000000000// Function that provides map of rules found in ignorefiles for given ignorefile // type. Additinally it invokes event on changes in map which are results of // changes in ignorefiles. "use strict"; var invoke = require("es5-ext/function/invoke") , assign = require("es5-ext/object/assign") , isValue = require("es5-ext/object/is-value") , forEach = require("es5-ext/object/for-each") , isCopy = require("es5-ext/object/is-copy-deep") , endsWith = require("es5-ext/string/#/ends-with") , deferred = require("deferred") , pathUtils = require("path") , findRoot = require("./find-root") , readFile = require("../read-file").readFile , dirname = pathUtils.dirname , sep = pathUtils.sep , ConfMap , readRules , readRulesWatcher , paths , getMap , lockId = 0; paths = function (rootPath, path2) { var starter, data; starter = [rootPath]; if (rootPath === path2) { return starter; } if (endsWith.call(rootPath, sep)) { data = path2.slice(rootPath.length).split(sep); starter.push((rootPath += data.shift())); } else { data = path2.slice(rootPath.length + 1).split(sep); } return starter.concat(data.map(function (path) { return (rootPath += sep + path); })); }; readRules = function (path) { return this.readFile(path + sep + this.filename)( function (src) { return isValue(src) ? this.parse(src, path) : src; }.bind(this) ); }; readRulesWatcher = function (path) { var watcher, promise, current; watcher = this.readFile(path + sep + this.filename); promise = watcher( function (src) { return (current = isValue(src) ? this.parse(src, path) : src); }.bind(this) ); watcher.on( "change", function (data) { data = isValue(data) ? this.parse(data, path) : data; if (data === current) return; if ( isValue(current) && isValue(data) && typeof current === "object" && isCopy(current, data) ) { return; } current = promise.value = data; promise.emit("change", current, path); }.bind(this) ); promise.close = watcher.close; return promise; }; ConfMap = function (path, watch) { this.path = path; this.watch = watch; this.data = { root: null, map: {} }; assign(this, deferred()); if (this.watch) { this.onRulesChange = this.onRulesChange.bind(this); this.rulePromises = {}; this.promise.close = this.close.bind(this); } }; ConfMap.prototype = { init: function (lFindRoot) { this.findRoot = lFindRoot; if (this.watch) { lFindRoot.on("change", this.updateRoot.bind(this)); } lFindRoot.done( function (rootPath) { if (rootPath) { this.data.root = rootPath; this.addPaths(rootPath, this.path).done( function () { this.resolve(this.data); }.bind(this), this.resolve ); } else { this.resolve(this.data); } }.bind(this), this.resolve ); return this.promise; }, close: function () { if (this.rulePromises) { this.findRoot.close(); forEach(this.rulePromises, invoke("close")); delete this.rulePromises; } }, parse: String, readFile: function (path) { return readFile(path, { loose: true, watch: this.watch }); }, onRulesChange: function (rules, path) { if (isValue(rules)) { this.data.map[path] = rules; } else { delete this.data.map[path]; } this.promise.emit("change", this.data); }, addPaths: function (rootPath, path) { return deferred.map( paths(rootPath, path), function (lPath) { var rules = this.readRules(lPath); if (this.watch) { this.rulePromises[lPath] = rules; rules.on("change", this.onRulesChange); } return rules.aside( function (lRules) { if (isValue(lRules)) { this[lPath] = lRules; } }.bind(this.data.map) )( null, function (err) { // Watcher might have been closed in a meantime, if it was we ignore // this error as we're not interested in that value anymore return this.rulePromises[lPath] ? err : null; }.bind(this) ); }, this ); }, removePaths: function (rootPath, path) { paths(rootPath, path).forEach(function (lPath) { var promise = this.rulePromises[lPath]; delete this.rulePromises[lPath]; delete this.data.map[lPath]; promise.close(); }, this); }, updateRoot: function (rootPath) { var lock = ++lockId; if (!rootPath) { this.removePaths(this.data.root, this.path); this.data.root = null; this.promise.emit("change", this.data); } else if (!this.data.root) { this.data.root = rootPath; this.addPaths(rootPath, this.path).done( function () { if (lock === lockId) { this.promise.emit("change", this.data); } }.bind(this) ); } else if (this.data.root < rootPath) { this.removePaths(this.data.root, dirname(rootPath)); this.data.root = rootPath; this.promise.emit("change", this.data); } else { this.addPaths(rootPath, dirname(this.data.root)).done( function () { if (lock === lockId) { this.promise.emit("change", this.data); } }.bind(this) ); this.data.root = rootPath; } } }; getMap = module.exports = function (path, mode, watch, parse) { var map = new ConfMap(path, watch); map.filename = mode.filename; map.readRules = watch ? readRulesWatcher : readRules; if (parse) { map.parse = parse; } return map.init(findRoot(watch ? mode.isRootWatcher : mode.isRoot, path, { watch: watch })); }; getMap.ConfMap = ConfMap; getMap.readRules = readRules; getMap.readRulesWatcher = readRulesWatcher; medikoo-fs2-b93c977/lib/ignore-modes/000077500000000000000000000000001466730653100173535ustar00rootroot00000000000000medikoo-fs2-b93c977/lib/ignore-modes/git.js000066400000000000000000000020361466730653100204750ustar00rootroot00000000000000"use strict"; var deferred = require("deferred") , resolve = require("path").resolve , lstat = require("fs").lstat , WatchPath = require("../../watch-path").WatchPath , isRoot; exports.filename = ".gitignore"; exports.globalRules = [".git"]; exports.isRoot = isRoot = function (path) { var def, gPath; gPath = resolve(path, ".git"); def = deferred(); lstat(gPath, function (err, stats) { def.resolve(err ? false : stats.isDirectory()); }); def.promise.gitPath = gPath; def.promise.path = path; return def.promise; }; exports.isRoot.returnsPromise = true; exports.isRootWatcher = function (path) { var promise, watcher; promise = isRoot(path); watcher = new WatchPath(promise.gitPath); watcher.on("change", function (event) { if (event.type === "create") { promise.value = true; } else if (event.type === "remove") { promise.value = false; } else { return; } promise.emit("change", promise.value, path); }); promise.close = watcher.close; return promise; }; exports.isRootWatcher.returnsPromise = true; medikoo-fs2-b93c977/lib/ignore-modes/index.js000066400000000000000000000000731466730653100210200ustar00rootroot00000000000000"use strict"; module.exports = { git: require("./git") }; medikoo-fs2-b93c977/lib/memoize-watcher.js000066400000000000000000000020141466730653100204160ustar00rootroot00000000000000"use strict"; var noop = require("es5-ext/function/noop") , assign = require("es5-ext/object/assign") , memoize = require("memoizee") , ee = require("event-emitter") , eePipe = require("event-emitter/pipe") , deferred = require("deferred") , isPromise = deferred.isPromise; module.exports = function (fn/*, options*/) { var factory, memoized; if (fn.__memoized__) return fn; memoized = memoize(fn, assign(Object(arguments[1]), { refCounter: true })); factory = function () { var watcher, emitter, pipe, args, def; args = arguments; watcher = memoized.apply(this, arguments); if (isPromise(watcher)) { def = deferred(); emitter = def.promise; def.resolve(watcher); } else { emitter = ee(); } pipe = eePipe(watcher, emitter); emitter.close = function () { emitter.close = noop; pipe.close(); if (memoized.deleteRef.apply(this, args)) watcher.close(); }; return emitter; }; factory.clear = memoized.delete; factory.__memoized__ = true; return factory; }; medikoo-fs2-b93c977/lib/watch-alt.js000066400000000000000000000051101466730653100172020ustar00rootroot00000000000000"use strict"; var promisify = require("deferred").promisify , ee = require("event-emitter") , fs = require("fs") , typeByStats = require("../type-by-stats") , lstatSync = fs.lstatSync , readdir = promisify(fs.readdir) , watchFile = fs.watchFile , unwatchFile = fs.unwatchFile , other , directory , opts = { persistent: false, interval: 1500 }; other = function (path, emitter, stats) { var end, close, type, listener; end = function (err) { if (emitter) { emitter.emit("end", err); close(); } }; close = function () { unwatchFile(path, listener); emitter = null; }; emitter.end = end; emitter.close = close; type = typeByStats(stats); watchFile( path, opts, (listener = function (nstats) { var nType, err; if (!emitter) return; if (!nstats.ctime.getTime() && !nstats.mode) { // It means that file doesn't exist enymore err = new Error("File doesn't exist"); err.code = "ENOENT"; end(err); return; } nType = typeByStats(nstats); if (type !== nType) { err = new Error("File type have changed"); err.code = "DIFFTYPE"; end(err); return; } if ( stats.ctime.valueOf() !== nstats.ctime.valueOf() || (stats.mtime.valueOf() !== nstats.mtime.valueOf() || stats.size !== nstats.size) ) { emitter.emit("change"); } stats = nstats; }) ); }; directory = function (path, emitter) { var end, close, data, compare, listener; end = function (err) { if (emitter) { emitter.emit("end", err); close(); } }; close = function () { if (emitter) { if (listener) unwatchFile(path, listener); emitter = null; } }; compare = function (file, index) { return data[index] === file; }; emitter.end = end; emitter.close = close; readdir(path).done(function (files) { data = files.sort(); watchFile( path, opts, (listener = function (stats) { var err; if (!emitter) return; if (!stats.ctime.getTime() && !stats.mode) { // It means that dir doesn't exist enymore err = new Error("Directory doesn't exist"); err.code = "ENOENT"; end(err); return; } readdir(path).done(function (nuFiles) { if (!emitter) return; if (nuFiles.length !== data.length || !nuFiles.sort().every(compare)) { data = nuFiles; emitter.emit("change"); } }, end); }) ); }, end); }; module.exports = function (path, emitter) { var stats = lstatSync(path); if (!emitter) emitter = ee(); if (stats.isDirectory()) directory(path, emitter); else other(path, emitter, stats); return emitter; }; medikoo-fs2-b93c977/lib/watch.js000066400000000000000000000041371466730653100164340ustar00rootroot00000000000000"use strict"; var promisify = require("deferred").promisify , ee = require("event-emitter") , fs = require("fs") , typeByStats = require("../type-by-stats"); var nextTick = process.nextTick , lstat = promisify(fs.lstat) , watch = fs.watch , opts = { persistent: false }; module.exports = function (path, emitter) { var stats, fileType, listener, watcher, lock, end, clearLock, close; end = function (err) { if (emitter) { emitter.emit("end", err); close(); } }; close = function () { if (emitter) { watcher.close(); emitter = null; } }; clearLock = function () { lock = null; }; listener = function (type) { if (lock) return; if (lock === false) { lock = type === "rename"; return; } lock = type === "rename"; // We do timeout, as there are cases that reinitializing watcher right away // doesn't work as file is not accessible. It gives us false positive that // file is removed (and that is not reported by dir watcher on parent dir) setTimeout(function () { var nwatcher; nextTick(clearLock); watcher.close(); try { nwatcher = watch(path, opts, listener); } catch (e) { end(e); return; } watcher = nwatcher; watcher.on("error", end); if (stats && (lock || stats.isFile())) { lstat(path).done(function (nstats) { var newFileType, err; if (!emitter) return; newFileType = typeByStats(nstats); if (fileType !== newFileType) { err = new Error("File type have changed"); err.code = "DIFFTYPE"; end(err); return; } if ( stats.isDirectory() || (stats.ctime.valueOf() !== nstats.ctime.valueOf() || (stats.mtime.valueOf() !== nstats.mtime.valueOf() || stats.size !== nstats.size)) ) { emitter.emit("change"); } stats = nstats; }, end); } }, 10); }; watcher = watch(path, opts, listener); watcher.on("error", end); if (!emitter) emitter = ee(); emitter.end = end; emitter.close = close; lstat(path)(function (nstats) { stats = nstats; fileType = typeByStats(stats); }, end); return emitter; }; medikoo-fs2-b93c977/lstat.js000066400000000000000000000017001466730653100157000ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , resolve = require("path").resolve , original = require("fs").lstat; var lstat = function (path, options) { var def = deferred(); original(path, function (err, stats) { if (err) { if (options.loose && (err.code === "ENOENT" || err.code === "ENOTDIR")) { def.resolve(null); } else { def.reject(err); } } else { def.resolve(stats); } }); return def.promise; }; lstat.returnsPromise = true; module.exports = function (path/*, callback*/) { var options, cb; path = resolve(String(path)); options = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = Object(options); } return lstat(path, options).cb(cb); }; module.exports.returnsPromise = true; module.exports.lstat = lstat; medikoo-fs2-b93c977/mkdir.js000066400000000000000000000035441466730653100156670ustar00rootroot00000000000000// Internal logic inspired by substack's node-mkdirp: // https://github.com/substack/node-mkdirp/ "use strict"; var isNumber = require("es5-ext/number/is-number") , isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , fs = require("fs") , pathUtils = require("path"); var stat = fs.stat, original = fs.mkdir, dirname = pathUtils.dirname, resolve = pathUtils.resolve; var _mkdir, mkdir; _mkdir = function (path, options, pResolve, reject) { original(path, options.mode, function (err) { var dir; if (!isValue(err)) { pResolve(null); return; } if (err.code === "EEXIST" && options.silent) { pResolve(null); return; } if (!options.intermediate) { reject(err); return; } if (err.code === "ENOENT") { dir = dirname(path); if (dir === path) { reject(err); return; } _mkdir(dir, options, function () { _mkdir(path, options, pResolve, reject); }, reject); } else { stat(path, function (statErr, stats) { if (statErr) { if (statErr.code !== "ENOENT") { reject(err); return; } _mkdir(path, options, pResolve, reject); return; } if (stats.isDirectory()) pResolve(null); else reject(err); }); } }); }; mkdir = function (path, options) { var def = deferred(); _mkdir(path, options, def.resolve, def.reject); return def.promise; }; mkdir.returnsPromise = true; module.exports = exports = function (path/*, mode|options, cb*/) { var options, cb; path = resolve(String(path)); options = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = isNumber(options) ? { mode: options } : Object(options); } return mkdir(path, options).cb(cb); }; exports.returnsPromise = true; exports.mkdir = mkdir; medikoo-fs2-b93c977/package.json000066400000000000000000000042421466730653100165050ustar00rootroot00000000000000{ "name": "fs2", "version": "0.4.0", "description": "fs (file system package) extensions", "author": "Mariusz Nowak (http://www.medikoo.com/)", "keywords": [ "addons", "extensions", "extras", "fs", "filesystem", "mkdir", "readdir", "files", "dirs", "directories", "git" ], "repository": "medikoo/fs2", "dependencies": { "d": "^1.0.1", "deferred": "^0.7.11", "es5-ext": "^0.10.53", "event-emitter": "^0.3.5", "ext": "^1.6.0", "ignore": "^5.1.8", "memoizee": "^0.4.14", "type": "^2.1.0" }, "devDependencies": { "eslint": "^8.2.0", "eslint-config-medikoo": "^4.1.1", "git-list-updated": "^1.2.1", "github-release-from-cc-changelog": "^2.2.0", "husky": "^4.3.0", "lint-staged": "^10.5.1", "prettier-elastic": "^2.1.2", "tad": "^3.0.1" }, "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*.js": [ "eslint" ], "*.{css,html,js,json,md,yaml,yml}": [ "prettier -c" ] }, "eslintConfig": { "extends": "medikoo/node/6", "root": true, "overrides": [ { "files": [ "chmod.js" ], "rules": { "no-bitwise": "off" } }, { "files": [ "empty-dir-sync.js", "rmdir-sync.js" ], "rules": { "no-use-before-define": "off" } } ] }, "prettier": { "printWidth": 100, "tabWidth": 4, "overrides": [ { "files": [ "*.md", "*.yml" ], "options": { "tabWidth": 2 } } ] }, "scripts": { "lint": "eslint --ignore-path=.gitignore .", "lint:updated": "pipe-git-updated --base=main --ext=js -- eslint --ignore-pattern '!*'", "prettier-check": "prettier -c --ignore-path .gitignore \"**/*.{css,html,js,json,md,yaml,yml}\"", "prettier-check:updated": "pipe-git-updated --base=main --ext=css --ext=html --ext=js --ext=json --ext=md --ext=yaml --ext=yml -- prettier -c", "prettify": "prettier --write --ignore-path .gitignore \"**/*.{css,html,js,json,md,yaml,yml}\"", "prettify:updated": "pipe-git-updated ---base=main -ext=css --ext=html --ext=js --ext=json --ext=md --ext=yaml --ext=yml -- prettier --write", "test": "tad" }, "engines": { "node": ">=6" }, "license": "ISC" } medikoo-fs2-b93c977/read-file.js000066400000000000000000000046151466730653100164110ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , isString = require("es5-ext/string/is-string") , deferred = require("deferred") , original = require("fs").readFile , resolve = require("path").resolve , watch = require("./watch").watch , WatchPath = require("./watch-path").WatchPath , readFile; readFile = function (filename, options) { var def, current, promise, watcher, resolveCb, onchange, loose; def = deferred(); loose = options.loose; original( filename, options.encoding, (resolveCb = function (err, data) { if (def.resolved) return; if (err) { if (watcher && !loose) watcher.close(); if (loose) def.resolve(null); else def.reject(err); return; } if (options.watch) current = String(data); def.resolve(data); }) ); promise = def.promise; if (options.watch) { onchange = function () { original(filename, options.encoding, function (err, data) { var dataStr; if (!def.resolved) { resolveCb(err, data); return; } if (!watcher) return; if (err) { watcher.close(); promise.emit("end"); return; } dataStr = String(data); if (dataStr !== current) { current = dataStr; promise.emit("change", data); } }); }; if (loose) { current = null; watcher = new WatchPath(filename); watcher.on("change", function (event) { if (event.type === "remove") { if (isValue(current)) promise.emit("change", (current = null)); } else { onchange(); } }); } else { try { watcher = watch(filename); } catch (e) { return def.reject(e); } watcher.on("change", onchange); watcher.on("end", function () { watcher = null; promise.emit("end"); }); } promise.close = function () { watcher.close(); if (!def.resolved) { def.reject(new Error("Operation aborted: " + filename)); } }; } return promise; }; readFile.returnsPromise = true; module.exports = exports = function (filename) { var options, cb; filename = resolve(String(filename)); options = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = isString(options) ? { encoding: options } : Object(options); } return readFile(filename, options).cb(cb); }; exports.returnsPromise = true; exports.readFile = readFile; medikoo-fs2-b93c977/readdir.js000066400000000000000000000421071466730653100161710ustar00rootroot00000000000000/* eslint max-statements: off, max-lines: off */ "use strict"; var invoke = require("es5-ext/function/invoke") , noop = require("es5-ext/function/noop") , curry = require("es5-ext/function/#/curry") , contains = curry.call(require("es5-ext/array/#/contains")) , diff = require("es5-ext/array/#/diff") , remove = require("es5-ext/array/#/remove") , assign = require("es5-ext/object/assign") , forEach = require("es5-ext/object/for-each") , isCallable = require("es5-ext/object/is-callable") , isCopy = require("es5-ext/object/is-copy") , isValue = require("es5-ext/object/is-value") , toPosInt = require("es5-ext/number/to-pos-integer") , startsWith = require("es5-ext/string/#/starts-with") , deferred = require("deferred") , fs = require("fs") , pathUtils = require("path") , typeByStats = require("./type-by-stats") , watchPath = require("./watch") , isIgnored = require("./is-ignored"); var isArray = Array.isArray , push = Array.prototype.push , promisify = deferred.promisify , resolve = pathUtils.resolve , sep = pathUtils.sep , original = fs.readdir , lstat = fs.lstat , pLstat = promisify(lstat) , getIsIgnored = isIgnored.getIsIgnored , applyGlobalRules = isIgnored.applyGlobalRules , Readdir , readdir , enoentSurpass , eolRe = /(?:\r\n|[\n\r\u2028\u2029])/ , passErrCodes = ["ENOENT", "DIFFTYPE"]; passErrCodes.contains = contains; enoentSurpass = function (err) { return passErrCodes.contains(err.code) ? [] : err; }; // eslint-disable-next-line no-empty-function Readdir = function () {}; Readdir.prototype = { init: function () { var data, result, promise, stream; stream = this.stream; data = this.read(this.path, this.depth); if (!this.depth) { promise = data.files; if (this.stream) { promise.aside(function (files) { if (!files) return; promise.emit("change", { data: files, added: files, removed: [] }); }); } return promise; } this.readers = {}; result = []; assign(this, deferred()); promise = this.promise; data.files.done(null, this.reject); if (this.watch) { data.files.on( "end", function () { delete this.readers; if (!promise.resolved) { this.reject(new Error("Directory was removed")); return; } promise.emit("end", result); }.bind(this) ); promise.close = this.close.bind(this); } (function self(nuData, rootPath, depth) { var getPath, files; this.readers[rootPath] = { files: nuData.files }; if (nuData.dirs && nuData.dirs !== nuData.files) { this.readers[rootPath].dirs = nuData.dirs; } if (rootPath) { getPath = function (path) { return rootPath + path; }; files = nuData.files.aside(function (newFiles) { if (newFiles.length) { newFiles = newFiles.map(getPath); push.apply(result, newFiles); if (promise.resolved || stream) { promise.emit("change", { data: result, removed: [], added: newFiles }); } } return newFiles; }); } else { files = nuData.files.aside(function (newFiles) { if (newFiles && newFiles.length) { push.apply(result, newFiles); if (promise.resolved || stream) { promise.emit("change", { data: result, removed: [], added: newFiles }); } } return newFiles; }); } if (this.watch) { if (rootPath) { nuData.files.on( "end", (nuData.files.onend = function (newFiles) { delete this.readers[rootPath]; if (newFiles.length) { newFiles = newFiles.map(getPath); remove.apply(result, newFiles); if (promise.resolved || stream) { promise.emit("change", { data: result, removed: newFiles, added: [] }); } } }.bind(this)) ); } nuData.files.on("change", function (nextData) { var removed, added; removed = rootPath ? nextData.removed.map(getPath) : nextData.removed; added = rootPath ? nextData.added.map(getPath) : nextData.added; remove.apply(result, removed); push.apply(result, added); if (promise.resolved || stream) { promise.emit("change", { data: result, removed: removed, added: added }); } }); } if (nuData.dirs) { if (this.watch) { nuData.dirs.on( "change", function (nextData) { deferred .map( nextData.added, function (dir) { return self.call( this, this.read(this.path + sep + rootPath + dir, depth - 1), rootPath + dir + sep, depth - 1 ); }, this ) .done(); nextData.removed.forEach( function (dir) { var path = rootPath + dir + sep, reader = this.readers[path]; if (reader) { reader.files.close(); if (reader.dirs) reader.dirs.close(); reader.files.onend(reader.files.value); forEach(this.readers, function (newReader, key) { if (startsWith.call(key, path)) { newReader.files.close(); if (newReader.dirs) newReader.dirs.close(); newReader.files.onend(newReader.files.value); } }); } }.bind(this) ); }.bind(this) ); } return deferred( files(null, enoentSurpass), nuData .dirs(null, enoentSurpass) .map(function (dir) { return self.call( this, this.read(this.path + sep + rootPath + dir, depth - 1), rootPath + dir + sep, depth - 1 ); }, this) ); } return files; } .call(this, data, "", this.depth) .done(this.resolve.bind(this, result), this.reject)); return this.promise; }, close: function () { if (this.readers) { forEach(this.readers, function (data) { data.files.close(); if (data.dirs) data.dirs.close(); }); delete this.readers; } }, read: function (path, getDirs) { var dirPaths, paths, data; paths = this.readdir(path); if (this.type || getDirs) { data = this.filterByType(paths, getDirs); paths = data.files; dirPaths = data.dirs; } else if (this.pattern || this.globalRules) { paths = this.filterByPattern(paths); } if (this.isIgnored) { if (dirPaths && dirPaths !== paths) { dirPaths = this.filterIgnored(dirPaths); paths = this.filterIgnored(paths); } else { paths = this.filterIgnored(paths); if (dirPaths) dirPaths = paths; } } return { files: paths, dirs: dirPaths }; }, filterByType: function (paths, getDirs) { var result = {} , test , rootPath = paths.root , files , dirs , resolveCb , defFiles , defDirs , close , resolved , failed; if (this.type || this.pattern || this.globalRules) { files = []; defFiles = deferred(); result.files = defFiles.promise; result.files.root = rootPath; } else { result.files = paths; } if (getDirs) { if (this.type && isCopy(this.type, { directory: true }) && !this.pattern) { dirs = files; result.dirs = result.files; getDirs = false; } else { dirs = []; defDirs = deferred(); result.dirs = defDirs.promise; result.dirs.root = rootPath; } } resolveCb = function (e) { if (defFiles) { if (e) defFiles.reject(e); else defFiles.resolve(files); } if (defDirs) { if (e) defDirs.reject(e); else defDirs.resolve(dirs); } failed = Boolean(e); resolved = true; }; paths.done( function (newPaths) { if (!newPaths) { files = null; resolveCb(); return; } var waiting = newPaths.length; if (!waiting) { resolveCb(); return; } newPaths.forEach(function (path) { var fullPath = rootPath + sep + path; if ( (!getDirs && this.pattern && !this.pattern.test(fullPath)) || (this.globalRules && applyGlobalRules(fullPath, this.globalRules)) ) { if (!--waiting) resolveCb(); return; } lstat( fullPath, function (err, stat) { var type; if (resolved) return; if (!err) { try { type = typeByStats(stat); } catch (e) { resolveCb(e); return; } if ( files && (!this.type || this.type[type]) && (!this.pattern || !getDirs || this.pattern.test(fullPath)) ) { files.push(path); } if (getDirs && type === "directory") { if (!this.dirFilter || this.dirFilter(fullPath)) { dirs.push(path); } } } else if (err.code !== "ENOENT") { resolveCb(err); return; } if (!--waiting) resolveCb(); }.bind(this) ); }, this); }.bind(this), resolveCb ); if (this.watch) { test = function (path, newFiles, newDirs) { var fullPath = rootPath + sep + path, promise; if ( (!getDirs && this.pattern && !this.pattern.test(fullPath)) || (this.globalRules && applyGlobalRules(fullPath, this.globalRules)) ) { return null; } promise = pLstat(fullPath).aside( function (stat) { var type = typeByStats(stat); if ( newFiles && (!this.type || this.type[type]) && (!this.pattern || !getDirs || this.pattern.test(fullPath)) ) { newFiles.push(path); } if (newDirs && type === "directory") newDirs.push(path); }.bind(this) ); return promise.catch(function (err) { if (err.code !== "ENOENT") throw err; }); }.bind(this); paths.on("change", function (data) { var removed, nFiles, nDirs; if (data.added.length) { nFiles = files && []; nDirs = getDirs && []; } deferred .map(data.added, function (path) { return test(path, nFiles, nDirs); }) .done(function () { if (files) { removed = data.removed.filter(contains, files); if (removed.length || (nFiles && nFiles.length)) { remove.apply(files, removed); if (nFiles) push.apply(files, nFiles); result.files.emit("change", { data: files, removed: removed, added: nFiles || [] }); } } if (getDirs) { removed = data.removed.filter(contains, dirs); if (removed.length || (nDirs && nDirs.length)) { remove.apply(dirs, removed); if (nDirs) push.apply(dirs, nDirs); result.dirs.emit("change", { data: dirs, removed: removed, added: nDirs || [] }); } } }); }); paths.on("end", function (data, err) { if (!resolved) { if (defFiles) defFiles.reject(err); if (defDirs) defDirs.reject(err); return; } if (!failed) { if (files) result.files.emit("end", files, err); if (getDirs) result.dirs.emit("end", dirs, err); } }); close = function () { if (defFiles && !defFiles.resolved) { defFiles.reject(new Error("Readdir operation cancelled")); } if (defDirs && !defDirs.resolved) { defDirs.reject(new Error("Readdir operation cancelled")); } if (paths.close) paths.close(); }; if (defFiles) { result.files.close = close; if (defDirs) result.dirs.close = noop; } else { result.dirs.close = close; } } return result; }, filterByPattern: function (paths) { var promise , result , rootPath = paths.root , pattern = this.pattern , rules = this.globalRules , filter; filter = function (path) { var fullPath = rootPath + sep + path; return ( (!pattern || pattern.test(fullPath)) && (!rules || !applyGlobalRules(fullPath, rules)) ); }; promise = paths(function (data) { return (result = data.filter(filter)); }); promise.root = rootPath; if (this.watch) { paths.on("change", function (data) { var removed, added; removed = data.removed.filter(contains, result); added = data.added.filter(filter); if (removed.length || added.length) { remove.apply(result, removed); push.apply(result, added); promise.emit("change", { data: result, removed: removed, added: added }); } }); paths.on("end", function (data, err) { promise.emit("end", result, err); }); promise.close = function () { paths.close(); }; } return promise; }, filterIgnored: function (paths) { var promise, result, test, rootPath = paths.root, promises, def = deferred(); promise = def.promise; test = function (path, cb) { var status = this.isIgnored(rootPath + sep + path); if (this.watch) { promises[path] = status; status.on("change", function (value) { if (value) { remove.call(result, path); promise.emit("change", { data: result, removed: [path], added: [] }); } else { result.push(path); promise.emit("change", { data: result, removed: [], added: [path] }); } }); } status.aside(cb); }.bind(this); if (this.watch) { promises = {}; paths.on("change", function (data) { var removed, added = [], waiting = data.added.length, onEnd; data.removed.forEach(function (path) { promises[path].close(); delete promises[path]; }); removed = data.removed.filter(contains, result); onEnd = function () { if (removed.length || added.length) { remove.apply(result, removed); push.apply(result, added); promise.emit("change", { data: result, removed: removed, added: added }); } }; if (!waiting) { onEnd(); return; } data.added.forEach(function (path) { test(path, function (lIsIgnored) { if (!lIsIgnored) added.push(path); if (!--waiting) onEnd(); }); }); }); paths.on("end", function (data, err) { if (!promises) return; forEach(promises, invoke("close")); promises = null; if (!def.resolved) { def.reject(err); return; } promise.emit("end", result, err); }); promise.close = function () { if (promises) { if (!def.resolved) def.reject(new Error("Operation aborted")); forEach(promises, invoke("close")); promises = null; paths.close(); } }; } paths.done( function (newPaths) { if (!newPaths) { def.resolve(newPaths); return; } var waiting = newPaths.length; result = []; if (!waiting) { def.resolve(result); return; } newPaths.forEach(function (path) { test(path, function (lIsIgnored) { if (!lIsIgnored) result.push(path); if (!--waiting) def.resolve(result); }); }); }, function (e) { def.reject(e); } ); promise.root = rootPath; return promise; }, readdir: function (path) { var def, promise, watcher, files; def = deferred(); promise = def.promise; promise.root = path; if (this.watch) { try { watcher = watchPath(path); } catch (e) { return def.reject(e); } watcher.on("end", function (err) { if (!def.resolved) def.reject(err); else if (files) promise.emit("end", files, err); }); watcher.on("change", function () { original(path, function (err, data) { var removed, added; if (err) { promise.emit("end", files, err); return; } removed = diff.call(files, data); added = diff.call(data, files); if (removed.length || added.length) { remove.apply(files, removed); push.apply(files, added); promise.emit("change", { data: files, removed: removed, added: added }); } }); }); promise.close = function () { watcher.close(); if (!def.resolved) def.reject(new Error("Readdir action cancelled")); }; } original( path, function (err, data) { if (err) { if (this.loose && this.path === path && err.code === "ENOENT") { def.resolve(null); } else { def.reject(err); } return; } def.resolve((files = data)); }.bind(this) ); return promise; } }; readdir = function (path, options) { var lReaddir, globalRules; lReaddir = new Readdir(); lReaddir.path = path; lReaddir.depth = isNaN(options.depth) ? 0 : toPosInt(options.depth); lReaddir.type = isValue(options.type) ? Object(options.type) : null; lReaddir.loose = Boolean(options.loose); lReaddir.pattern = isValue(options.pattern) ? new RegExp(options.pattern) : null; if (isValue(options.dirFilter)) { if (typeof options.dirFilter === "function") lReaddir.dirFilter = options.dirFilter; else lReaddir.dirFilter = RegExp.prototype.test.bind(new RegExp(options.dirFilter)); } lReaddir.watch = options.watch; lReaddir.stream = Boolean(options.stream); if (options.globalRules) { globalRules = isArray(options.globalRules) ? options.globalRules : String(options.globalRules).split(eolRe); } if (options.ignoreRules) { assign( lReaddir, getIsIgnored( isArray(options.ignoreRules) ? options.ignoreRules : [options.ignoreRules], globalRules, options.watch ) ); } else { lReaddir.globalRules = globalRules; } return lReaddir.init(); }; readdir.returnsPromise = true; module.exports = exports = function (path) { var options, cb; path = resolve(String(path)); options = Object(arguments[1]); cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } return readdir(path, options).cb(cb); }; exports.returnsPromise = true; exports.readdir = readdir; medikoo-fs2-b93c977/readlink.js000066400000000000000000000020771466730653100163520ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , resolve = require("path").resolve , original = require("fs").readlink; var readlink = function (path, options) { var def = deferred(); original(path, options, function (err, stats) { if (err) { if ( options.loose && (err.code === "ENOENT" || err.code === "EINVAL" || err.code === "ENOTDIR" || err.code === "UNKNOWN") ) { def.resolve(null); } else { def.reject(err); } } else { def.resolve(stats); } }); return def.promise; }; readlink.returnsPromise = true; module.exports = function (path/*[, options[, callback]]*/) { var options, cb; path = resolve(String(path)); options = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = Object(options); options = {}; } else { options = Object(options); } return readlink(path, options).cb(cb); }; module.exports.returnsPromise = true; module.exports.readlink = readlink; medikoo-fs2-b93c977/realpath.js000066400000000000000000000016541466730653100163610ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , resolve = require("path").resolve , original = require("fs").realpath; var realpath = function (path, options) { var def = deferred(); original(path, options, function (err, stats) { if (err) { if (options.loose && err.code === "ENOENT") def.resolve(null); else def.reject(err); } else { def.resolve(stats); } }); return def.promise; }; realpath.returnsPromise = true; module.exports = function (path/*, callback*/) { var options, cb; path = resolve(String(path)); options = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = Object(options); } return realpath(path, options).cb(cb); }; module.exports.returnsPromise = true; module.exports.realpath = realpath; medikoo-fs2-b93c977/rename.js000066400000000000000000000031631466730653100160250ustar00rootroot00000000000000"use strict"; const isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , path = require("path") , original = require("fs").rename , mkdir = require("./mkdir") , stat = require("./stat") , copy = require("./copy") , copyDir = require("./copy-dir") , rmdir = require("./rmdir") , unlink = require("./unlink") , { dirname } = path , { resolve } = path; const crossDeviceRename = function (oldPath, newPath) { return stat.then(stats => { if (stats.isDirectory()) { return copyDir(oldPath, newPath).then(() => rmdir(oldPath, { recursive: true, force: true }) ); } return copy(oldPath, newPath).then(() => unlink(oldPath)); }); }; const rename = function (oldPath, newPath) { const def = deferred(); original(oldPath, newPath, err => { if (err) { if (err.code === "EXDEV") { def.resolve(crossDeviceRename(oldPath, newPath)); return; } def.reject(err); } else { def.resolve(); } }); return def.promise; }; rename.returnsPromise = true; module.exports = exports = function (oldPath, newPath, options = {}, cb = null) { if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } oldPath = resolve(String(oldPath)); newPath = resolve(String(newPath)); if (options.intermediate) { return mkdir(dirname(newPath), { intermediate: true })(() => rename(oldPath, newPath)).cb( cb ); } return rename(oldPath, resolve(String(newPath))).cb(cb); }; exports.returnsPromise = true; exports.rename = rename; medikoo-fs2-b93c977/rm.js000066400000000000000000000016031466730653100151710ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , resolve = require("path").resolve , lstat = require("./lstat") , rmdir = require("./rmdir") , unlink = require("./unlink"); var rm = function (path, options) { return lstat(path, options)(function (stats) { if (!stats) return null; // loose option if (stats.isDirectory()) return rmdir(path, options); return unlink(path, options); }); }; rm.returnsPromise = true; module.exports = function (path/*[, options[, callback]]*/) { var options, cb; path = resolve(String(path)); options = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = Object(options); } return rm(path, options).cb(cb); }; module.exports.returnsPromise = true; module.exports.rm = rm; medikoo-fs2-b93c977/rmdir-sync.js000066400000000000000000000017501466730653100166450ustar00rootroot00000000000000"use strict"; const fs = require("fs") , path = require("path") , ensureString = require("type/string/ensure") , isObject = require("type/object/is") , toShortString = require("type/lib/to-short-string"); module.exports = (dirnameInput, options = {}) => { const dirname = path.resolve(ensureString(dirnameInput)); if (!isObject(options)) options = {}; if (!options.recursive) { fs.rmdirSync(dirname); return; } try { emptyDirSync(dirname, options); fs.rmdirSync(dirname); } catch (error) { if (!error.errors) throw error; let errorMessage = `Could not remove ${ toShortString(dirnameInput) } due to:\n- ${ error.errors.slice(0, 5).map(({ code, _filename }) => `${ code } on ${ _filename }`) }`; if (error.errors.length > 5) { errorMessage += `\nand ${ error.errors.length - 5 } other errors`; } throw Object.assign(new Error(errorMessage), { errors: error.errors }); } }; const emptyDirSync = require("./empty-dir-sync"); medikoo-fs2-b93c977/rmdir.js000066400000000000000000000056501466730653100156760ustar00rootroot00000000000000"use strict"; const partial = require("es5-ext/function/#/partial") , isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , fs = require("fs") , pathUtils = require("path") , chmod = require("./chmod") , lstat = require("./lstat") , readdir = require("./readdir") , unlink = require("./unlink"); const original = fs.rmdir, { resolve } = pathUtils, { sep } = pathUtils, empty = {}; const rmcontent = function (path, options) { return readdir(path)( function self(files, repeated) { return deferred.map(files, name => { const filename = path + sep + name; let aborted; return lstat(filename)( stats => { if (aborted || options.aborted) return null; if (options.recursive && stats.isDirectory()) { return rmcontent(filename, options)(null, err2 => { options.aborted = true; throw err2; }); } if (options.force) { return unlink(filename)(null, err2 => { if (err2.code === "ENOENT") return; aborted = true; throw err2; }); } const err = new Error(`ENOTEMPTY rmdir '${ path }'`); err.errno = 53; err.code = "ENOTEMPTY"; err.path = path; options.aborted = true; throw err; }, err => { if (err.code === "ENOENT") return; options.aborted = true; throw err; } ); })(null, err => { if (!options.aborted && !repeated && err.code === "EACCES" && chmod) { return chmod(path, 146)(partial.call(self, files, true)); } throw err; }); }, err => { if (err.code === "ENOENT") return; throw err; } )( () => { if (options.aborted) return null; return rmdir(path, empty)(null, err => { if (options.aborted) return null; if (err.code === "ENOTEMPTY") { // Race condition (new files were added to the directory in a meantime) return rmcontent(path, options); } if (err.code === "ENOENT") return null; throw err; }); }, err => { if (err.code === "ENOENT") return; throw err; } ); }; const rmdir = function (path, options) { const def = deferred(); original(path, err => { if (err) { if (err.code === "ENOTEMPTY") { if (options.recursive || options.force) { def.resolve(rmcontent(path, options)); return; } } else if (err.code === "ENOENT") { if (options.loose) { def.resolve(null); return; } } def.reject(err); return; } def.resolve(null); }); return def.promise; }; rmdir.returnsPromise = true; module.exports = exports = function (path, options = {}, cb = null) { path = resolve(String(path)); if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = Object(options); } return rmdir(path, options).cb(cb); }; exports.returnsPromise = true; exports.rmdir = rmdir; medikoo-fs2-b93c977/stat.js000066400000000000000000000016131466730653100155270ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , resolve = require("path").resolve , original = require("fs").stat; var stat = function (path, options) { var def = deferred(); original(path, function (err, stats) { if (err) { if (options.loose && err.code === "ENOENT") def.resolve(null); else def.reject(err); } else { def.resolve(stats); } }); return def.promise; }; stat.returnsPromise = true; module.exports = function (path/*, callback*/) { var options, cb; path = resolve(String(path)); options = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = Object(options); } return stat(path, options).cb(cb); }; module.exports.returnsPromise = true; module.exports.stat = stat; medikoo-fs2-b93c977/symlink.js000066400000000000000000000030341466730653100162410ustar00rootroot00000000000000"use strict"; const isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , isString = require("es5-ext/string/is-string") , deferred = require("deferred") , path = require("path") , original = require("fs").symlink , mkdir = require("./mkdir") , isSymlink = require("./is-symlink") , unlink = require("./unlink"); const symlink = function (src, dest, options) { const def = deferred(); original(src, dest, options.type, err => { if (err) { def.reject(err); return; } def.resolve(true); }); return def.promise.catch(error => { if (!options.loose && !options.force) throw error; if (error.code === "EEXIST") { return isSymlink(dest, { linkPath: src })(result => { if (result) return Promise.resolve(false); if (!options.force) throw error; return unlink(dest).then(() => symlink(src, dest, options), () => { throw error; }); }); } throw error; }); }; symlink.returnsPromise = true; module.exports = exports = function (src, dest, options = {}, cb = null) { src = String(src); dest = path.resolve(String(dest)); if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = isString(options) ? { type: options } : Object(options); } if (options.intermediate) { return mkdir(path.dirname(dest), { intermediate: true })(() => symlink(src, dest, options) ).cb(cb); } return symlink(src, dest, options).cb(cb); }; exports.returnsPromise = true; exports.symlink = symlink; medikoo-fs2-b93c977/test/000077500000000000000000000000001466730653100151745ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/000077500000000000000000000000001466730653100176565ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/chmod/000077500000000000000000000000001466730653100207505ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/chmod/test000066400000000000000000000000001466730653100216400ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/copy-dir/000077500000000000000000000000001466730653100214045ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/copy-dir/some-dir/000077500000000000000000000000001466730653100231235ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/copy-dir/some-dir/sample1.js000066400000000000000000000000441466730653100250210ustar00rootroot00000000000000"use strict"; module.exports = {}; medikoo-fs2-b93c977/test/__playground/copy-dir/some-dir/sample3.js000066400000000000000000000000441466730653100250230ustar00rootroot00000000000000"use strict"; module.exports = {}; medikoo-fs2-b93c977/test/__playground/copy-dir/some-dir/some-dir2/000077500000000000000000000000001466730653100247245ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/copy-dir/some-dir/some-dir2/sample1.js000066400000000000000000000000441466730653100266220ustar00rootroot00000000000000"use strict"; module.exports = {}; medikoo-fs2-b93c977/test/__playground/copy/000077500000000000000000000000001466730653100206305ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/copy/sample.js000066400000000000000000000000441466730653100224450ustar00rootroot00000000000000"use strict"; module.exports = {}; medikoo-fs2-b93c977/test/__playground/is-ignored/000077500000000000000000000000001466730653100217165ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/is-ignored/x000066400000000000000000000000001466730653100220760ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/is-symlink/000077500000000000000000000000001466730653100217555ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/is-symlink/from000066400000000000000000000000001466730653100226310ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/lchmod/000077500000000000000000000000001466730653100211245ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/lchmod/test000066400000000000000000000000001466730653100220140ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/lib/000077500000000000000000000000001466730653100204245ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/lib/find-root/000077500000000000000000000000001466730653100223255ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/lib/find-root/x000066400000000000000000000000001466730653100225050ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/lib/get-conf-file-map/000077500000000000000000000000001466730653100236165ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/lib/get-conf-file-map/x000066400000000000000000000000001466730653100237760ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/lib/ignore-modes/000077500000000000000000000000001466730653100230145ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/lib/ignore-modes/git/000077500000000000000000000000001466730653100235775ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/lib/ignore-modes/git/x000066400000000000000000000000001466730653100237570ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/lib/watch-alt/000077500000000000000000000000001466730653100223105ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/lib/watch-alt/x000066400000000000000000000000001466730653100224700ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/lib/watch/000077500000000000000000000000001466730653100215325ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/lib/watch/x000066400000000000000000000000001466730653100217120ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/mkdir/000077500000000000000000000000001466730653100207645ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/mkdir/one/000077500000000000000000000000001466730653100215455ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/mkdir/one/x000066400000000000000000000000001466730653100217250ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/read-file/000077500000000000000000000000001466730653100215065ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/read-file/test000066400000000000000000000000071466730653100224050ustar00rootroot00000000000000raz dwamedikoo-fs2-b93c977/test/__playground/readdir/000077500000000000000000000000001466730653100212705ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readdir/done/000077500000000000000000000000001466730653100222155ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readdir/done/done/000077500000000000000000000000001466730653100231425ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readdir/done/done/dthree/000077500000000000000000000000001466730653100244155ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readdir/done/done/dthree/dthree/000077500000000000000000000000001466730653100256705ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readdir/done/done/dthree/dthree/foo000066400000000000000000000000021466730653100263660ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/done/done/dthree/dtwo/000077500000000000000000000000001466730653100253725ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readdir/done/done/dthree/dtwo/foo000066400000000000000000000000021466730653100260700ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/done/done/dthree/one000066400000000000000000000000011466730653100251100ustar00rootroot00000000000000xmedikoo-fs2-b93c977/test/__playground/readdir/done/done/dthree/three000066400000000000000000000000021466730653100254370ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/done/done/dthree/two000066400000000000000000000000021466730653100251410ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/done/done/dtwo/000077500000000000000000000000001466730653100241175ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readdir/done/done/dtwo/dtwo/000077500000000000000000000000001466730653100250745ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readdir/done/done/dtwo/dtwo/foo000066400000000000000000000000021466730653100255720ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/done/done/dtwo/one000066400000000000000000000000011466730653100246120ustar00rootroot00000000000000xmedikoo-fs2-b93c977/test/__playground/readdir/done/done/dtwo/three000066400000000000000000000000021466730653100251410ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/done/done/dtwo/two000066400000000000000000000000021466730653100246430ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/done/done/one000066400000000000000000000000011466730653100236350ustar00rootroot00000000000000xmedikoo-fs2-b93c977/test/__playground/readdir/done/done/three000066400000000000000000000000021466730653100241640ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/done/done/two000066400000000000000000000000021466730653100236660ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/done/dtwo/000077500000000000000000000000001466730653100231725ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readdir/done/dtwo/foo000066400000000000000000000000031466730653100236710ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/done/one000066400000000000000000000000011466730653100227100ustar00rootroot00000000000000xmedikoo-fs2-b93c977/test/__playground/readdir/done/three000066400000000000000000000000021466730653100232370ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/done/two000066400000000000000000000000021466730653100227410ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/dthree/000077500000000000000000000000001466730653100225435ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readdir/dthree/dthree/000077500000000000000000000000001466730653100240165ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readdir/dthree/dthree/done/000077500000000000000000000000001466730653100247435ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readdir/dthree/dthree/done/dthree/000077500000000000000000000000001466730653100262165ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readdir/dthree/dthree/done/dthree/foo000066400000000000000000000000021466730653100267140ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/dthree/dthree/done/one000066400000000000000000000000011466730653100254360ustar00rootroot00000000000000xmedikoo-fs2-b93c977/test/__playground/readdir/dthree/dthree/done/three000066400000000000000000000000021466730653100257650ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/dthree/dthree/done/two000066400000000000000000000000021466730653100254670ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/dthree/dthree/one000066400000000000000000000000011466730653100245110ustar00rootroot00000000000000xmedikoo-fs2-b93c977/test/__playground/readdir/dthree/dthree/three000066400000000000000000000000021466730653100250400ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/dthree/dthree/two000066400000000000000000000000021466730653100245420ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/dthree/dtwo/000077500000000000000000000000001466730653100235205ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readdir/dthree/dtwo/foo000066400000000000000000000000021466730653100242160ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/dthree/one000066400000000000000000000000011466730653100232360ustar00rootroot00000000000000xmedikoo-fs2-b93c977/test/__playground/readdir/dthree/three000066400000000000000000000000021466730653100235650ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/dthree/two000066400000000000000000000000021466730653100232670ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/dtwo/000077500000000000000000000000001466730653100222455ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readdir/dtwo/one000066400000000000000000000000011466730653100227400ustar00rootroot00000000000000xmedikoo-fs2-b93c977/test/__playground/readdir/dtwo/three000066400000000000000000000000021466730653100232670ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/dtwo/two000066400000000000000000000000021466730653100227710ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/one000066400000000000000000000000011466730653100217630ustar00rootroot00000000000000xmedikoo-fs2-b93c977/test/__playground/readdir/three000066400000000000000000000000021466730653100223120ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readdir/two000066400000000000000000000000021466730653100220140ustar00rootroot00000000000000x medikoo-fs2-b93c977/test/__playground/readlink/000077500000000000000000000000001466730653100214475ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readlink/from000066400000000000000000000000001466730653100223230ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/readlink/non-symlink000066400000000000000000000000001466730653100236360ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/rename/000077500000000000000000000000001466730653100211255ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/rename/.gitignore000066400000000000000000000000171466730653100231130ustar00rootroot00000000000000* !/.gitignore medikoo-fs2-b93c977/test/__playground/symlink/000077500000000000000000000000001466730653100213445ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/symlink/from000066400000000000000000000000001466730653100222200ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/watch-path/000077500000000000000000000000001466730653100217165ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/watch-path/test000066400000000000000000000000001466730653100226060ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/watch/000077500000000000000000000000001466730653100207645ustar00rootroot00000000000000medikoo-fs2-b93c977/test/__playground/watch/x000066400000000000000000000000001466730653100211440ustar00rootroot00000000000000medikoo-fs2-b93c977/test/access.js000066400000000000000000000004721466730653100167760ustar00rootroot00000000000000"use strict"; var fs = require("fs"); var execMode = (fs.constants || fs).X_OK; module.exports = function (t, a, d) { t(__filename)(function (result) { a(result, undefined, "Success"); return t(__filename, execMode)(a.never, function (err) { a(err.code, "EACCES", "Error"); }); }, a.never).done(d, d); }; medikoo-fs2-b93c977/test/append-file.js000066400000000000000000000024231466730653100177170ustar00rootroot00000000000000"use strict"; var fs = require("fs") , resolve = require("path").resolve , rmdir = require("../rmdir") , readFile = fs.readFile , unlink = fs.unlink , pgPath = resolve(__dirname, "./__playground") , testFilePath = resolve(pgPath, "append-file-test") , intermediateDirPath = resolve(pgPath, "_append-file") , intermediatePath = resolve(intermediateDirPath, "intermediate/test"); module.exports = { Append: function (t, a, d) { t(testFilePath, "raz", function (err) { a(err, null, "#1"); t(testFilePath, "dwa", function (err2) { a(err2, null, "#2"); t(testFilePath, "trzy", function (err3) { a(err3, null, "#3"); readFile(testFilePath, function (err4, content) { a(String(content), "razdwatrzy", "Result"); unlink(testFilePath, d); }); }); }); }); }, Intermediate: function (t, a, d) { t(intermediatePath, "elo", { intermediate: true }, function (err) { if (err) { d(err); return; } fs.readFile(intermediatePath, function (err2, content) { if (err2) { d(err2); return; } a(String(content), "elo", "Content"); rmdir(intermediateDirPath, { recursive: true, force: true }, d); }); }); } }; medikoo-fs2-b93c977/test/chmod.js000066400000000000000000000010201466730653100166150ustar00rootroot00000000000000"use strict"; var lstat = require("../lstat") , testFile = require("path").resolve(__dirname, "__playground/chmod/test"); module.exports = function (t, a, d) { if (process.platform === "win32") { a(t, null); d(); return; } lstat(testFile)(function (stats) { var org = stats.mode; return t(testFile, 511)(function () { return lstat(testFile)(function (stats2) { // eslint-disable-next-line no-bitwise a(stats2.mode & 511, 511); return t(testFile, org); }); }); }, a.never).done(d, d); }; medikoo-fs2-b93c977/test/copy-dir.js000066400000000000000000000023531466730653100172630ustar00rootroot00000000000000"use strict"; var deferred = require("deferred") , path = require("path") , readdir = require("../readdir") , readlink = require("../readlink") , symlink = require("../symlink") , rm = require("../rm"); var relative = path.relative , resolve = path.resolve , pg = path.resolve(__dirname, "./__playground/copy-dir"); module.exports = function (t, a, d) { var src = resolve(pg, "some-dir") , srcFile1 = resolve(src, "sample1") , srcSymlink1 = resolve(src, "symlink1") , srcSymlink2 = resolve(src, "symlink2") , dst = resolve(pg, "dir-copy"); symlink(srcFile1, srcSymlink1)(function () { return symlink(__dirname, srcSymlink2); })( function () { return t(src, dst); } )(function () { return deferred(readdir(src, { depth: Infinity }), readdir(dst, { depth: Infinity })); }) .spread(function (srcFiles, dstFiles) { a.deep(srcFiles, dstFiles); return readlink(resolve(dst, "symlink1")); })(function (symLinkPath) { a(symLinkPath, relative(dst, resolve(dst, "sample1"))); return readlink(resolve(dst, "symlink2")); })(function (symLinkPath) { a(symLinkPath, relative(dst, __dirname)); return rm(dst, { recursive: true, force: true })(rm(srcSymlink1))(rm(srcSymlink2)); }) .done(d, d); }; medikoo-fs2-b93c977/test/copy.js000066400000000000000000000036241466730653100165110ustar00rootroot00000000000000"use strict"; var path = require("path") , fs = require("fs") , pg = path.resolve(__dirname, "./__playground/copy"); module.exports = { "Success": function (t, a, d) { var src = pg + "/sample.js", dst = pg + "/sample.copy.js"; t(src, dst, function (err) { if (err) { d(err); return; } fs.readFile(src, "utf8", function (err2, srcContent) { if (err2) { d(err2); return; } fs.readFile(dst, "utf8", function (err3, dstContent) { if (err3) { d(err3); return; } a(dstContent, srcContent, "Content"); fs.stat(src, function (err4, srcStats) { if (err4) { d(err4); return; } fs.stat(dst, function (err5, dstStats) { if (err5) { d(err5); return; } a(dstStats.mode, srcStats.mode); fs.unlink(dst, d); }); }); }); }); }); }, "Deep": function (t, a, d) { var src = pg + "/sample.js", dst = pg + "/deep/path/sample.copy.js"; return t(src, dst, { intermediate: true }).done(function () { fs.readFile(src, "utf8", function (err, srcContent) { if (err) { d(err); return; } fs.readFile(dst, "utf8", function (err2, dstContent) { if (err2) { d(err2); return; } a(dstContent, srcContent, "Content"); fs.unlink(dst, d); }); }); }, d); }, "Wrong path": function (t, a, d) { t(pg + "/sample.js", pg + "/:;\\//wrong-filename").done(a.never, function (e) { a(e.code, "ENOENT", "Path error"); d(); }); }, "Loose": function (t, a, d) { t(pg + "/:;\\//wrong-filename", pg + "/sample-test.js", { loose: true }).done(function ( result ) { a(result, false); d(); }, d); }, "Loose with mode": function (t, a, d) { t(pg + "/:;\\//wrong-filename", pg + "/sample-test2.js", { loose: true, mode: 33188 }).done( function (result) { a(result, false); d(); }, d ); } }; medikoo-fs2-b93c977/test/descriptors-handler.js000066400000000000000000000010071466730653100215040ustar00rootroot00000000000000"use strict"; var fs = require("fs"); module.exports = function (t, a, d) { var done = 0; t(); fs.closeSync(fs.openSync(__filename, "r")); fs.open(__filename, "r", function (err, fd) { if (err) { d(err); return; } a(typeof fd, "number", "Open"); fs.close(fd, function (err2) { if (err2 || done++) { d(err2); } }); }); fs.readdir(__dirname, function (err, result) { if (err) { d(err); return; } a(Array.isArray(result), true, "Readdir"); if (done++) { d(); } }); }; medikoo-fs2-b93c977/test/empty-dir-sync.js000066400000000000000000000016521466730653100204220ustar00rootroot00000000000000"use strict"; const path = require("path") , readdir = require("../readdir") , mkdir = require("../mkdir") , writeFile = require("../write-file") , pg = path.resolve(__dirname, "__playground") , rootPath = path.resolve(pg, "rmdir-sync") , nested = path.resolve(rootPath, "one/two/three/dir") , nested2 = path.resolve(rootPath, "one/four/five/six"); module.exports = function (t, a) { return Promise.all([ mkdir(nested, { intermediate: true }), mkdir(nested2, { intermediate: true }) ]) .then(() => writeFile(path.resolve(nested, "../foo"), "bar")) .then(() => { try { t(rootPath); throw new Error("Unexpected"); } catch (error) { if (!error.message.includes("ENOTEMPTY")) throw error; a(error.message.includes("ENOTEMPTY"), true); } t(rootPath, { recursive: true }); return readdir(rootPath).then(content => { a.deep(content, []); }); }); }; medikoo-fs2-b93c977/test/has-access.js000066400000000000000000000007611466730653100175500ustar00rootroot00000000000000"use strict"; var resolve = require("path").resolve , fs = require("fs"); var execMode = (fs.constants || fs).X_OK; module.exports = function (t, a, d) { t(__filename) .then(function (result) { a(result, true, "Success"); return t(__filename, { mode: execMode }); }, a.never) .then(function (result) { a(result, false, "No access"); return t(resolve(__filename, "n-a"), { loose: true }); }) .then(function (result) { a(result, null, "Loose"); }) .done(d, d); }; medikoo-fs2-b93c977/test/is-directory.js000066400000000000000000000005451466730653100201530ustar00rootroot00000000000000"use strict"; const { resolve } = require("path"); module.exports = function (t, a, d) { t(__filename)(result => { a(result, false, "Existing non directory"); return t(__dirname); })(result => { a(result, true, "Existing directory"); return t(resolve(__filename, "foo")); })(result => { a(result, null, "Existing directory"); }).done(d, d); }; medikoo-fs2-b93c977/test/is-file.js000066400000000000000000000005251466730653100170640ustar00rootroot00000000000000"use strict"; const { resolve } = require("path"); module.exports = function (t, a, d) { t(__filename)(result => { a(result, true, "Existing file"); return t(__dirname); })(result => { a(result, false, "Existing non file"); return t(resolve(__filename, "foo")); })(result => { a(result, null, "Not existing"); }).done(d, d); }; medikoo-fs2-b93c977/test/is-ignored.js000066400000000000000000000151731466730653100176010ustar00rootroot00000000000000/* eslint max-lines: off */ "use strict"; const fs = require("fs") , { resolve } = require("path") , noop = require("es5-ext/function/noop") , deferred = require("deferred") , { delay } = deferred , { promisify } = deferred , mkdir = promisify(fs.mkdir) , writeFile = promisify(fs.writeFile) , unlink = promisify(fs.unlink) , rmdir = promisify(fs.rmdir) , modes = require("../lib/ignore-modes") , pgPath = resolve(__dirname, "./__playground/is-ignored"); module.exports = function (t, a, d) { let invoked = null, testIsRoot, watcher; const DELAY = 100 , gitRoot = resolve(pgPath, ".git") , rootFile = resolve(pgPath, ".gitignore") , onePath = resolve(pgPath, "one") , oneFile = resolve(onePath, ".gitignore") , twoPath = resolve(onePath, "two") , twoFile = resolve(twoPath, ".gitignore") , twoOtherFile = resolve(twoPath, ".ignore") , twoFooPath = resolve(twoPath, "foo"); modes.test = { filename: ".ignore", isRoot: (testIsRoot = function (path) { const promise = deferred(path === onePath); promise.close = noop; return promise; }), isRootWatcher: testIsRoot }; // Make .git dir deferred( mkdir(gitRoot), mkdir(onePath)(() => mkdir(twoPath)) )( delay(() => { t( "git", resolve(gitRoot, "foo/bar") )(value => { a(value, true, "Ignore gitrepo file"); }).done(); watcher = t("git", twoFooPath, { watch: true }); watcher.on("change", arg => { a(invoked, null, "Invoked once"); invoked = arg; }); watcher.done(); return t("git", twoFooPath); }, DELAY) )( delay(value => { a(value, false, "#1"); // Write root .gitignore with "foo" return writeFile(rootFile, "foo"); }, DELAY) )( delay(() => { a(invoked, true, "#2 event"); invoked = null; return t("git", twoFooPath); }, DELAY) )(value => { a(value, true, "#2"); // Write root/one .gitignore with "/two/foo" return writeFile(oneFile, "/two/foo"); })( delay(() => { a(invoked, null, "#3 event"); return t("git", twoFooPath); }, DELAY) )(value => { a(value, true, "#3"); // Write root/one/two .gitignore with "!foo" return writeFile(twoFile, "!foo"); })( delay(() => { a(invoked, false, "#4 event"); invoked = null; return t("git", twoFooPath); }, DELAY) )(value => { a(value, false, "#4"); // Remove root .gitignore // Remove root/one .gitignore return deferred(unlink(rootFile), unlink(oneFile)); })( delay(() => { a(invoked, null, "#5 event"); return t("git", twoFooPath); }, DELAY) )(value => { a(value, false, "#5"); // Remove root/one/two .gitignore return unlink(twoFile); })( delay(() => { a(invoked, null, "#6 event"); invoked = null; return t("git", twoFooPath); }, DELAY) )(value => { a(value, false, "#6"); // Write root/one .gitignore with "/two/foo\n!/two/foo" return writeFile(oneFile, "/two/foo\n!/two/foo"); })( delay(() => { a(invoked, null, "#7 event"); invoked = null; return t("git", twoFooPath); }, DELAY) )(value => { a(value, false, "#7"); // Write root .gitignore with "two" return writeFile(rootFile, "two"); })( delay(() => { a(invoked, null, "#8 event"); return t("git", twoFooPath); }, DELAY) )(value => { a(value, false, "#8"); // Remove root .gitignore return unlink(rootFile); })( delay(() => { a(invoked, null, "#9 event"); return t("git", twoFooPath); }, DELAY) )(value => { a(value, false, "#9"); // Write root .gitignore with "/one" return writeFile(rootFile, "/one"); })( delay(() => { a(invoked, true, "#10 event"); invoked = null; return t("git", twoFooPath); }, DELAY) )(value => { a(value, true, "#10"); watcher.close(); // Write root .gitignore with "one\n!one/two/foo" // Remove root/one .gitignore return deferred(writeFile(rootFile, "one\n!one/two/foo"), unlink(oneFile)); })( delay(() => { a(invoked, null, "#11 event"); invoked = null; return t("git", twoFooPath); }, DELAY) )(value => { a(value, true, "#11"); // Remove root .gitignore return unlink(rootFile); })( delay(() => { invoked = null; watcher = t(["git", "test"], twoFooPath, { watch: true }); watcher.on("change", arg => { a(invoked, null, "Invoked once"); invoked = arg; }); watcher.done(); return t("git", twoFooPath); }, DELAY) )(value => { a(value, false, "Both #1"); // Write root .gitignore with "foo" return writeFile(rootFile, "foo"); })( delay(() => { a(invoked, true, "Both #2"); invoked = null; return t(["git", "test"], twoFooPath); }, DELAY * 2) )(value => { a(value, true, "Both #2"); return writeFile(twoOtherFile, "!foo"); })( delay(() => { a(invoked, false, "Both #3"); invoked = null; return t(["git", "test"], twoFooPath); }, DELAY) )(value => { a(value, false, "Both #3"); return writeFile(rootFile, "one\n"); })( delay(() => { a(invoked, true, "Both #4"); invoked = null; return t(["git", "test"], twoFooPath); }, DELAY) )(value => { a(value, true, "Both #4"); return unlink(rootFile); })( delay(() => { a(invoked, false, "Both #5"); invoked = null; return t(["git", "test"], twoFooPath); }, DELAY) )(value => { a(value, false, "Both #5"); return writeFile(twoOtherFile, "foo"); })( delay(() => { a(invoked, true, "Both #6"); invoked = null; return t(["git", "test"], twoFooPath); }, DELAY) )(value => { a(value, true, "Both #6"); return writeFile(twoFile, "!foo"); })( delay(() => { a(invoked, null, "Both #7"); invoked = null; return t(["git", "test"], twoFooPath); }, DELAY) )(value => { a(value, true, "Both #7"); return writeFile(twoOtherFile, "!foo"); })( delay(() => { a(invoked, false, "Both #8"); invoked = null; return t(["git", "test"], twoFooPath); }, DELAY) )(value => { a(value, false, "Both #8"); return writeFile(twoFile, "foo"); })( delay(() => { a(invoked, null, "Both #9"); invoked = null; return t(["git", "test"], twoFooPath); }, DELAY) )(value => { a(value, false, "Both #9"); watcher.close(); })(delay(() => deferred(unlink(twoFile), unlink(twoOtherFile)), DELAY))( delay(() => { t(null, twoFooPath, { globalRules: "foo" })(value => { a(value, true, "Global: Direct"); }); t(null, twoFooPath, { globalRules: ["one"] })(value => { a(value, true, "Global: Upper"); }); t(null, twoFooPath, { globalRules: ["bar"] })(value => { a(value, false, "Global: Not matching"); }); delete modes.test; return deferred(rmdir(gitRoot), rmdir(twoPath)(() => rmdir(onePath)))(false); }, DELAY) ).done(d, d); }; medikoo-fs2-b93c977/test/is-symlink.js000066400000000000000000000023361466730653100176350ustar00rootroot00000000000000"use strict"; const { resolve } = require("path") , symlink = require("../symlink") , unlink = require("../unlink"); const rootPath = resolve(__dirname, "./__playground/is-symlink") , targetFile = resolve(rootPath, "from") , nonSymlink = resolve(rootPath, "non-symlink") , symlink1 = resolve(rootPath, "sym1") , symlink2 = resolve(rootPath, "sym2"); module.exports = function (t, a, d) { symlink("from", symlink1) .then(() => symlink("sym1", symlink2)) .then(() => t(symlink2)) .then(result => { a(result, true); return t(symlink2, { linkPath: "sym1" }); }) .then(result => { a(result, true); return t(symlink2, { linkPath: targetFile }); }) .then(result => { a(result, false); return t(symlink2, { linkPath: symlink1 }); }) .then(result => { a(result, true); return t(symlink2, { linkPath: targetFile, recursive: true }); }) .then(result => { a(result, true); return t(targetFile); }) .then(result => { a(result, false); return t(`${ targetFile }/foo`); }) .then(result => { a(result, null); return unlink(symlink1)(unlink(symlink2)); }) .then(() => t(nonSymlink, { loose: true }))(result => { a(result, null); }) .done(d, d); }; medikoo-fs2-b93c977/test/lchmod.js000066400000000000000000000010121466730653100167720ustar00rootroot00000000000000"use strict"; var lstat = require("../lstat") , testFile = require("path").resolve(__dirname, "__playground/lchmod/test"); module.exports = function (t, a, d) { if (!require("fs").lchmod) { a(t, null); d(); return; } lstat(testFile)(function (stats) { var org = stats.mode; return t(testFile, 511)(function () { return lstat(testFile)(function (stats2) { // eslint-disable-next-line no-bitwise a(stats2.mode & 511, 511); return t(testFile, org); }); }); }, a.never).done(d, d); }; medikoo-fs2-b93c977/test/lib/000077500000000000000000000000001466730653100157425ustar00rootroot00000000000000medikoo-fs2-b93c977/test/lib/buffer-from.js000066400000000000000000000001321466730653100205060ustar00rootroot00000000000000"use strict"; module.exports = function (t, a) { a(Buffer.isBuffer(t("data")), true); }; medikoo-fs2-b93c977/test/lib/find-root.js000066400000000000000000000047111466730653100202040ustar00rootroot00000000000000"use strict"; var fs = require("fs") , deferred = require("deferred") , resolve = require("path").resolve , promisify = deferred.promisify , delay = deferred.delay , mkdir = promisify(fs.mkdir) , rmdir = promisify(fs.rmdir) , gitMode = require("../../lib/ignore-modes/git") , rootPath = resolve(__dirname, "../__playground/lib/find-root"); module.exports = function (t, a, d) { var gitRoot = resolve(rootPath, ".git") , onePath = resolve(rootPath, "one") , gitOnePath = resolve(onePath, ".git") , twoPath = resolve(onePath, "two") , gitTwoPath = resolve(twoPath, ".git") , filePath = resolve(twoPath, "file.xxx"); var DELAY = 100, watcher, events = []; // Create /.git mkdir(gitRoot)(function () { // Create /one return mkdir(onePath); })(function () { // Create /one/.git return mkdir(gitOnePath); })(function () { watcher = t(gitMode.isRootWatcher, filePath, { watch: true }); watcher.on("change", function (path) { events.push(path); }); return watcher; })(function (path) { a(path, onePath, "#1"); })( delay(function () { a(String(events), "", "#1: Event"); events = []; // Create /one/two return mkdir(twoPath); }, DELAY) )( delay(function () { // Create /one/two/.git return mkdir(gitTwoPath); }, DELAY) )( delay(function () { a(String(events), twoPath, "#2: Event"); events = []; return t(gitMode.isRoot, filePath); }, DELAY) )(function (path) { a(path, twoPath, "#2"); // Remove /one/.git return rmdir(gitOnePath); })( delay(function () { // Remove /one/two/.git return rmdir(gitTwoPath); }, DELAY) )( delay(function () { a(String(events), rootPath, "#3: Event"); events = []; return t(gitMode.isRoot, filePath); }, DELAY) )(function (path) { a(path, rootPath, "#3"); // Create /one/two/.git return mkdir(gitTwoPath); })( delay(function () { a(String(events), twoPath, "#4: Event"); events = []; return t(gitMode.isRoot, filePath); }, DELAY) )(function (path) { a(path, twoPath, "#4"); // Remove /one/two/.git return rmdir(gitTwoPath); })(function () { // Remove /one/two return rmdir(twoPath); })(function () { // Remove /one return rmdir(onePath); })( delay(function () { a(String(events), rootPath, "#5: Event"); events = []; return t(gitMode.isRoot, filePath); }, DELAY) )(function (path) { a(path, rootPath, "#5"); watcher.close(); return rmdir(gitRoot); }).done(d, d); }; medikoo-fs2-b93c977/test/lib/get-conf-file-map.js000066400000000000000000000076571466730653100215110ustar00rootroot00000000000000"use strict"; var fs = require("fs") , resolve = require("path").resolve , omap = require("es5-ext/object/map") , deferred = require("deferred") , delay = deferred.delay , promisify = deferred.promisify , mkdir = promisify(fs.mkdir) , writeFile = promisify(fs.writeFile) , unlink = promisify(fs.unlink) , rmdir = promisify(fs.rmdir) , mode = require("../../lib/ignore-modes/git") , pgPath = resolve(__dirname, "../__playground/lib/get-conf-file-map"); module.exports = function (t, a, d) { var data , invoked = false , DELAY = 100 , gitRoot = resolve(pgPath, ".git") , rootFile = resolve(pgPath, ".gitignore") , onePath = resolve(pgPath, "one") , oneFile = resolve(onePath, ".gitignore") , twoPath = resolve(onePath, "two") , twoFile = resolve(twoPath, ".gitignore") , gitTwo = resolve(twoPath, ".git") , watcher; deferred(mkdir(gitRoot), mkdir(onePath)(function () { return mkdir(twoPath); }))( delay(function () { watcher = t(twoPath, mode, true); watcher.on("change", function (arg) { a(invoked, false, "Invoked once"); invoked = arg; }); return watcher; }, DELAY) )( delay(function (value) { var map = {}; data = value; a(data.root, pgPath, "#1 Root"); a.deep(omap(data.map, String), map, "#1 Data"); return writeFile(oneFile, "foo\n!bar"); }, DELAY) )( delay(function () { var map = {}; map[onePath] = "foo\n!bar"; a(invoked, data, "#2 invoked"); invoked = false; a(data.root, pgPath, "#2 Root"); a.deep(omap(data.map, String), map, "#2 Data"); return writeFile(twoFile, "!raz\ndwa\n"); }, DELAY) )( delay(function () { var map = {}; map[onePath] = "foo\n!bar"; map[twoPath] = "!raz\ndwa\n"; a(invoked, data, "#3 invoked"); invoked = false; a(data.root, pgPath, "#3 Root"); a.deep(omap(data.map, String), map, "#3 Data"); return t(twoPath, mode); }, DELAY) )(function (lData) { var map = {}; map[onePath] = "foo\n!bar"; map[twoPath] = "!raz\ndwa\n"; a(lData.root, pgPath, "#3 Root"); a.deep(omap(lData.map, String), map, "#3 Data"); return writeFile(rootFile, "one\n\ntwo\n!three\n"); })( delay(function () { var map = {}; map[pgPath] = "one\n\ntwo\n!three\n"; map[onePath] = "foo\n!bar"; map[twoPath] = "!raz\ndwa\n"; a(invoked, data, "#4 invoked"); invoked = false; a(data.root, pgPath, "#4 Root"); a.deep(omap(data.map, String), map, "#4 Data"); return mkdir(gitTwo); }, DELAY) )( delay(function () { var map = {}; map[twoPath] = "!raz\ndwa\n"; a(invoked, data, "#5 invoked"); invoked = false; a(data.root, twoPath, "#5 Root"); a.deep(omap(data.map, String), map, "#5 Data"); return rmdir(gitTwo); }, DELAY) )( delay(function () { var map = {}; map[pgPath] = "one\n\ntwo\n!three\n"; map[onePath] = "foo\n!bar"; map[twoPath] = "!raz\ndwa\n"; a(invoked, data, "#6 invoked"); invoked = false; a(data.root, pgPath, "#6 Root"); a.deep(omap(data.map, String), map, "#6 Data"); return unlink(twoFile); }, DELAY) )( delay(function () { var map = {}; map[pgPath] = "one\n\ntwo\n!three\n"; map[onePath] = "foo\n!bar"; a(invoked, data, "#7 invoked"); invoked = false; a(data.root, pgPath, "#7 Root"); a.deep(omap(data.map, String), map, "#7 Data"); return unlink(oneFile); }, DELAY) )( delay(function () { var map = {}; map[pgPath] = "one\n\ntwo\n!three\n"; a(invoked, data, "#8 invoked"); invoked = false; a(data.root, pgPath, "#8 Root"); a.deep(omap(data.map, String), map, "#8 Data"); return unlink(rootFile); }, DELAY) )( delay(function () { var map = {}; a(invoked, data, "#9 invoked"); invoked = false; a(data.root, pgPath, "#9 Root"); a.deep(omap(data.map, String), map, "#9 Data"); watcher.close(); return deferred( rmdir(gitRoot), rmdir(twoPath)(function () { return rmdir(onePath); }) )(false); }, DELAY) ).done(d, d); }; medikoo-fs2-b93c977/test/lib/ignore-modes/000077500000000000000000000000001466730653100203325ustar00rootroot00000000000000medikoo-fs2-b93c977/test/lib/ignore-modes/git.js000066400000000000000000000106311466730653100214540ustar00rootroot00000000000000"use strict"; var isValue = require("es5-ext/object/is-value") , fs = require("fs") , deferred = require("deferred") , resolve = require("path").resolve , promisify = deferred.promisify , delay = deferred.delay , mkdir = promisify(fs.mkdir) , rmdir = promisify(fs.rmdir) , isArray = Array.isArray , rootPath = resolve(__dirname, "../../__playground/lib/ignore-modes/git"); module.exports = function (t, a, d) { var gitRoot = resolve(rootPath, ".git") , onePath = resolve(rootPath, "one") , gitOnePath = resolve(onePath, ".git") , twoPath = resolve(onePath, "two") , gitTwoPath = resolve(twoPath, ".git") , rootEvents = [] , oneEvents = [] , twoEvents = [] , w1 , w2 , w3; a(typeof t.filename, "string", "Filename"); a(!isValue(t.globalRules) || isArray(t.globalRules), true, "Global rules"); // Create /.git mkdir(gitRoot)(function () { // Create /one return mkdir(onePath); })(function () { // Create /one/.git return mkdir(gitOnePath); })(function () { w1 = t.isRootWatcher(rootPath); w1.on("change", function (value) { rootEvents.push(value); }); w2 = t.isRootWatcher(onePath); w2.on("change", function (value) { oneEvents.push(value); }); w3 = t.isRootWatcher(twoPath); w3.on("change", function (value) { twoEvents.push(value); }); return deferred(w1, w2, w3); })( delay(function (data) { a.deep(data, [true, true, false], "#1"); a(String(rootEvents), "", "#1: Root Event"); a(String(oneEvents), "", "#1: One Event"); a(String(twoEvents), "", "#1: Two Event"); rootEvents = []; oneEvents = []; twoEvents = []; // Create /one/two return mkdir(twoPath); }, 20) )( delay(function () { // Create /one/two/.git return mkdir(gitTwoPath); }, 20) )( delay(function () { a(String(rootEvents), "", "#2: Root Event"); a(String(oneEvents), "", "#2: One Event"); a(String(twoEvents), "true", "#2: Two Event"); rootEvents = []; oneEvents = []; twoEvents = []; return deferred(t.isRoot(rootPath), t.isRoot(onePath), t.isRoot(twoPath)); }, 20) )(function (data) { a.deep(data, [true, true, true], "#2"); // Remove /one/.git return rmdir(gitOnePath); })( delay(function () { a(String(rootEvents), "", "#3: Root Event"); a(String(oneEvents), "false", "#3: One Event"); a(String(twoEvents), "", "#3: Two Event"); rootEvents = []; oneEvents = []; twoEvents = []; return deferred(t.isRoot(rootPath), t.isRoot(onePath), t.isRoot(twoPath)); }, 20) )(function (data) { a.deep(data, [true, false, true], "#3"); // Remove /one/two/.git return rmdir(gitTwoPath); })( delay(function () { a(String(rootEvents), "", "#4: Root Event"); a(String(oneEvents), "", "#4: One Event"); a(String(twoEvents), "false", "#4: Two Event"); rootEvents = []; oneEvents = []; twoEvents = []; return deferred(t.isRoot(rootPath), t.isRoot(onePath), t.isRoot(twoPath)); }, 20) )(function (data) { a.deep(data, [true, false, false], "#4"); // Create /one/two/.git return mkdir(gitTwoPath); })( delay(function () { a(String(rootEvents), "", "#5: Root Event"); a(String(oneEvents), "", "#5: One Event"); a(String(twoEvents), "true", "#5: Two Event"); rootEvents = []; oneEvents = []; twoEvents = []; return deferred(t.isRoot(rootPath), t.isRoot(onePath), t.isRoot(twoPath)); }, 20) )(function (data) { a.deep(data, [true, false, true], "#5"); // Remove /one/two/.git return rmdir(gitTwoPath); })( delay(function () { a(String(rootEvents), "", "#6: Root Event"); a(String(oneEvents), "", "#6: One Event"); a(String(twoEvents), "false", "#6: Two Event"); rootEvents = []; oneEvents = []; twoEvents = []; return deferred(t.isRoot(rootPath), t.isRoot(onePath), t.isRoot(twoPath)); }, 20) )(function (data) { a.deep(data, [true, false, false], "#6"); })(function () { // Remove /one/two return rmdir(twoPath); })(function () { // Remove /one return rmdir(onePath); })( delay(function () { a(String(rootEvents), "", "#7: Root Event"); a(String(oneEvents), "", "#7: One Event"); a(String(twoEvents), "", "#7: Two Event"); rootEvents = []; oneEvents = []; twoEvents = []; return deferred(t.isRoot(rootPath), t.isRoot(onePath), t.isRoot(twoPath)); }, 20) )(function (data) { a.deep(data, [true, false, false], "#7"); w1.close(); w2.close(); w3.close(); return rmdir(gitRoot); }).done(d, d); }; medikoo-fs2-b93c977/test/lib/ignore-modes/index.js000066400000000000000000000003031466730653100217730ustar00rootroot00000000000000"use strict"; var indexTest = require("tad/lib/utils/index-test") , dirPath = require("path").resolve(__dirname, "../../../lib/ignore-modes"); module.exports = indexTest(dirPath, ["tad"]); medikoo-fs2-b93c977/test/lib/memoize-watcher.js000066400000000000000000000013671466730653100214070ustar00rootroot00000000000000"use strict"; module.exports = function (t, a) { var fn, invoked, mfn, fnX, fnY, fnZ; fn = function (pathIgnored) { return { emit: function () { return true; }, close: function () { invoked = true; } }; }; invoked = false; mfn = t(fn); fnX = mfn("foo"); fnY = mfn("foo"); fnZ = mfn("bar"); a(invoked, false, "Pre calls"); fnZ.close(); a(invoked, true, "After single call"); invoked = false; fnZ.close(); a(invoked, false, "Second close call has no effect"); invoked = false; fnX.close(); a(invoked, false, "After one of two calls"); invoked = false; fnY.close(); a(invoked, true, "After two of two calls"); invoked = false; fnX.close(); a(invoked, false, "Second close call has no effect (two calls case)"); invoked = false; }; medikoo-fs2-b93c977/test/lib/watch-alt.js000066400000000000000000000064011466730653100201650ustar00rootroot00000000000000"use strict"; var fs = require("fs") , resolve = require("path").resolve , deferred = require("deferred") , bufferFrom = require("../../lib/buffer-from") , delay = deferred.delay , promisify = deferred.promisify , mkdir = promisify(fs.mkdir) , open = promisify(fs.open) , rename = promisify(fs.rename) , write = promisify(fs.write) , close = promisify(fs.close) , writeFile = promisify(fs.writeFile) , unlink = promisify(fs.unlink) , rmdir = promisify(fs.rmdir) , pgPath = resolve(__dirname, "../__playground/lib/watch-alt"); module.exports = function (t, a, d) { var ondirchange = 0 , onfilechange = 0 , ondirend = 0 , onfileend = 0 , DELAY = 200 , DELAYWAIT = 2000 , dirPath = resolve(pgPath, "tmpdir") , filePath = resolve(dirPath, "tmpfile"); a.throws(function () { t(filePath); }, "Not existing"); delay(function () { return mkdir(dirPath); }, DELAY)()( delay(function () { var dirWatch; dirWatch = t(dirPath); dirWatch.on("change", function () { ++ondirchange; }); dirWatch.on("end", function () { ++ondirend; }); }, DELAY) )(delay(function () { return writeFile(filePath, "raz"); }, DELAYWAIT))( delay(function () { var fileWatch; a(ondirchange, 1, "Dir change: File created"); a(ondirend, 0, "Dir end: File created"); ondirchange = ondirend = 0; fileWatch = t(filePath); fileWatch.on("change", function () { ++onfilechange; }); fileWatch.on("end", function () { ++onfileend; }); }, DELAYWAIT) )( delay(function () { return open(filePath, "a")(function (fd) { return write( fd, bufferFrom("dwatrzy"), 0, 3, null )(function () { return close(fd); }); }); }, DELAY) )( delay(function () { a(ondirchange, 0, "Dir change: File changed"); a(ondirend, 0, "Dir end: File changed"); a(onfilechange, 1, "File change: File created"); a(onfileend, 0, "File end: File created"); ondirchange = ondirend = onfilechange = onfileend = 0; return rename(filePath, filePath + "r"); }, DELAYWAIT) )( delay(function () { a(ondirchange, 1, "Dir change: File renamed"); a(ondirend, 0, "Dir end: File renamed"); a(onfilechange, 0, "File change: File renamed"); a(onfileend, 1, "File end: File renamed"); ondirchange = ondirend = onfilechange = onfileend = 0; return rename(filePath + "r", filePath); }, DELAYWAIT) )( delay(function () { a(ondirchange, 1, "Dir change: File renamed back"); a(ondirend, 0, "Dir end: File renamed back"); a(onfilechange, 0, "File change: File renamed back"); a(onfileend, 0, "File end: File renamed back"); ondirchange = ondirend = onfilechange = onfileend = 0; return unlink(filePath); }, DELAYWAIT) )( delay(function () { a(ondirchange, 1, "Dir change: File removed"); a(ondirend, 0, "Dir end: File removed"); a(onfilechange, 0, "File change: File removed"); a(onfileend, 0, "File end: File removed"); ondirchange = ondirend = onfilechange = onfileend = 0; return rmdir(dirPath); }, DELAYWAIT) )( delay(function () { a(ondirchange, 0, "Dir change: Dir removed"); a(ondirend, 1, "Dir end: Dir removed"); a(onfilechange, 0, "File change: Dir removed"); a(onfileend, 0, "File end: Dir removed"); }, DELAYWAIT) ).done(d, d); }; medikoo-fs2-b93c977/test/lib/watch.js000066400000000000000000000062631466730653100174150ustar00rootroot00000000000000"use strict"; var fs = require("fs") , resolve = require("path").resolve , deferred = require("deferred") , bufferFrom = require("../../lib/buffer-from") , delay = deferred.delay , promisify = deferred.promisify , mkdir = promisify(fs.mkdir) , open = promisify(fs.open) , rename = promisify(fs.rename) , write = promisify(fs.write) , close = promisify(fs.close) , writeFile = promisify(fs.writeFile) , unlink = promisify(fs.unlink) , rmdir = promisify(fs.rmdir) , pgPath = resolve(__dirname, "../__playground/lib/watch"); module.exports = function (t, a, d) { var ondirchange = 0 , onfilechange = 0 , ondirend = 0 , onfileend = 0 , DELAY = 200 , dirPath = resolve(pgPath, "tmpdir") , filePath = resolve(dirPath, "tmpfile"); a.throws(function () { t(filePath); }, "Not existing"); delay(function () { return mkdir(dirPath); }, DELAY)()( delay(function () { var emitter = t(dirPath); emitter.on("change", function () { ++ondirchange; }); emitter.on("end", function () { ++ondirend; }); }, DELAY) )(delay(function () { return writeFile(filePath, "raz"); }, DELAY))( delay(function () { var emitter; a(ondirchange, 1, "Dir change: File created"); a(ondirend, 0, "Dir end: File created"); ondirchange = ondirend = 0; emitter = t(filePath); emitter.on("change", function () { ++onfilechange; }); emitter.on("end", function () { ++onfileend; }); }, DELAY) )( delay(function () { return open(filePath, "a")(function (fd) { return write( fd, bufferFrom("dwatrzy"), 0, 3, null )(function () { return close(fd); }); }); }, DELAY) )( delay(function () { a(ondirchange, 0, "Dir change: File changed"); a(ondirend, 0, "Dir end: File changed"); a(onfilechange, 1, "File change: File created"); a(onfileend, 0, "File end: File created"); ondirchange = ondirend = onfilechange = onfileend = 0; return rename(filePath, filePath + "r"); }, DELAY) )( delay(function () { a(ondirchange, 1, "Dir change: File renamed"); a(ondirend, 0, "Dir end: File renamed"); a(onfilechange, 0, "File change: File renamed"); a(onfileend, 1, "File end: File renamed"); ondirchange = ondirend = onfilechange = onfileend = 0; return rename(filePath + "r", filePath); }, DELAY) )( delay(function () { a(ondirchange, 1, "Dir change: File renamed back"); a(ondirend, 0, "Dir end: File renamed back"); a(onfilechange, 0, "File change: File renamed back"); a(onfileend, 0, "File end: File renamed back"); ondirchange = ondirend = onfilechange = onfileend = 0; return unlink(filePath); }, DELAY) )( delay(function () { a(ondirchange, 1, "Dir change: File removed"); a(ondirend, 0, "Dir end: File removed"); a(onfilechange, 0, "File change: File removed"); a(onfileend, 0, "File end: File removed"); ondirchange = ondirend = onfilechange = onfileend = 0; return rmdir(dirPath); }, DELAY) )( delay(function () { a(ondirchange, 0, "Dir change: Dir removed"); a(ondirend, 1, "Dir end: Dir removed"); a(onfilechange, 0, "File change: Dir removed"); a(onfileend, 0, "File end: Dir removed"); }, DELAY) ).done(d, d); }; medikoo-fs2-b93c977/test/lstat.js000066400000000000000000000004541466730653100166640ustar00rootroot00000000000000"use strict"; var resolve = require("path").resolve; module.exports = function (t, a, d) { t(__filename)(function (stats) { a(stats.isFile(), true, "Success"); return t( resolve(__dirname, "n/a") )(a.never, function (err) { a(err.code, "ENOENT", "Error"); }); }, a.never).done(d, d); }; medikoo-fs2-b93c977/test/mkdir.js000066400000000000000000000024561466730653100166470ustar00rootroot00000000000000"use strict"; var promisify = require("deferred").promisify , fs = require("fs") , path = require("path") , dirname = path.dirname , resolve = path.resolve , lstat = promisify(fs.lstat) , rmdir = promisify(fs.rmdir) , rootPath = resolve(__dirname, "./__playground/mkdir") , regular = resolve(rootPath, "foo") , existing = resolve(rootPath, "one") , deep = resolve(rootPath, "foo", "bar"); module.exports = function (t) { return { Regular: { Success: function (a, d) { t(regular)(function () { return lstat(regular)(function (stats) { a(stats.isDirectory(), true); return rmdir(regular); }); }).done(d, d); }, Error: function (a, d) { t(deep)(a.never, function () { a.ok(true, ""); }).done(d, d); }, Existing: function (a, d) { t(existing)(a.never, function () { a.ok(true, ""); }).done(d, d); } }, Intermediate: { "": function (a, d) { t(deep, { intermediate: true })(function () { return lstat(deep)(function (stats) { a(stats.isDirectory(), true); return rmdir(deep)(function () { return rmdir(dirname(deep)); }); }); }).done(d, d); }, "Existing": function (a, d) { t(existing, { intermediate: true })(function () { a.ok(true, ""); }).done(d, d); } } }; }; medikoo-fs2-b93c977/test/read-file.js000066400000000000000000000113511466730653100173630ustar00rootroot00000000000000"use strict"; var deferred = require("deferred") , bufferFrom = require("../lib/buffer-from") , delay = deferred.delay , promisify = deferred.promisify , isBuffer = Buffer.isBuffer , fs = require("fs") , resolve = require("path").resolve , open = promisify(fs.open) , write = promisify(fs.write) , close = promisify(fs.close) , writeFile = promisify(fs.writeFile) , unlink = promisify(fs.unlink) , pgPath = resolve(__dirname, "./__playground/read-file"); module.exports = function (t) { var DELAY = 100; return { Regular: { "Doesn't exist": function (a, d) { t(resolve(pgPath, "fake"))(a.never, function (err) { a(err.code, "ENOENT"); }).done( d, d ); }, "Exists": function (a, d) { t(resolve(pgPath, "test"))(function (data) { a(isBuffer(data), true, "Buffer returned"); a(String(data), "raz\ndwa", "Content"); }, a.never).done(d, d); }, "Encoding": function (a, d) { t(resolve(pgPath, "test"), "utf8")(function (data) { a(data, "raz\ndwa"); }, a.never).done(d, d); }, "Loose": { "Doesn't exist": function (a, d) { t(resolve(pgPath, "fake"), { loose: true })(function (data) { a(data, null); }, a.never).done(d, d); }, "Exists": function (a, d) { t(resolve(pgPath, "test"), { loose: true })(function (data) { a(String(data), "raz\ndwa"); }, a.never).done(d, d); } } }, Watch: { Regular: { "Doesn't exist": function (a, d) { t(resolve(pgPath, "fake"), { watch: true })(a.never, function (err) { a(err.code, "ENOENT"); }).done(d, d); }, "Exists": function (a, d) { var path = resolve(pgPath, "watch-test"), invoked, ended, watcher; return writeFile(path, "one\ntwo")( delay(function () { invoked = false; ended = false; watcher = t(path, { watch: true }); watcher.on("change", function (data) { a(invoked, false, "Expected invoke"); invoked = data; }); watcher.on("end", function () { ended = true; }); return watcher; }, DELAY) )( delay(function (data) { a(isBuffer(data), true, "Buffer returned"); a(String(data), "one\ntwo", "Content"); return open(path, "a")(function (fd) { return write( fd, bufferFrom("\nthree\n"), 0, 7, null )(function () { return close(fd); }); }); }, DELAY) )( delay(function () { a(isBuffer(invoked), true, "Emitted buffer"); a(String(invoked), "one\ntwo\nthree\n", "Buffer data"); invoked = false; return open(path, "a")(function (fd) { return write( fd, bufferFrom(""), 0, 0, null )(function () { return close(fd); }); }); }, DELAY) )( delay(function () { a(invoked, false, "Update without change"); a(ended, false, "Not ended"); return unlink(path); }, DELAY) )(delay(function () { a(ended, true, "Watcher ended"); }, DELAY)).done(d, d); } }, Loose: function (a, d) { var path = resolve(pgPath, "watch-loose-test"), invoked, ended, watcher; invoked = false; ended = false; watcher = t(path, { watch: true, loose: true }); watcher.on("change", function (data) { a(invoked, false, "Expected invoke"); invoked = data; }); watcher.on("end", function () { ended = true; }); return watcher( delay(function (data) { a(data, null, "No file yet"); return writeFile(path, "foo\nbar"); }, DELAY) )( delay(function () { a(isBuffer(invoked), true, "Emitted buffer"); a(String(invoked), "foo\nbar", "Emitted Content"); invoked = false; return open(path, "a")(function (fd) { return write( fd, bufferFrom("\nfour\n"), 0, 6, null )(function () { return close(fd); }); }); }, DELAY) )( delay(function () { a(isBuffer(invoked), true, "Emitted buffer"); a(String(invoked), "foo\nbar\nfour\n", "Buffer data"); invoked = false; return open(path, "a")(function (fd) { return write( fd, bufferFrom(""), 0, 0, null )(function () { return close(fd); }); }); }, DELAY) )( delay(function () { a(invoked, false, "Update without change"); a(ended, false, "Not ended"); return unlink(path); }, DELAY) )( delay(function () { a(invoked, null, "Emitted null"); invoked = false; return writeFile(path, "foo\nagain"); }, DELAY) )( delay(function () { a(isBuffer(invoked), true, "Emitted buffer"); a(String(invoked), "foo\nagain", "Emitted Content"); watcher.close(); return unlink(path); }, DELAY) ).done(d, d); } } }; }; medikoo-fs2-b93c977/test/readdir.js000066400000000000000000000725551466730653100171620ustar00rootroot00000000000000/* eslint max-lines: off */ "use strict"; var push = Array.prototype.push , fs = require("fs") , pathUtils = require("path") , aFrom = require("es5-ext/array/from") , diff = require("es5-ext/array/#/diff") , startsWith = require("es5-ext/string/#/starts-with") , deferred = require("deferred") , delay = deferred.delay , promisify = deferred.promisify , mkdir = promisify(fs.mkdir) , writeFile = promisify(fs.writeFile) , unlink = promisify(fs.unlink) , rmdir = promisify(fs.rmdir) , basename = pathUtils.basename , resolve = pathUtils.resolve , sep = pathUtils.sep , pgPath = resolve(__dirname, "./__playground/readdir"); module.exports = function (t) { var pathsAll, paths2, paths0, files2, replaceSep, DELAY = 100; replaceSep = function (path) { return path.replace(/\//g, sep); }; pathsAll = [ "done", "done/done", "done/done/dthree", "done/done/dthree/dthree", "done/done/dthree/dthree/foo", "done/done/dthree/dtwo", "done/done/dthree/dtwo/foo", "done/done/dthree/one", "done/done/dthree/three", "done/done/dthree/two", "done/done/dtwo", "done/done/dtwo/dtwo", "done/done/dtwo/dtwo/foo", "done/done/dtwo/one", "done/done/dtwo/three", "done/done/dtwo/two", "done/done/one", "done/done/three", "done/done/two", "done/dtwo", "done/dtwo/foo", "done/one", "done/three", "done/two", "dthree", "dthree/dthree", "dthree/dthree/done", "dthree/dthree/done/dthree", "dthree/dthree/done/dthree/foo", "dthree/dthree/done/one", "dthree/dthree/done/three", "dthree/dthree/done/two", "dthree/dthree/one", "dthree/dthree/three", "dthree/dthree/two", "dthree/dtwo", "dthree/dtwo/foo", "dthree/one", "dthree/three", "dthree/two", "dtwo", "dtwo/one", "dtwo/three", "dtwo/two", "one", "three", "two" ].map(replaceSep); paths2 = pathsAll.filter(function (path) { return path.split(sep).length < 4; }); paths0 = pathsAll.filter(function (path) { return path.split(sep).length < 2; }); files2 = paths2.filter(function (path) { return basename(path)[0] !== "d"; }); return { "": { "0": function (a, d) { var reader = t(pgPath, { watch: true }) , testName = "foo" , testPath = resolve(pgPath, testName) , paths = paths0 , invoked = false; reader.on("change", function (data) { invoked = data; }); reader( delay(function (data) { a.deep(data.sort(), paths); return mkdir(testPath); }, DELAY * 2) )( delay(function () { a.deep(invoked.removed, [], "Created: removed"); a.deep(invoked.added, [testName], "Created: added"); invoked = false; reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return rmdir(testPath); })( delay(function () { a.deep(invoked.removed, [testName], "Deleted: removed"); a.deep(invoked.added, [], "Deleted: added"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); reader.close(); }, DELAY) ).done(d, d); }, "2": function (a, d) { var reader = t(pgPath, { depth: 2, watch: true }) , testName = replaceSep("dtwo/foo") , testPath = resolve(pgPath, testName) , paths = paths2 , invoked = false; reader.on("change", function (data) { invoked = data; }); reader(function (data) { a.deep(data.sort(), paths); })( delay(function () { return mkdir(testPath); }, DELAY) )( delay(function () { a.deep(invoked.removed, [], "Created: removed"); a.deep(invoked.added, [testName], "Created: added"); invoked = false; reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2 }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return rmdir(testPath); })( delay(function () { a.deep(invoked.removed, [testName], "Deleted: removed"); a.deep(invoked.added, [], "Deleted: added"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); reader.close(); }, DELAY) ).done(d, d); }, "∞": function (a, d) { var reader = t(pgPath, { depth: Infinity, watch: true }) , testName = replaceSep("done/done/dthree/test") , testPath = resolve(pgPath, testName) , paths = pathsAll , invoked = false; reader.on("change", function (data) { invoked = data; }); reader(function (data) { a.deep(data.sort(), paths); })( delay(function () { return writeFile(testPath, "foo"); }, DELAY) )( delay(function () { a.deep(invoked.removed, [], "Created: removed"); a.deep(invoked.added, [testName], "Created: added"); invoked = false; reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: Infinity }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return unlink(testPath); })( delay(function () { a.deep(invoked.removed, [testName], "Deleted: removed"); a.deep(invoked.added, [], "Deleted: added"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); reader.close(); }, DELAY) ).done(d, d); } }, "Loose": function (a, d) { var reader = t(resolve(pgPath, "not-existing"), { loose: true }); reader(function (data) { a(data, null); }).done(d, d); }, "Progress events": function (a, d) { var reader = t(pgPath, { depth: Infinity, stream: true }) , result = [] , lengths = [] , count = 0; reader.on("change", function (data) { ++count; lengths.push(data.added.length); a.deep(data.removed, [], "Removed #" + count); push.apply(result, data.added); a.deep(result.sort(), data.data.sort(), "Data #" + count); }); reader(function (data) { a.deep(lengths.sort(), [1, 1, 1, 1, 1, 1, 3, 4, 4, 4, 5, 5, 5, 5, 6], "Events"); a.deep(result.sort(), data.sort(), "Result"); }).done(d, d); }, "Type": function (a, d) { var reader = t(pgPath, { depth: 2, type: { file: true }, watch: true }) , testName = replaceSep("dtwo/test") , testPath = resolve(pgPath, testName) , paths = files2 , invoked = false; reader.on("change", function (data) { invoked = data; }); reader(function (data) { a.deep(data.sort(), paths); return mkdir(testPath); })( delay(function () { a(invoked, false, "Created other type: event"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Created other type: data"); }).done(); return rmdir(testPath); }, DELAY) )( delay(function () { a(invoked, false, "Deleted other type: event"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted other type: data"); }).done(); return writeFile(testPath, "foo"); }, DELAY) )( delay(function () { a.deep(invoked.removed, [], "Created: removed"); a.deep(invoked.added, [testName], "Created: added"); invoked = false; reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, type: { file: true } }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return unlink(testPath); })( delay(function () { a.deep(invoked.removed, [testName], "Deleted: removed"); a.deep(invoked.added, [], "Deleted: added"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); reader.close(); }, DELAY) ).done(d, d); }, "Types": function (a, d) { var reader = t(pgPath, { depth: 2, type: { file: true, directory: true }, watch: true }) , testName = replaceSep("dtwo/foo") , testPath = resolve(pgPath, testName) , paths = paths2 , invoked = false; reader.on("change", function (data) { invoked = data; }); reader( delay(function (data) { a.deep(data.sort(), paths); return mkdir(testPath); }, DELAY) )( delay(function () { a.deep(invoked.removed, [], "Created: removed"); a.deep(invoked.added, [testName], "Created: added"); invoked = false; reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, type: { file: true, directory: true } }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return rmdir(testPath); })( delay(function () { a.deep(invoked.removed, [testName], "Deleted: removed"); a.deep(invoked.added, [], "Deleted: added"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); reader.close(); }, DELAY) ).done(d, d); }, "Pattern": function (a, d) { var pattern = /one$/ , reader = t(pgPath, { depth: 2, pattern: pattern, watch: true }) , otherName = replaceSep("dtwo/test") , otherPath = resolve(pgPath, otherName) , testName = replaceSep("dtwo/fooone") , testPath = resolve(pgPath, testName) , paths = paths2.filter(function (path) { return pattern.test(path); }) , invoked = false; reader.on("change", function (data) { invoked = data; }); reader(function (data) { a.deep(data.sort(), paths); return mkdir(otherPath); })( delay(function () { a(invoked, false, "Created other type: event"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Created other type: data"); }).done(); return rmdir(otherPath); }, DELAY) )( delay(function () { a(invoked, false, "Deleted other type: event"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted other type: data"); }).done(); return mkdir(testPath); }, DELAY) )( delay(function () { a.deep(invoked.removed, [], "Created: removed"); a.deep(invoked.added, [testName], "Created: added"); invoked = false; reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, pattern: pattern }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return rmdir(testPath); })( delay(function () { a.deep(invoked.removed, [testName], "Deleted: removed"); a.deep(invoked.added, [], "Deleted: added"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); reader.close(); }, DELAY) ).done(d, d); }, "Global rules": function (a, d) { var rules = ["one"] , re = /(?:^|\/|\\)one(?:\/|\\|$)/ , reader = t(pgPath, { depth: 2, globalRules: rules, watch: true }) , otherName = replaceSep("dthree/dtwo/one") , otherPath = resolve(pgPath, otherName) , testName = replaceSep("dtwo/fooone") , testPath = resolve(pgPath, testName) , paths = paths2.filter(function (path) { return !re.test(path); }) , invoked = false; reader.on("change", function (data) { invoked = data; }); reader(function (data) { a.deep(data.sort(), paths); return mkdir(otherPath); })( delay(function () { a(invoked, false, "Created other type: event"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Created other type: data"); }).done(); return rmdir(otherPath); }, DELAY) )( delay(function () { a(invoked, false, "Deleted other type: event"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted other type: data"); }).done(); return mkdir(testPath); }, DELAY) )( delay(function () { a.deep(invoked.removed, [], "Created: removed"); a.deep(invoked.added, [testName], "Created: added"); invoked = false; reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, globalRules: rules }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return rmdir(testPath); })( delay(function () { a.deep(invoked.removed, [testName], "Deleted: removed"); a.deep(invoked.added, [], "Deleted: added"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); reader.close(); }, DELAY) ).done(d, d); }, "Pattern & Type": function (a, d) { var pattern = /one$/ , reader = t(pgPath, { depth: 2, type: { file: true }, pattern: pattern, watch: true }) , testName = replaceSep("dtwo/fooone") , testPath = resolve(pgPath, testName) , paths = files2.filter(function (path) { return pattern.test(path); }) , invoked = false; reader.on("change", function (data) { invoked = data; }); reader( delay(function (data) { a.deep(data.sort(), paths); return mkdir(testPath); }, DELAY) )( delay(function () { a(invoked, false, "Created other type: event"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Created other type: data"); }).done(); return rmdir(testPath); }, DELAY) )( delay(function () { a(invoked, false, "Deleted other type: event"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted other type: data"); }).done(); return writeFile(testPath, "foo"); }, DELAY) )( delay(function () { a.deep(invoked.removed, [], "Created: removed"); a.deep(invoked.added, [testName], "Created: added"); invoked = false; reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, type: { file: true }, pattern: pattern }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return unlink(testPath); })( delay(function () { a.deep(invoked.removed, [testName], "Deleted: removed"); a.deep(invoked.added, [], "Deleted: added"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); reader.close(); }, DELAY) ).done(d, d); }, "Ignored": function (a, d) { var gitPath = resolve(pgPath, ".git") , ignoreFile = resolve(pgPath, ".gitignore") , otherName = replaceSep("dtwo/test") , otherPath = resolve(pgPath, otherName) , testName = replaceSep("dthree/fooone") , testPath = resolve(pgPath, testName) , paths = paths2.filter(function (path) { return path.indexOf("dtwo") === -1; }) , reader , invoked = [] , mergeInvoked , npaths; mergeInvoked = function () { var result; if (!invoked.length) { return false; } result = { data: invoked[0].data, removed: [], added: [] }; invoked.forEach(function (data) { push.apply(result.added, data.added); push.apply(result.removed, data.removed); }); invoked = []; return result; }; paths.push(".gitignore"); paths.sort(); npaths = paths.filter(function (path) { return ( path !== "one" && path.indexOf(sep + "one") === -1 && !startsWith.call(path, "dthree" + sep + "dthree") ); }); deferred(mkdir(gitPath), writeFile(ignoreFile, "dtwo"))( delay(function () { reader = t(pgPath, { depth: 2, ignoreRules: "git", watch: true }); reader.on("change", function (data) { invoked.push(data); }); return reader; }, DELAY) )(function (data) { a.deep(data.sort(), paths); return mkdir(otherPath); })( delay(function () { var lInvoked = mergeInvoked(); a(lInvoked, false, "Created other type: event"); reader(function (data) { a.deep(data.sort(), paths, "Created other type: data"); }).done(); return rmdir(otherPath); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a(lInvoked, false, "Deleted other type: event"); reader(function (data) { a.deep(data.sort(), paths, "Deleted other type: data"); }).done(); return mkdir(testPath); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [], "Created: removed"); a.deep(lInvoked.added, [testName], "Created: added"); reader(function (data) { var npaths2 = aFrom(paths); npaths2.push(testName); a.deep(data.sort(), npaths2.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, ignoreRules: "git" }); }, DELAY) )(function (data) { var npaths2 = aFrom(paths); npaths2.push(testName); a.deep(data.sort(), npaths2.sort(), "Not watched"); return rmdir(testPath); })( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [testName], "Deleted: removed"); a.deep(lInvoked.added, [], "Deleted: added"); reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); return writeFile(ignoreFile, "dtwo\none\n/dthree/dthree"); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a.deep( lInvoked && lInvoked.removed && lInvoked.removed.sort(), diff.call(paths, npaths).sort(), "Ignored: removed" ); a.deep(lInvoked.added, [], "Ignored: added"); reader(function (data) { a.deep(data.sort(), npaths, "Ignored: data"); }).done(); return writeFile(ignoreFile, "dtwo"); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [], "Ignored revert: removed"); a.deep( lInvoked && lInvoked.added && lInvoked.added.sort(), diff.call(paths, npaths).sort(), "Ignored revert: added" ); reader(function (data) { a.deep(data.sort(), paths, "Ignored revert: data"); }).done(); reader.close(); return deferred(rmdir(gitPath), unlink(ignoreFile))(false); }, DELAY) ).done(d, d); }, "Ignored & Type": function (a, d) { var gitPath = resolve(pgPath, ".git") , ignoreFile = resolve(pgPath, ".gitignore") , otherName = replaceSep("dtwo/test") , otherPath = resolve(pgPath, otherName) , testName = replaceSep("dthree/fooone") , testPath = resolve(pgPath, testName) , paths = files2.filter(function (path) { return path.indexOf("dtwo") === -1; }) , reader , invoked = [] , mergeInvoked; mergeInvoked = function () { var result; if (!invoked.length) { return false; } result = { data: invoked[0].data, removed: [], added: [] }; invoked.forEach(function (data) { push.apply(result.added, data.added); push.apply(result.removed, data.removed); }); invoked = []; return result; }; paths.push(".gitignore"); paths.sort(); deferred(mkdir(gitPath), writeFile(ignoreFile, "dtwo"))( delay(function () { reader = t(pgPath, { depth: 2, type: { file: true }, ignoreRules: "git", watch: true }); reader.on("change", function (data) { invoked.push(data); }); return reader; }, DELAY) )( delay(function (data) { a.deep(data.sort(), paths); return writeFile(otherPath, "foo"); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a(lInvoked, false, "Created other type: event"); reader(function (data) { a.deep(data.sort(), paths, "Created other type: data"); }).done(); return unlink(otherPath); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a(lInvoked, false, "Deleted other type: event"); reader(function (data) { a.deep(data.sort(), paths, "Deleted other type: data"); }).done(); return writeFile(testPath, "foo"); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [], "Created: removed"); a.deep(lInvoked.added, [testName], "Created: added"); reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, type: { file: true }, ignoreRules: "git" }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return unlink(testPath); })( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [testName], "Deleted: removed"); a.deep(lInvoked.added, [], "Deleted: added"); reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); }, DELAY) )(delay(function () { return writeFile(ignoreFile, "dtwo\none"); }, DELAY))( delay(function () { var lInvoked , npaths = paths .filter(function (path) { return path !== "one" && path.indexOf(sep + "one") === -1; }) .sort(); lInvoked = mergeInvoked(); a.deep( lInvoked.removed && lInvoked.removed.sort(), diff.call(paths, npaths).sort(), "Ignored: removed" ); a.deep(lInvoked.added, [], "Ignored: added"); reader(function (data) { a.deep(data.sort(), npaths, "Ignored: data"); }).done(); reader.close(); return deferred(rmdir(gitPath), unlink(ignoreFile))(false); }, DELAY) ).done(d, d); }, "Ignored & Pattern": function (a, d) { var pattern = /done/ , gitPath = resolve(pgPath, ".git") , ignoreFile = resolve(pgPath, ".gitignore") , otherName = replaceSep("dtwo/test") , otherPath = resolve(pgPath, otherName) , testName = replaceSep("done/fooone") , testPath = resolve(pgPath, testName) , paths = paths2.filter(function (path) { return path.indexOf("dtwo") === -1 && pattern.test(path); }) , reader , invoked = [] , mergeInvoked; mergeInvoked = function () { var result; if (!invoked.length) { return false; } result = { data: invoked[0].data, removed: [], added: [] }; invoked.forEach(function (data) { push.apply(result.added, data.added); push.apply(result.removed, data.removed); }); invoked = []; return result; }; deferred(mkdir(gitPath), writeFile(ignoreFile, "dtwo"))( delay(function () { reader = t(pgPath, { depth: 2, pattern: pattern, ignoreRules: "git", watch: true }); reader.on("change", function (data) { invoked.push(data); }); return reader; }, DELAY) )( delay(function (data) { a.deep(data.sort(), paths); return mkdir(otherPath); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a(lInvoked, false, "Created other type: event"); reader(function (data) { a.deep(data.sort(), paths, "Created other type: data"); }).done(); return rmdir(otherPath); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a(lInvoked, false, "Deleted other type: event"); reader(function (data) { a.deep(data.sort(), paths, "Deleted other type: data"); }).done(); return mkdir(testPath); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [], "Created: removed"); a.deep(lInvoked.added, [testName], "Created: added"); reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, pattern: pattern, ignoreRules: "git" }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return rmdir(testPath); })( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [testName], "Deleted: removed"); a.deep(lInvoked.added, [], "Deleted: added"); reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); }, DELAY) )(delay(function () { return writeFile(ignoreFile, "dtwo\none"); }, DELAY))( delay(function () { var lInvoked , npaths = paths .filter(function (path) { return path !== "one" && path.indexOf(sep + "one") === -1; }) .sort(); lInvoked = mergeInvoked(); a.deep( lInvoked && lInvoked.removed && lInvoked.removed.sort(), diff.call(paths, npaths).sort(), "Ignored: removed" ); a.deep(lInvoked.added, [], "Ignored: added"); reader(function (data) { a.deep(data.sort(), npaths, "Ignored: data"); }).done(); reader.close(); return deferred(rmdir(gitPath), unlink(ignoreFile))(false); }, DELAY) ).done(d, d); }, "Ignored & Pattern & Type": function (a, d) { var pattern = /done/ , gitPath = resolve(pgPath, ".git") , ignoreFile = resolve(pgPath, ".gitignore") , otherName = replaceSep("dtwo/test") , otherPath = resolve(pgPath, otherName) , testName = replaceSep("done/fooone") , testPath = resolve(pgPath, testName) , paths = files2.filter(function (path) { return path.indexOf("dtwo") === -1 && pattern.test(path); }) , reader , invoked = [] , mergeInvoked; mergeInvoked = function () { var result; if (!invoked.length) { return false; } result = { data: invoked[0].data, removed: [], added: [] }; invoked.forEach(function (data) { push.apply(result.added, data.added); push.apply(result.removed, data.removed); }); invoked = []; return result; }; deferred(mkdir(gitPath), writeFile(ignoreFile, "dtwo"))( delay(function () { reader = t(pgPath, { depth: 2, type: { file: true }, pattern: pattern, ignoreRules: "git", watch: true }); reader.on("change", function (data) { invoked.push(data); }); return reader; }, DELAY) )( delay(function (data) { a.deep(data.sort(), paths); return writeFile(otherPath, "foo"); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a(lInvoked, false, "Created other type: event"); reader(function (data) { a.deep(data.sort(), paths, "Created other type: data"); }).done(); return unlink(otherPath); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a(lInvoked, false, "Deleted other type: event"); reader(function (data) { a.deep(data.sort(), paths, "Deleted other type: data"); }).done(); return writeFile(testPath, "foo"); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [], "Created: removed"); a.deep(lInvoked.added, [testName], "Created: added"); reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, type: { file: true }, pattern: pattern, ignoreRules: "git" }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return unlink(testPath); })( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [testName], "Deleted: removed"); a.deep(lInvoked.added, [], "Deleted: added"); reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); }, DELAY) )(delay(function () { return writeFile(ignoreFile, "dtwo\none"); }, DELAY))( delay(function () { var lInvoked , npaths = paths .filter(function (path) { return path !== "one" && path.indexOf(sep + "one") === -1; }) .sort(); lInvoked = mergeInvoked(); a.deep( lInvoked && lInvoked.removed && lInvoked.removed.sort(), diff.call(paths, npaths).sort(), "Ignored: removed" ); a.deep(lInvoked.added, [], "Ignored: added"); reader(function (data) { a.deep(data.sort(), npaths, "Ignored: data"); }).done(); reader.close(); return deferred(rmdir(gitPath), unlink(ignoreFile))(false); }, DELAY) ).done(d, d); }, "cb": function (a, d) { t(pgPath, function (err, result) { if (err) { d(err); return; } a.deep(result.sort(), ["done", "dthree", "dtwo", "one", "three", "two"]); d(); }); } }; }; medikoo-fs2-b93c977/test/readlink.js000066400000000000000000000013541466730653100173260ustar00rootroot00000000000000"use strict"; var resolve = require("path").resolve , symlink = require("../symlink") , unlink = require("../unlink"); var rootPath = resolve(__dirname, "./__playground/readlink") , targetFile = resolve(rootPath, "from") , nonSymlink = resolve(rootPath, "non-symlink") , symlink1 = resolve(rootPath, "sym1") , symlink2 = resolve(rootPath, "sym2"); module.exports = function (t, a, d) { symlink(targetFile, symlink1)(function () { return symlink(symlink1, symlink2); })(function () { return t(symlink2); })(function (resolvedTarget) { a(resolvedTarget, symlink1); return unlink(symlink1)(unlink(symlink2)); })(function () { return t(nonSymlink, { loose: true }); })(function (result) { a(result, null); }).done(d, d); }; medikoo-fs2-b93c977/test/realpath.js000066400000000000000000000004571466730653100173400ustar00rootroot00000000000000"use strict"; var resolve = require("path").resolve; module.exports = function (t, a, d) { t(__filename)(function (filename) { a(filename, __filename, "Success"); return t( resolve(__dirname, "n/a") )(a.never, function (err) { a(err.code, "ENOENT", "Error"); }); }, a.never).done(d, d); }; medikoo-fs2-b93c977/test/rename.js000066400000000000000000000021461466730653100170040ustar00rootroot00000000000000"use strict"; var deferred = require("deferred") , resolve = require("path").resolve , lstat = require("../lstat") , unlink = require("../unlink") , writeFile = require("../write-file") , rootPath = resolve(__dirname, "__playground/rename") , name1 = resolve(rootPath, "file1") , name2 = resolve(rootPath, "file2"); module.exports = function (t, a, d) { writeFile(name1, "fooraz")(function () { return lstat(name1)(function (stats1) { return t(name1, name2)(function () { return deferred( lstat(name1)(a.never, function () { a.ok(true, "No first file"); }), lstat(name2)(function (stats2) { // Do not compare eventual birthtime and ctime // as in some envs they may not reflect value of source file delete stats1.birthtime; delete stats1.birthtimeMs; delete stats2.birthtime; delete stats2.birthtimeMs; delete stats1.ctime; delete stats1.ctimeMs; delete stats2.ctime; delete stats2.ctimeMs; a.deep(stats1, stats2, "Same"); return unlink(name2); }) )(false); }); }); }).done(d, d); }; medikoo-fs2-b93c977/test/rm.js000066400000000000000000000016101466730653100161460ustar00rootroot00000000000000"use strict"; var lstat = require("../lstat") , mkdir = require("../mkdir") , writeFile = require("../write-file") , testFile = require("path").resolve(__dirname, "__playground/rm-file") , testDir = require("path").resolve(__dirname, "__playground/rm-dir"); module.exports = { File: function (t, a, d) { return writeFile(testFile, "foo")(function () { return lstat(testFile)(function () { return t(testFile)(function () { return lstat(testFile)(a.never, function (err) { a(err.code, "ENOENT"); return t(testFile + "bla", { loose: true }).catch(a.never); }); }); }); }).done(d, d); }, Directory: function (t, a, d) { mkdir(testDir)(function () { return lstat(testDir)(function () { return t(testDir)(function () { return lstat(testDir)(a.never, function (err) { a(err.code, "ENOENT"); }); }); }); }).done(d, d); } }; medikoo-fs2-b93c977/test/rmdir-sync.js000066400000000000000000000016331466730653100176240ustar00rootroot00000000000000"use strict"; const { resolve } = require("path") , lstat = require("../lstat") , mkdir = require("../mkdir") , writeFile = require("../write-file") , pg = resolve(__dirname, "__playground") , rootPath = resolve(pg, "rmdir-sync") , nested = resolve(rootPath, "one/two/three/dir") , nested2 = resolve(rootPath, "one/four/five/six"); module.exports = function (t, a) { return Promise.all([ mkdir(nested, { intermediate: true }), mkdir(nested2, { intermediate: true }) ]) .then(() => writeFile(resolve(nested, "../foo"), "bar")) .then(() => { try { t(rootPath); throw new Error("Unexpected"); } catch (error) { a(error.code, "ENOTEMPTY", "Default on not empty"); } t(rootPath, { recursive: true, force: true }); return lstat(rootPath).then(a.never, err => { a(err.code, "ENOENT", "Recursive and forced"); }); }); }; medikoo-fs2-b93c977/test/rmdir.js000066400000000000000000000036401466730653100166520ustar00rootroot00000000000000"use strict"; const { resolve } = require("path") , lstat = require("../lstat") , mkdir = require("../mkdir") , writeFile = require("../write-file") , pg = resolve(__dirname, "__playground") , rootPath = resolve(pg, "rmdir") , nested = resolve(rootPath, "one/two/three/dir") , nested2 = resolve(rootPath, "one/four/five/six"); module.exports = function (t, a, d) { // Setup mkdir(nested, { intermediate: true })(mkdir(nested2, { intermediate: true }))(() => writeFile(resolve(nested, "../foo"), "bar") ) // Do not remove non empty (with default options) .then(() => t(rootPath)(a.never, err => { a(err.code, "ENOTEMPTY", "Default on not empty"); }) ) // Do not remove non empty (with recursive option) .then(() => t(rootPath, { recursive: true })(a.never, err => { a(err.code, "ENOTEMPTY", "Recursive not empty"); }) ) // Remove recrsively empty directories .then(() => { const path = resolve(rootPath, "one/four"); return t(path, { recursive: true })(() => lstat(path)(a.never, err => { a(err.code, "ENOENT", "Recursive on empty"); }) ); }) // Remove empty directory (with default options) .then(() => t(nested)(() => lstat(nested)(a.never, err => { a(err.code, "ENOENT", "Plain"); })) ) // Ignore not existing directory (with loose option) .then(() => t(nested, { loose: true })(res => { a(res, null, "Loose option"); }, a.never)) // Remove non empty directory without directories (with force option) .then(() => t(resolve(nested, "../"), { force: true })(() => lstat(resolve(nested, "../"))(a.never, err => { a(err.code, "ENOENT", "Forced"); }) ) ) // Remove non empty deep directory (with force and recursive option) .then(() => t(rootPath, { recursive: true, force: true })(() => lstat(rootPath)(a.never, err => { a(err.code, "ENOENT", "Recursive and forced"); }) ) ) .done(d, d); }; medikoo-fs2-b93c977/test/stat.js000066400000000000000000000004541466730653100165100ustar00rootroot00000000000000"use strict"; var resolve = require("path").resolve; module.exports = function (t, a, d) { t(__filename)(function (stats) { a(stats.isFile(), true, "Success"); return t( resolve(__dirname, "n/a") )(a.never, function (err) { a(err.code, "ENOENT", "Error"); }); }, a.never).done(d, d); }; medikoo-fs2-b93c977/test/symlink.js000066400000000000000000000035601466730653100172240ustar00rootroot00000000000000"use strict"; const { promisify } = require("deferred") , fs = require("fs") , path = require("path") , { resolve } = path , lstat = promisify(fs.lstat) , unlink = promisify(fs.unlink) , rmdir = require("../rmdir") , rootPath = resolve(__dirname, "./__playground/symlink") , base = resolve(rootPath, "from") , regular = resolve(rootPath, "foo") , deep = resolve(rootPath, "foo/bar"); module.exports = function (t) { return { Regular(a, d) { t(base, regular) .then(result => { a(result, true); return lstat(regular); }) .then(stats => { a(stats.isSymbolicLink(), true); }) .then(() => unlink(regular)) .done(d, d); }, Intermediate(a, d) { t(base, deep, { intermediate: true }) .then(result => { a(result, true); return lstat(deep); }) .then(stats => { a(stats.isSymbolicLink(), true); }) .then(() => rmdir(path.dirname(deep), { force: true })) .done(d, d); }, Loose(a, d) { t(base, regular) .then(result => { a(result, true); return lstat(regular); }) .then(stats => { a(stats.isSymbolicLink(), true); }) .then(() => t(base, regular, { loose: true })) .then(result => { a(result, false); return unlink(regular); }) .done(d, d); }, Force(a, d) { t(base, regular) .then(result => { a(result, true); return lstat(regular); }) .then(stats => { a(stats.isSymbolicLink(), true); }) .then(() => t(resolve(rootPath, "other"), regular, { force: true })) .then(result => { a(result, true); return lstat(regular); }) .then(stats => { a(stats.isSymbolicLink(), true); }) .then(() => unlink(regular)) .done(d, d); }, Error(a, d) { t(base, deep)(a.never, () => { a.ok(true, ""); }).done(d, d); } }; }; medikoo-fs2-b93c977/test/type-by-stats.js000066400000000000000000000005371466730653100202640ustar00rootroot00000000000000"use strict"; var lstat = require("fs").lstat; module.exports = function (t, a, d) { lstat(__filename, function (err, stat) { if (err) { d(err); return; } a(t(stat), "file", "File"); lstat(__dirname, function (err2, stat2) { if (err2) { d(err2); return; } a(t(stat2), "directory", "Directory"); d(); }); }); }; medikoo-fs2-b93c977/test/unlink-sync.js000066400000000000000000000006761466730653100200150ustar00rootroot00000000000000"use strict"; const lstat = require("../lstat") , writeFile = require("../write-file") , testFile = require("path").resolve(__dirname, "__playground/.unlink"); module.exports = function (t, a, d) { return writeFile( testFile, "foo" )(() => lstat(testFile)(() => { t(testFile); return lstat(testFile)(a.never, err => { a(err.code, "ENOENT"); t(`${ testFile }bla`, { loose: true }); }); }) ).done(d, d); }; medikoo-fs2-b93c977/test/unlink.js000066400000000000000000000007261466730653100170370ustar00rootroot00000000000000"use strict"; const lstat = require("../lstat") , writeFile = require("../write-file") , testFile = require("path").resolve(__dirname, "__playground/unlink"); module.exports = function (t, a, d) { return writeFile( testFile, "foo" )(() => lstat(testFile)(() => t(testFile)(() => lstat(testFile)(a.never, err => { a(err.code, "ENOENT"); return t(`${ testFile }bla`, { loose: true }).catch(a.never); }) ) ) ).done(d, d); }; medikoo-fs2-b93c977/test/watch-path.js000066400000000000000000000071661466730653100176040ustar00rootroot00000000000000"use strict"; var fs = require("fs") , resolve = require("path").resolve , deferred = require("deferred") , bufferFrom = require("../lib/buffer-from") , delay = deferred.delay , promisify = deferred.promisify , mkdir = promisify(fs.mkdir) , open = promisify(fs.open) , rename = promisify(fs.rename) , write = promisify(fs.write) , close = promisify(fs.close) , writeFile = promisify(fs.writeFile) , unlink = promisify(fs.unlink) , rmdir = promisify(fs.rmdir) , pgPath = resolve(__dirname, "./__playground/watch-path"); module.exports = function (t, a, d) { var ondirchange = [] , onfilechange = [] , DELAY = 100 , dirPath = resolve(pgPath, "tmpdir") , filePath = resolve(dirPath, "tmpfile") , watch1 , watch2; watch1 = t(dirPath); watch1.on("change", function (e) { ondirchange.push(e.type); }); watch2 = t(filePath); watch2.on("change", function (e) { onfilechange.push(e.type); }); delay(function () { return mkdir(dirPath); }, DELAY)()( delay(function () { a(String(ondirchange), "create", "Dir: Dir created"); a(String(onfilechange), "", "File: Dir created"); ondirchange = []; onfilechange = []; return writeFile(filePath, "raz"); }, DELAY) )( delay(function () { a(String(ondirchange), "modify", "Dir: File created"); a(String(onfilechange), "create", "File: File created"); ondirchange = []; onfilechange = []; return open(filePath, "a")(function (fd) { return write( fd, bufferFrom("dwatrzy"), 0, 3, null )(function () { return close(fd); }); }); }, DELAY) )( delay(function () { a(String(ondirchange), "", "Dir: File changed"); a(String(onfilechange), "modify", "File: File changed"); ondirchange = []; onfilechange = []; return rename(filePath, filePath + "r"); }, DELAY) )( delay(function () { a(String(ondirchange), "modify", "Dir: File renamed"); a(String(onfilechange), "remove", "File: File renamed"); ondirchange = []; onfilechange = []; return rename(filePath + "r", filePath); }, DELAY) )( delay(function () { a(String(ondirchange), "modify", "Dir: File renamed back"); a(String(onfilechange), "create", "File: File renamed back"); ondirchange = []; onfilechange = []; return unlink(filePath); }, DELAY) )( delay(function () { a(String(ondirchange), "modify", "Dir: File removed"); a(String(onfilechange), "remove", "File: File removed"); ondirchange = []; onfilechange = []; return rmdir(dirPath); }, DELAY) )( delay(function () { a(String(ondirchange), "remove", "Dir: Dir removed"); a(String(onfilechange), "", "File: Dir removed"); ondirchange = []; onfilechange = []; return mkdir(dirPath); }, DELAY) )( delay(function () { a(String(ondirchange), "create", "Dir: Dir created #2"); a(String(onfilechange), "", "File: Dir created #2"); ondirchange = []; onfilechange = []; return writeFile(filePath, "raz"); }, DELAY) )( delay(function () { a(String(ondirchange), "modify", "Dir: File created #2"); a(String(onfilechange), "create", "File: File created #2"); ondirchange = []; onfilechange = []; return unlink(filePath); }, DELAY) )( delay(function () { a(String(ondirchange), "modify", "Dir: File removed #2"); a(String(onfilechange), "remove", "File: File removed #2"); ondirchange = []; onfilechange = []; return rmdir(dirPath); }, DELAY) )( delay(function () { a(String(ondirchange), "remove", "Dir: Dir removed #2"); a(String(onfilechange), "", "File: Dir removed #2"); watch1.close(); watch2.close(); }, DELAY) ).done(d, d); }; medikoo-fs2-b93c977/test/watch.js000066400000000000000000000063761466730653100166540ustar00rootroot00000000000000"use strict"; var fs = require("fs") , resolve = require("path").resolve , deferred = require("deferred") , bufferFrom = require("../lib/buffer-from") , delay = deferred.delay , promisify = deferred.promisify , mkdir = promisify(fs.mkdir) , open = promisify(fs.open) , rename = promisify(fs.rename) , write = promisify(fs.write) , close = promisify(fs.close) , writeFile = promisify(fs.writeFile) , unlink = promisify(fs.unlink) , rmdir = promisify(fs.rmdir) , pgPath = resolve(__dirname, "./__playground/watch"); module.exports = function (t, a, d) { var ondirchange = 0 , onfilechange = 0 , ondirend = 0 , onfileend = 0 , w1 , w2 , w3 , w4 , DELAY = 500 , dirPath = resolve(pgPath, "tmpdir") , filePath = resolve(dirPath, "tmpfile"); a.throws(function () { t(filePath); }, "Not existing"); delay(function () { return mkdir(dirPath); }, DELAY)()( delay(function () { w1 = t(dirPath); w1.on("change", function () { ++ondirchange; }); w2 = t(dirPath); w2.on("end", function () { ++ondirend; }); }, DELAY) )(delay(function () { return writeFile(filePath, "raz"); }, DELAY))( delay(function () { a(ondirchange, 1, "Dir change: File created"); a(ondirend, 0, "Dir end: File created"); ondirchange = ondirend = 0; w3 = t(filePath); w3.on("change", function () { ++onfilechange; }); w4 = t(filePath); w4.on("end", function () { ++onfileend; }); }, DELAY) )( delay(function () { return open(filePath, "a")(function (fd) { return write( fd, bufferFrom("dwatrzy"), 0, 3, null )(function () { return close(fd); }); }); }, DELAY) )( delay(function () { a(ondirchange, 0, "Dir change: File changed"); a(ondirend, 0, "Dir end: File changed"); a(onfilechange, 1, "File change: File created"); a(onfileend, 0, "File end: File created"); ondirchange = ondirend = onfilechange = onfileend = 0; return rename(filePath, filePath + "r"); }, DELAY) )( delay(function () { a(ondirchange, 1, "Dir change: File renamed"); a(ondirend, 0, "Dir end: File renamed"); a(onfilechange, 0, "File change: File renamed"); a(onfileend, 1, "File end: File renamed"); ondirchange = ondirend = onfilechange = onfileend = 0; return rename(filePath + "r", filePath); }, DELAY) )( delay(function () { a(ondirchange, 1, "Dir change: File renamed back"); a(ondirend, 0, "Dir end: File renamed back"); a(onfilechange, 0, "File change: File renamed back"); a(onfileend, 0, "File end: File renamed back"); ondirchange = ondirend = onfilechange = onfileend = 0; return unlink(filePath); }, DELAY) )( delay(function () { a(ondirchange, 1, "Dir change: File removed"); a(ondirend, 0, "Dir end: File removed"); a(onfilechange, 0, "File change: File removed"); a(onfileend, 0, "File end: File removed"); ondirchange = ondirend = onfilechange = onfileend = 0; return rmdir(dirPath); }, DELAY) )( delay(function () { a(ondirchange, 0, "Dir change: Dir removed"); a(ondirend, 1, "Dir end: Dir removed"); a(onfilechange, 0, "File change: Dir removed"); a(onfileend, 0, "File end: Dir removed"); w1.close(); w2.close(); w3.close(); w4.close(); }, DELAY) ).done(d, d); }; medikoo-fs2-b93c977/test/write-file.js000066400000000000000000000023721466730653100176050ustar00rootroot00000000000000"use strict"; var fs = require("fs") , resolve = require("path").resolve , rmdir = require("../rmdir") , readFile = fs.readFile , unlink = fs.unlink , pgPath = resolve(__dirname, "./__playground") , overwritePath = resolve(pgPath, "write-file-test") , intermediateDirPath = resolve(pgPath, "_write-file") , intermediatePath = resolve(intermediateDirPath, "intermediate/test"); module.exports = { Overwrite: function (t, a, d) { t(overwritePath, "raz", function (err) { a(err, null, "#1"); }); t(overwritePath, "dwa", function (err) { a(err, null, "#2"); }); t(overwritePath, "trzy", function (err) { a(err, null, "#3"); readFile(overwritePath, function (err2, content) { a(String(content), "trzy", "Last written"); unlink(overwritePath, d); }); }); }, Intermediate: function (t, a, d) { t(intermediatePath, "elo", { intermediate: true }, function (err) { if (err) { d(err); return; } fs.readFile(intermediatePath, function (err2, content) { if (err2) { d(err2); return; } a(String(content), "elo", "Content"); rmdir(intermediateDirPath, { recursive: true, force: true }, d); }); }); } }; medikoo-fs2-b93c977/type-by-stats.js000066400000000000000000000007341466730653100173040ustar00rootroot00000000000000"use strict"; module.exports = function (stat) { if (stat.isFile()) { return "file"; } if (stat.isDirectory()) { return "directory"; } if (stat.isSymbolicLink && stat.isSymbolicLink()) { return "symbolicLink"; } if (stat.isSocket()) { return "socket"; } if (stat.isBlockDevice()) { return "blockDevice"; } if (stat.isCharacterDevice()) { return "characterDevice"; } if (stat.isFIFO()) { return "FIFO"; } throw new Error("Cannot detect type"); }; medikoo-fs2-b93c977/unlink-sync.js000066400000000000000000000007051466730653100170270ustar00rootroot00000000000000"use strict"; const ensureString = require("type/string/ensure") , isObject = require("type/object/is") , path = require("path") , fs = require("fs"); module.exports = (filename, options = {}) => { filename = path.resolve(ensureString(filename)); if (!isObject(options)) options = {}; try { fs.unlinkSync(filename); } catch (error) { if (error.code === "ENOENT" && options.loose) return; throw error; } }; medikoo-fs2-b93c977/unlink.js000066400000000000000000000015201466730653100160510ustar00rootroot00000000000000"use strict"; const isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , { resolve } = require("path") , original = require("fs").unlink; const unlink = function (path, options) { const def = deferred(); original(path, err => { if (err) { if (err.code === "ENOENT" && options.loose) def.resolve(); else def.reject(err); return; } def.resolve(); }); return def.promise; }; unlink.returnsPromise = true; module.exports = exports = function (path, options = {}, cb = null) { path = resolve(String(path)); if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = Object(options); } return unlink(path, options).cb(cb); }; exports.returnsPromise = true; exports.unlink = unlink; medikoo-fs2-b93c977/watch-path.js000066400000000000000000000040221466730653100166110ustar00rootroot00000000000000"use strict"; var ee = require("event-emitter") , pathUtils = require("path") , watch = require("./watch").watch; var basename = pathUtils.basename , dirname = pathUtils.dirname , join = pathUtils.join , resolve = pathUtils.resolve , Watcher; Watcher = function (path) { this.path = path; this.missing = []; this.onchange = this.onchange.bind(this); this.onremove = this.onremove.bind(this); this.up = this.up.bind(this); this.watch(); this.emitter = ee(); this.emitter.close = this.close.bind(this); return this.emitter; }; Watcher.prototype = { close: function () { this.watcher.close(); }, up: function () { var parent = dirname(this.path); if (parent === this.path) { return; } this.missing.unshift(basename(this.path)); this.path = parent; this.watch(); }, watch: function () { var watcher; try { watcher = watch(this.path); } catch (e) { this.up(); return; } this.onwatch(watcher); }, tryDown: function () { var watcher, npath; npath = join(this.path, this.missing[0]); try { watcher = watch(npath); } catch (e) { return false; } this.path = npath; this.missing.shift(); if (!this.missing.length) { this.onwatch(watcher); this.oncreate(); } else if (this.tryDown()) { watcher.close(); } else { this.onwatch(watcher); } return true; }, onwatch: function (watcher) { if (this.missing.length) { watcher.on( "change", function () { if (this.tryDown()) { watcher.close(); } }.bind(this) ); watcher.once("end", this.up); } else { watcher.on("change", this.onchange); watcher.once("end", this.onremove); } this.watcher = watcher; }, oncreate: function () { this.emitter.emit("change", { type: "create" }); }, onchange: function () { this.emitter.emit("change", { type: "modify" }); }, onremove: function () { this.emitter.emit("change", { type: "remove" }); this.up(); } }; module.exports = exports = function (path) { return new Watcher(resolve(String(path))); }; exports.WatchPath = Watcher; medikoo-fs2-b93c977/watch.js000066400000000000000000000075671466730653100157000ustar00rootroot00000000000000/* eslint max-statements: off */ "use strict"; var last = require("es5-ext/array/#/last") , remove = require("es5-ext/array/#/remove") , descHandler = require("./descriptors-handler") , resolve = require("path").resolve , watchReg = require("./lib/watch") , watchAlt = require("./lib/watch-alt") , memoizeWatcher = require("./lib/memoize-watcher") , max = Math.max , watch , compare , releaseDescs , switchToAlt , switchToReg , switchAltsToReg , onLstat , isAvail , watchers = { reg: [], alt: [] }; compare = function (watcherA, watcherB) { return watcherB.count - watcherA.count; }; isAvail = function () { return descHandler.available > 50; }; switchToAlt = function (watcher) { var closePrevious = watcher.emitter._close; remove.call(watchers.reg, watcher); try { watchAlt(watcher.path, watcher.emitter); } catch (err) { if (err.code === "ENOENT" || err.code === "DIFFTYPE") { watcher.emitter.end(err); return; } throw err; } closePrevious(); descHandler.close(); watcher.alt = true; onLstat(watcher); watchers.alt.push(watcher); watchers.alt.sort(compare); }; switchToReg = function (watcher) { var emitter = watcher.emitter, closePrevious = emitter._close; try { watchReg(watcher.path, watcher.emitter); } catch (err) { if (err.code === "EMFILE") { descHandler.limit = descHandler.taken; releaseDescs(); return; } if (err.code === "ENOENT" || err.code === "DIFFTYPE") { emitter.off("change", emitter._watchSwitchListener); delete emitter._watchSwitchListener; remove.call(watchers.alt, watcher); watcher.emitter.end(err); return; } throw err; } emitter.off("change", emitter._watchSwitchListener); delete emitter._watchSwitchListener; remove.call(watchers.alt, watcher); closePrevious(); descHandler.open(); watcher.alt = false; watchers.reg.push(watcher); watchers.reg.sort(compare); }; switchAltsToReg = function () { while (watchers.alt.length && isAvail()) { switchToReg(watchers.alt[0]); } }; releaseDescs = function () { var count = max(watchers.reg.length - (descHandler.taken - 50), 0); if (count) { watchers.reg.sort(compare).slice(-count).forEach(switchToAlt); } }; onLstat = function (watcher) { var emitter = watcher.emitter; emitter.on( "change", (emitter._watchSwitchListener = function () { var candidate; watchers.alt.sort(compare); if (watchers.alt[0] !== watcher) return; if (isAvail()) { switchAltsToReg(); } else if (watchers.reg.length) { candidate = last.call(watchers.reg.sort(compare)); if (candidate.count >= watcher.count) return; // Move last regular watcher to lstat watch switchToAlt(candidate); // Move current watcher to regular watch switchToReg(watcher); } }) ); }; watch = memoizeWatcher( function self(path) { var emitter, watcher; watcher = { path: path, count: 0 }; if (isAvail()) { try { emitter = watcher.emitter = watchReg(path); } catch (e) { if (e.code === "EMFILE") { descHandler.limit = descHandler.taken; releaseDescs(); return self(path); } throw e; } descHandler.open(); watchers.reg.push(watcher); } else { emitter = watcher.emitter = watchAlt(path); watcher.alt = true; watchers.alt.push(watcher); } emitter._close = emitter.close; emitter.close = function () { emitter._close(); remove.call(watchers[watcher.alt ? "alt" : "reg"], watcher); if (!watcher.alt) { descHandler.close(); // Switch if possible switchAltsToReg(); } }; emitter.on("end", function () { watch.clear(path); emitter.close(); }); emitter.on("change", function () { ++watcher.count; }); if (watcher.alt) { onLstat(watcher); } return emitter; }, { primitive: true } ); module.exports = exports = function (path) { return watch(resolve(String(path))); }; exports.watch = watch; medikoo-fs2-b93c977/write-file.js000066400000000000000000000062231466730653100166250ustar00rootroot00000000000000// Fs.writeFile that's safe for simultaneous calls for same file. // In such event write that is ongoing is exited and new one is initialized "use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , isString = require("es5-ext/string/is-string") , deferred = require("deferred") , fs = require("fs") , pathUtils = require("path") , bufferFrom = require("./lib/buffer-from") , mkdir = require("./mkdir").mkdir; var dirname = pathUtils.dirname , resolve = pathUtils.resolve , next , writeAll , cache = {} , _writeFile , writeFile; next = function (path, err, content, encoding, flag, mode) { var data = cache[path]; if (err) { if (!cache[path].intermediate || err.code !== "ENOENT") { delete cache[path]; data.def.reject(err); return; } mkdir(dirname(path), { intermediate: true }).cb(function (err2) { delete cache[path].intermediate; if (err2) { next(path, err2); return; } _writeFile(path, content, encoding, flag, mode); }); return; } if (data.data) { data = data.data; delete cache[path].data; _writeFile(path, data.data, data.encoding, data.flag, data.mode); } else { delete cache[path]; data.def.resolve(); } }; writeAll = function (path, fd, buffer, offset, length) { fs.write(fd, buffer, offset, length, offset, function (writeErr, written) { if (writeErr) { fs.close(fd, function () { next(path, writeErr); }); } else if (written === length || cache[path].data) { fs.close(fd, function (err) { next(path, err); }); } else { writeAll(path, fd, buffer, offset + written, length - written); } }); }; _writeFile = function (path, data, encoding, flag, mode) { if (!encoding) { encoding = "utf8"; } fs.open(path, flag || "w", mode || 438, function (openErr, fd) { if (openErr) { next(path, openErr, data, encoding, flag, mode); return; } if (cache[path].data) { fs.close(fd, function (err) { next(path, err); }); } else { var buffer; if (Buffer.isBuffer(data)) { buffer = data; } else { buffer = bufferFrom(String(data), encoding); } writeAll(path, fd, buffer, 0, buffer.length); } }); }; writeFile = function (path, data, options) { var def, encoding = options.encoding || null; if (cache[path]) { if (!cache[path].intermediate && options.intermediate) { cache[path].intermediate = true; } cache[path].data = { data: data, encoding: encoding, flag: options.flag, mode: options.mode }; def = cache[path].def; } else { def = deferred(); cache[path] = { def: def, intermediate: options.intermediate }; _writeFile(path, data, encoding, options.flag, options.mode); } return def.promise; }; writeFile.returnsPromise = true; module.exports = exports = function (path, data) { var cb, options; path = resolve(String(path)); options = arguments[2]; cb = arguments[3]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = isString(options) ? { encoding: options } : Object(options); } return writeFile(path, data, options).cb(cb); }; exports.returnsPromise = true; exports.writeFile = writeFile;