├── LICENSE.md ├── README.md ├── index.js └── package.json /LICENSE.md: -------------------------------------------------------------------------------- 1 | This software is released under the MIT license: 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # file-tree # 2 | 3 | A more flexible, asynchronous version of 4 | [file-size-tree](http://github.com/hughsk/file-size-tree). 5 | 6 | ## Installation ## 7 | 8 | ``` bash 9 | npm install file-tree 10 | ``` 11 | 12 | ## Usage ## 13 | 14 | ### `require('file-tree')(files, mapper, callback)` ### 15 | 16 | Takes an array of `files`. 17 | 18 | `mapper(filename, next)` should pass an object to the the callback 19 | with the metadata you want to associate with the file. 20 | 21 | `callback(err, tree)` is called when everything's done. 22 | 23 | ``` javascript 24 | var tree = require('file-tree') 25 | var fs = require('fs') 26 | 27 | tree([ 28 | __dirname + '/project/src/index.js' 29 | , __dirname + '/project/src/README.md' 30 | , __dirname + '/project/src/package.json' 31 | , __dirname + '/LICENSE' 32 | ], function(filename, next) { 33 | fs.stat(filename, function(err, stats) { 34 | if (err) return next(err) 35 | next(null, { 36 | size: stats.size 37 | }) 38 | }) 39 | }, function(err, fileTree) { 40 | console.log(fileTree) // done! 41 | }) 42 | ``` 43 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var commondir = require('commondir') 2 | var reduce = require('async-reduce') 3 | var path = require('path') 4 | var flat = require('flat') 5 | 6 | module.exports = tree 7 | 8 | function tree(filenames, mapper, callback) { 9 | filenames = filenames.map(resolve) 10 | 11 | var top = commondir(filenames) 12 | 13 | reduce(filenames, {}, function(memo, name, next) { 14 | var key = path.relative(top, name) 15 | mapper(name, function(err, result) { 16 | if (err) return next(err) 17 | result.__deepest_node__ = true 18 | memo[key] = result 19 | return next(null, memo) 20 | }) 21 | }, function(err, object) { 22 | if (err) return callback(err) 23 | 24 | object = flat.unflatten(object, { delimiter: path.sep }) 25 | 26 | callback(null, clean(reformat(object, 'name'))) 27 | }) 28 | } 29 | 30 | function reformat(object, namekey) { 31 | if (typeof object !== 'object') return object 32 | if (object.__deepest_node__) return object 33 | 34 | var entries = [] 35 | var result 36 | var entry 37 | 38 | for (var key in object) { 39 | var entry = reformat(object[key], namekey) 40 | if (entry.__deepest_node__) { 41 | entry[namekey] = key 42 | entries.push(entry) 43 | } else { 44 | entry = { children: entry } 45 | entry[namekey] = key 46 | entries.push(entry) 47 | } 48 | } 49 | 50 | return entries 51 | } 52 | 53 | function clean(object) { 54 | if (typeof object !== 'object') return object 55 | delete object.__deepest_node__ 56 | for (var key in object) { 57 | clean(object[key]) 58 | } 59 | return object 60 | } 61 | 62 | function resolve(file) { 63 | return path.resolve(file) 64 | } 65 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-tree", 3 | "version": "1.0.0", 4 | "description": "Generate a tree of file metadata that matches d3's hierarchy layout format", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git://github.com/hughsk/file-tree.git" 12 | }, 13 | "keywords": [ 14 | "hierarchy", 15 | "children", 16 | "tree", 17 | "file", 18 | "metadata", 19 | "d3" 20 | ], 21 | "author": "Hugh Kennedy (http://hughskennedy.com/)", 22 | "license": "MIT", 23 | "readmeFilename": "README.md", 24 | "dependencies": { 25 | "async-reduce": "0.0.1", 26 | "commondir": "0.0.1", 27 | "flat": "~1.0.0" 28 | } 29 | } 30 | --------------------------------------------------------------------------------