{"analyzedAt":"2022-06-28T21:33:51.119Z","collected":{"metadata":{"name":"walk","scope":"unscoped","version":"2.3.15","description":"A node port of python's os.walk","keywords":["util","os","sys","fs","walk","walkSync"],"date":"2021-09-22T17:48:24.914Z","author":{"name":"AJ ONeal","email":"coolaj86@gmail.com","username":"coolaj86"},"publisher":{"username":"coolaj86","email":"coolaj86@gmail.com"},"maintainers":[{"username":"coolaj86","email":"coolaj86@gmail.com"}],"repository":{"url":"https://git.coolaj86.com/coolaj86/fs-walk.js.git"},"links":{"npm":"https://www.npmjs.com/package/walk","homepage":"https://git.coolaj86.com/coolaj86/fs-walk.js","bugs":"https://git.coolaj86.com/coolaj86/fs-walk.js/issues"},"license":"(MIT OR Apache-2.0)","dependencies":{"foreachasync":"^3.0.0"},"releases":[{"from":"2022-05-29T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":0},{"from":"2022-03-30T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":0},{"from":"2021-12-30T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":0},{"from":"2021-06-28T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":1},{"from":"2020-06-28T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":1}],"hasTestScript":true,"hasSelectiveFiles":true,"readme":"# 2021 Update\n\nConsider using [`@root/walk`](https://npmjs.org/package/@root/walk) instead.\n\nI created `walk` quite literally a decade ago, in the Node v0.x days.\nBack then using an EventEmitter seemed like the thing to do. Nowadays,\nit seems a bit overkill for the simple task of walking over directories.\n\nThere's nothing wrong with `walk` - it's about the same as it was 10 years ago -\nhowever, at only 50 lines of code long, `@root/walk` is much simpler and much faster.\n\n# node-walk\n\n| a [Root](https://rootprojects.org) project\n\nnodejs walk implementation.\n\nThis is somewhat of a port python's `os.walk`, but using Node.JS conventions.\n\n- EventEmitter\n- Asynchronous\n- Chronological (optionally)\n- Built-in flow-control\n- includes Synchronous version (same API as Asynchronous)\n\nAs few file descriptors are opened at a time as possible.\nThis is particularly well suited for single hard disks which are not flash or solid state.\n\n## Installation\n\n```bash\nnpm install --save walk\n```\n\n# Getting Started\n\n```javascript\n'use strict';\n\nvar walk = require('walk');\nvar fs = require('fs');\nvar walker;\nvar options = {};\n\nwalker = walk.walk('/tmp', options);\n\nwalker.on('file', function (root, fileStats, next) {\n  fs.readFile(fileStats.name, function () {\n    // doStuff\n    next();\n  });\n});\n\nwalker.on('errors', function (root, nodeStatsArray, next) {\n  next();\n});\n\nwalker.on('end', function () {\n  console.log('all done');\n});\n```\n\n## Common Events\n\nAll single event callbacks are in the form of `function (root, stat, next) {}`.\n\nAll multiple event callbacks callbacks are in the form of `function (root, stats, next) {}`, except **names** which is an array of strings.\n\nAll **error** event callbacks are in the form `function (root, stat/stats, next) {}`.\n**`stat.error`** contains the error.\n\n- `names`\n- `directory`\n- `directories`\n- `file`\n- `files`\n- `end`\n- `nodeError` (`stat` failed)\n- `directoryError` (`stat` succedded, but `readdir` failed)\n- `errors` (a collection of any errors encountered)\n\nA typical `stat` event looks like this:\n\n```javascript\n{ dev: 16777223,\n  mode: 33188,\n  nlink: 1,\n  uid: 501,\n  gid: 20,\n  rdev: 0,\n  blksize: 4096,\n  ino: 49868100,\n  size: 5617,\n  blocks: 16,\n  atime: Mon Jan 05 2015 18:18:10 GMT-0700 (MST),\n  mtime: Thu Sep 25 2014 21:21:28 GMT-0600 (MDT),\n  ctime: Thu Sep 25 2014 21:21:28 GMT-0600 (MDT),\n  birthtime: Thu Sep 25 2014 21:21:28 GMT-0600 (MDT),\n  name: 'README.md',\n  type: 'file' }\n```\n\n# Advanced Example\n\nBoth Asynchronous and Synchronous versions are provided.\n\n```javascript\n'use strict';\n\nvar walk = require('walk');\nvar fs = require('fs');\nvar options;\nvar walker;\n\noptions = {\n  followLinks: false,\n  // directories with these keys will be skipped\n  filters: ['Temp', '_Temp'],\n};\n\nwalker = walk.walk('/tmp', options);\n\n// OR\n// walker = walk.walkSync(\"/tmp\", options);\n\nwalker.on('names', function (root, nodeNamesArray) {\n  nodeNamesArray.sort(function (a, b) {\n    if (a > b) return 1;\n    if (a < b) return -1;\n    return 0;\n  });\n});\n\nwalker.on('directories', function (root, dirStatsArray, next) {\n  // dirStatsArray is an array of `stat` objects with the additional attributes\n  // * type\n  // * error\n  // * name\n\n  next();\n});\n\nwalker.on('file', function (root, fileStats, next) {\n  fs.readFile(fileStats.name, function () {\n    // doStuff\n    next();\n  });\n});\n\nwalker.on('errors', function (root, nodeStatsArray, next) {\n  next();\n});\n\nwalker.on('end', function () {\n  console.log('all done');\n});\n```\n\n### Sync\n\nNote: You **can't use EventEmitter** if you want truly synchronous walker\n(although it's synchronous under the hood, it appears not to be due to the use of `process.nextTick()`).\n\nInstead **you must use `options.listeners`** for truly synchronous walker.\n\nAlthough the sync version uses all of the `fs.readSync`, `fs.readdirSync`, and other sync methods,\nI don't think I can prevent the `process.nextTick()` that `EventEmitter` calls.\n\n```javascript\n(function () {\n  'use strict';\n\n  var walk = require('walk');\n  var fs = require('fs');\n  var options;\n  var walker;\n\n  // To be truly synchronous in the emitter and maintain a compatible api,\n  // the listeners must be listed before the object is created\n  options = {\n    listeners: {\n      names: function (root, nodeNamesArray) {\n        nodeNamesArray.sort(function (a, b) {\n          if (a > b) return 1;\n          if (a < b) return -1;\n          return 0;\n        });\n      },\n      directories: function (root, dirStatsArray, next) {\n        // dirStatsArray is an array of `stat` objects with the additional attributes\n        // * type\n        // * error\n        // * name\n\n        next();\n      },\n      file: function (root, fileStats, next) {\n        fs.readFile(fileStats.name, function () {\n          // doStuff\n          next();\n        });\n      },\n      errors: function (root, nodeStatsArray, next) {\n        next();\n      },\n    },\n  };\n\n  walker = walk.walkSync('/tmp', options);\n\n  console.log('all done');\n})();\n```\n\n# API\n\nEmitted Values\n\n- `on('XYZ', function(root, stats, next) {})`\n\n- `root` - the containing the files to be inspected\n- _stats[Array]_ - a single `stats` object or an array with some added attributes\n  - type - 'file', 'directory', etc\n  - error\n  - name - the name of the file, dir, etc\n- next - no more files will be read until this is called\n\nSingle Events - fired immediately\n\n- `end` - No files, dirs, etc left to inspect\n\n- `directoryError` - Error when `fstat` succeeded, but reading path failed (Probably due to permissions).\n- `nodeError` - Error `fstat` did not succeeded.\n- `node` - a `stats` object for a node of any type\n- `file` - includes links when `followLinks` is `true`\n- `directory` - **NOTE** you could get a recursive loop if `followLinks` and a directory links to its parent\n- `symbolicLink` - always empty when `followLinks` is `true`\n- `blockDevice`\n- `characterDevice`\n- `FIFO`\n- `socket`\n\nEvents with Array Arguments - fired after all files in the dir have been `stat`ed\n\n- `names` - before any `stat` takes place. Useful for sorting and filtering.\n\n  - Note: the array is an array of `string`s, not `stat` objects\n  - Note: the `next` argument is a `noop`\n\n- `errors` - errors encountered by `fs.stat` when reading ndes in a directory\n- `nodes` - an array of `stats` of any type\n- `files`\n- `directories` - modification of this array - sorting, removing, etc - affects traversal\n- `symbolicLinks`\n- `blockDevices`\n- `characterDevices`\n- `FIFOs`\n- `sockets`\n\n**Warning** beware of infinite loops when `followLinks` is true (using `walk-recurse` varient).\n\n# Comparisons\n\nTested on my `/System` containing 59,490 (+ self) directories (and lots of files).\nThe size of the text output was 6mb.\n\n`find`:\ntime bash -c \"find /System -type d | wc\"\n59491 97935 6262916\n\n    real  2m27.114s\n    user  0m1.193s\n    sys 0m14.859s\n\n`find.js`:\n\nNote that `find.js` omits the start directory\n\n    time bash -c \"node examples/find.js /System -type d | wc\"\n    59490   97934 6262908\n\n    # Test 1\n    real  2m52.273s\n    user  0m20.374s\n    sys 0m27.800s\n\n    # Test 2\n    real  2m23.725s\n    user  0m18.019s\n    sys 0m23.202s\n\n    # Test 3\n    real  2m50.077s\n    user  0m17.661s\n    sys 0m24.008s\n\nIn conclusion node.js asynchronous walk is much slower than regular \"find\".\n\n# LICENSE\n\n`node-walk` is available under the following licenses:\n\n- MIT\n- Apache 2\n\nCopyright 2011 - Present AJ ONeal"},"npm":{"downloads":[{"from":"2022-06-27T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":84593},{"from":"2022-06-21T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":462371},{"from":"2022-05-29T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":1942099},{"from":"2022-03-30T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":7326017},{"from":"2021-12-30T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":13673699},{"from":"2021-06-28T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":29814866}],"starsCount":23},"source":{"files":{"readmeSize":7396,"testsSize":0},"outdatedDependencies":{"foreachasync":{"required":"^3.0.0","stable":"5.1.3","latest":"5.1.3"}}}},"evaluation":{"quality":{"carefulness":0.7899999999999999,"tests":0,"health":0.75,"branding":0},"popularity":{"communityInterest":23,"downloadsCount":2442005.6666666665,"downloadsAcceleration":-5666.875247336382,"dependentsCount":0},"maintenance":{"releasesFrequency":0.06164383561643837,"commitsFrequency":0,"openIssues":0,"issuesDistribution":0}},"score":{"final":0.34845734088840974,"detail":{"quality":0.5148656320708163,"popularity":0.22156504063304952,"maintenance":0.33271396298742156}}}