mihneadb / node-directory-tree Goto Github PK
View Code? Open in Web Editor NEWConvert a directory tree to a JS object.
License: MIT License
Convert a directory tree to a JS object.
License: MIT License
Apologies I think this might be a limitation of Nodejs as a whole but I am trying to replace a Python script I have running on my server that writes a JSON file out of the contents of a directory. Am I wrong to believe this can be done with node?
This package gives me a lovely output, I just can't figure out how I can write that output to a file once the script has run
Thanks
Osc
Hello,
i got this error: "FS.statSync is not a function
at directoryTree (directory-tree.js?1168:57)"
upon debugging it comes from here:
function directoryTree (path, options, onEachFile, onEachDirectory) {
const name = PATH.basename(path);
path = options && options.normalizePath ? normalizePath(path) : path;
const item = { path, name };
let stats;
console.log(path);
**try { stats = FS.statSync(path); }**
catch (e) {
console.log(e);
return null; }
i guess it make sense to catch it and show?
also, any idea why i am getting it?
I am thinking about making a pr for adding some sort options ,e.g. sort by date or maybe sort by name(which most of the times happens but due to this issue it is not guaranteed to happen).After all the change will not be more than ten lines and a bit of documentation maybe something like :
try {
dirData = FS.readdirSync(path);
}
goes to :
try{
dirData=FS.readdirSync(path);
if(options.sorted==="name")
dirData.sort()
else if(options.sorted==="date")
dirData.sort(dataComparer(a,b))
}
Any thoughts?
Hi,
would it be possible to add the possibility to specify multiple excludes and extensions?
I´m currently trying to parse nodejs/typescript projects and they often contain a lot of "metadata" which I would like to ignore. For example I would like to ignore node_modules
and an output folder like dist
.
Basically make the exclude
option accept an array of regexes...
Thx
Is it possible to add the option for an id to each item?
Can this be used to load data as files enter and leave the folder?
i try to change each item with callback
return new obj or change item doesn't do anything.
return dirTree(url || process.cwd().split('/.meteor')[0], {} , (i, p) => {
return { title: i.name, ...etc }
})
Hi,
Thank you for the pretty simple plugin.
In my application, I care about the folder structure only. I therefore do not want to include the final files. Is there a easy way to select?
For example, I am now getting:
-- Folder A
-- Folder B
-- FileA.doc
...
-- Folder C
-- FileA.doc
...
While, what I want is:
-- Folder A
-- Folder B
-- Folder C
I wish to filter the files out.
Hello Mihnea,
The below code works just perfect on codesandbox, but locally on my Windows machine console.log(tree)
, always returns a null object.
https://codesandbox.io/s/yp0qv1r40x
const dirTree = require("directory-tree");
const tree = dirTree("..");
console.log(tree);
What could be the problem?
Thank you.
Cristian
It's been 4 months and lots of fixes since 1.0.0, consider publish a new release?
Hi,
This package is super useful!
Wondering if you think it might be easy to enhance this package to index a child path instead of the entire provided path?
e.g. if i store user specific documents like this:
user1/files/folderA
user2/files/folderB
var data = directoryTree(username+'/files', ['.txt']);
I want the generated directory tree to have paths as follows, without the parent path:
e.g. for user1:
'files/folderA'
NOT 'user1/files/folderA'
This is for security reasons, as i have a client-side application that receives the directory tree data, but it should never know about the existence of parent folders like user1, user2 etc.
I imagine, the new approach to provide child subpaths only would need to support a new parameter like so:
var data = directoryTree(parentPath, subPath, ['.txt']);
e.g. in my use case I would invoke as follows:
var data = directoryTree(username,'/files', ['.txt']);
I'm glad to do a PR if you think this would be a useful addition. Any pointers appreciated!
Best Regards,
-S. Arora
Hi,
I have a small problem, probably not directly related to your module, but when I delete or create a new file programmatically in the directory that node-directory-tree is fetching information from it is not updated.
First I thought that it was my Angular app that was not refreshing the view, but I get the impression that it is the node server that is not updating.
Only If I stop and start the server it will pick up the changes.
This is my little script:
app.get('/api/readtree', function(req, res) {
// we have to put the json in an array to get the right format to use in Angular tree.
var theArray = [];
theArray.push(repotree);
res.json(theArray);
console.log(theArray);
});
Is there a way to make the server unlock from the file system without a restart?
It would be cool to have date
property as well. mtime
will be best choice I think.
I want to try and eliminate the empty folders from the output, the ones that don't have any children not just directly inside but also in their children and the children of their children.
basically if
Folder A has no children, I don't want to see it in the output.
if Folder A has Folder B and Folder C as children, and both of them have no children, I want folder A to be emitted from the output.
IS there anyway that is already built in your library, a small hack maybe ? that can help me do this ?
does the folder callback handle this case ?
"exlusion" → "exclusion".
Thanks for directory-tree!
directoryTree(".", {}, (_item, path) => {
console.log(path);
});
When you run this code, you get this value instead of the path string, which is the path module:
{
resolve: [Function: resolve],
normalize: [Function: normalize],
isAbsolute: [Function: isAbsolute],
join: [Function: join],
relative: [Function: relative],
toNamespacedPath: [Function: toNamespacedPath],
dirname: [Function: dirname],
basename: [Function: basename],
extname: [Function: extname],
format: [Function: bound _format],
parse: [Function: parse],
sep: '\\',
delimiter: ';',
win32: [Circular *1],
posix: <ref *2> {
resolve: [Function: resolve],
normalize: [Function: normalize],
isAbsolute: [Function: isAbsolute],
join: [Function: join],
relative: [Function: relative],
toNamespacedPath: [Function: toNamespacedPath],
dirname: [Function: dirname],
basename: [Function: basename],
extname: [Function: extname],
format: [Function: bound _format],
parse: [Function: parse],
sep: '/',
delimiter: ':',
win32: [Circular *1],
posix: [Circular *2],
_makeLong: [Function: toNamespacedPath]
},
_makeLong: [Function: toNamespacedPath]
}
Thanks for this good package!
In a directory, I only want first 10 files then what can i do for that?
@mihneadb Has anyone used this with a gruntfile to read the contents of a folder, then inject the results into a javascript file?
Thanks for creating this package which works great!
Is a search-function in the pipeline?
Could be something like this:
.search("search_for_this_string", nodeArray[]): nodes[]
This plugin is super use full. Is there a way to pass excludes to the plugin as well?
Thanks.
Don't forget to integrate in PR checks.
would love to see typescript types for this on DefinitelyTyped so you can do npm install @types/directory-tree
.
If I end up adding them for my project, I will try to publish them
Hey @mihneadb , I've been trying to order the resulting JSON the way Windows Explorer does - folders first.
Is there any way you can help me with it? Haven't been successful yet.
Hi, I am trying to use the directory-tree module, but the function is returning null.
What am I doing wrong here? Do I need specific modules installed?
Code example:
import React, { Component } from 'react';
import directoryTree from 'directory-tree';
import _ from 'lodash';
let tree = directoryTree("C:/Users/Daniel Varzim/Desktop/Apps");
class Dummy extends Component {
render() {
console.log(tree)
return (
renderTree(tree) {
return _.map(tree, app => {
return (
<tr>
<th>
{app.name}
</th>
</tr>
)
});
}
}
export default Dummy;
Hi,
Thanks for this nice package. I have a improvement proposal and I wanted to discuss it here before making a PR :
To know if an object refer to a file or a directory, it's necessary to test if the key extension
exists.
extension
is the value returned by path.extname and if the file doesn't have extension, an empty string is return.
It means the correct condition to know if an object refer to a file is typeof(obj.extension) === 'string'
It's also possible to write obj.extension !== undefined
or obj.extension || obj.extension === ''
or Object.keys(obj).includes('extension')
but it's not really nice.
Unfortunately, I don't think everybody will matter what happen when a file doesn't have extension and most people will probably just write obj.extension
, witch is correct but not for all cases.
I'd like to add a explicit Boolean index such a obj.isFile
. What's do you think about it ?
[ ] bug
[x] feature request
NodeJS has support to get time modified of an file. Here is an example on how to do it.
fs.stat("/dir/file.txt", function(err, stats){
var mtime = new Date(util.inspect(stats.mtime));
console.log(mtime);
});
Can you consider put this feature to node-directory-tree?
Hi, really thanks for good library.
When testing onEachDirectory callback, it only returns top level directory.
I tested on nodejs v10, directory-tree v2.2.0, installed via npm.
I think onEachDirectory callback parameter is missing when calling directoryTree recursively.
node-directory-tree/lib/directory-tree.js
Line 99 in 5f2db29
I just found this thing.
Does it read all folders and their children or just the folders in the current dir?
Let's say I use this thing to build a browser similar to Windows Explorer, then it would take a long time to get everything in C:/ for example, if it's nested.
Hi, I just want to request a new feature if possible. I know the plugin sort the JSON data with alphabetical order. I think it would be nice if can sort with alphabetical order plus sort it with file type. :D
Thx!
Hi guys,
First of all thank you for your job, I currently am using your library and it's pretty powerfull.
I'm just wondering if there would be a way to handle permission errors with it ? (would be awesome)
Thanks for your reply,
Cheers !
Would you consider adding the resut of callback function to the item?
Patch would be trivial, something along the lines
- onEachFile(item, PATH);
+ const results = onEachFile(item, PATH);
+ if (results !== undefined)
+ item.data = results;
Hi!
Is it possible to include,
/*if (item.children.length == 0) {
return null;
}*/
I'm on macOs, node v12, directory-tree v2.2.4...
When I try to create a directory tree by excluding the .git folder:
const tree = dirTree(rootPath, { exclude: [/.git/] }); console.log('tree is ', tree)
I get:
tree is null
But when I specify an absolute path to the .git folder:
const tree = dirTree(rootPath, { exclude: [/\/absolute-path-to-folder\/.git/] }); console.log('tree is ', tree)
I get:
tree is Object{...}
I'd like to exclude all .git folders (without having to specify the absolute path to them).
Has anyone else encountered this? Am I using exclude incorrectly (exclude does work as expected on any other folders starting with ' . ' just not '.git')?
How can you return just the directories?
Hi. I have a problem with the default sorted [ tree.children ] array.
Can you make that default so it puts the directories at the top and sorted alphabetically?
That's how tree views are sorted by default by most file viewers.
Right now i get a mixed [ tree.children ] array result.
Directories mixed with files.
Like this ...
/RootDir/
* afile.js
* animage.png
* apples.txt
/ DirC
* fileFoo.txt
/ SomeDirB
{
"path" : "./RootDir/",
"name" : "RootDir",
"children" : [
{
"path" : "RootDir/afile.js",
"name" : "afile.js",
"size" : 723,
"extension" : ".js"
}, {
"path" : "RootDir/animage.png",
"name" : "animage.png",
"size" : 32917,
"extension" : ".png"
}, {
"path" : "RootDir/apples.txt",
"name" : "apples.txt",
"size" : 4459,
"extension" : ".txt"
}, {
"path" : "RootDir/DirC", // Directory should be at the top ^
"name" : "DirC",
"children" : [...],
"size" : 36278
}, {
"path" : "RootDir/fileFoo.txt",
"name" : "fileFoo.txt",
"size" : 1527,
"extension" : ".txt"
}, {
"path" : "RootDir/SomeDirB", // Directory should be at the top ^
"name" : "SomeDirB",
"children" : [...],
"size" : 13028
}
]
}
/*
For a fix i have to sort the [ tree.childen ] array like this to get correct result
*/
const dirTree = require('directory-tree');
const _ = require("lodash");
const tree = dirTree('./RootDir');
// Put directories at the top
const sortFoldersToTop = (tree) => {
if (tree.children) {
// This is a directory
tree["children"] = _.orderBy(tree.children, ['children'], ['asc']);
tree["foldername"] = tree.name;
tree.children.forEach(child => {
sortFoldersToTop(child);
});
}
return tree;
}
// Sort directories alphabetically
const sortFoldersByName = (tree) => {
if (tree.children) {
// This is a directory
tree["children"] = _.orderBy(tree.children, ['foldername'], ['asc']);
tree.children.forEach(child => {
sortFoldersByName(child);
});
}
return tree;
}
const getSortedTree = (tree) => {
let sortedTree = sortFoldersToTop(tree);
let newTree = sortFoldersByName(sortedTree);
return newTree;
}
console.log(JSON.stringify(getSortedTree(tree), null, 4));
// Result
{
"path" : "./RootDir/",
"name" : "RootDir",
"children" : [
{
"path" : "RootDir/DirC", // <-- Correct Place
"name" : "DirC",
"children" : [...],
"size" : 36278
}, {
"path" : "RootDir/SomeDirB", // <-- Correct Place
"name" : "SomeDirB",
"children" : [...],
"size" : 13028
}, {
"path" : "RootDir/afile.js",
"name" : "afile.js",
"size" : 723,
"extension" : ".js"
}, {
"path" : "RootDir/animage.png",
"name" : "animage.png",
"size" : 32917,
"extension" : ".png"
}, {
"path" : "RootDir/apples.txt",
"name" : "apples.txt",
"size" : 4459,
"extension" : ".txt"
}, {
"path" : "RootDir/fileFoo.txt",
"name" : "fileFoo.txt",
"size" : 1527,
"extension" : ".txt"
}
]
}
You might want to check this line. I think you meant path
instead of PATH
.
node-directory-tree/lib/directory-tree.js
Line 87 in f08b2b2
I always hear that synchronous I / O operations is bad to use in production environments. How difficult is it to make the module asynchronous?
The order of the file tree is a problem with asynchronous listing, but it is possible to arrange the order with array sorting.
Which would be the best approach to avoid reading dot files?
Can I use the filter for that and if, how do I use it for that?
First I thought it was because I used the dotenv module that it read the dot files, but now when I have changed how the express app is reading its initial configuration and removed dotenv node.directory-tree is still reading dot files.
I am developing on a Mac so this could be OSX related when I get a .DS_Store file in the tree. I have left to test it in my Linux dev server to see if I get rid of this problem.
Hey i update the package from now on i get
TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export.
in Typescript could you please fix that ?
my tsconfig :
"compilerOptions": {
"outDir": "./dist/",
"noImplicitAny": false,
"noUnusedLocals": true,
"sourceMap": true,
"rootDir": "./src",
"module": "commonjs",
"moduleResolution": "node",
"types": ["node"],
"target": "es6",
"allowJs": true,
"newLine": "LF"
},
"include": ["src/**/*.ts"],
"exclude": ["src/**/*.d.ts"]
}
my typescript version :
"dependencies": {
"typescript": {
"version": "2.9.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz",
"integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==",
"dev": true
}
}
Not an issue, more a thanks kinda issue :)
I'm building something in React using your library and I'd like to share an usage example:
import React from "react";
import ReactDOM from "react-dom";
import FILETREE from "./tree";
import "./styles.css";
class App extends React.Component {
isDirectory(tree) {
return tree.type === "directory" && tree.hasOwnProperty("children");
}
renderFileTree(tree, depth = 0) {
const backgroundColor = `rgba(0, 0, 0, ${(depth + 1) * 5 / 100})`;
const isRoot = depth === 0;
return (
<div
className={`${isRoot ? "root" : "subtree"}`}
style={{ backgroundColor }}
>
{[
<code>{tree.name}</code>,
this.isDirectory(tree) &&
tree["children"].map(subtree =>
this.renderFileTree(subtree, depth + 1)
)
]}
</div>
);
}
render() {
return <div className="App">{this.renderFileTree(FILETREE)}</div>;
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
You can play around on codesandbox.
Thanks @mihneadb
Has anyone seen this bug where the name doesn't match the path?
{
path: 'foo/bar',
name: 'baz',
}
I am using the latest version and it happens only for one directory, everything else seems to work fine. It is possible that the dir got renamed at some point from foo/baz to bar. Not sure why it is not picking this up.
Right now the latest version on NPM is 2.0.0 and am hoping to utilize version 2.1.0.
Thanks
and option to sort by newest/oldest?
On my Windows, the npm run test
failed, because file size does not match.
Have you ever needed to sort the tree ? By size for example ?
How would you go about it ?
add depth option please
Case of: a directory containing three empty subdirectories:
/home/ubuntu/workspace/temp/
---my_dir_1
---my_dir_2
---my_dir_3
directory-tree returns 'null' for /home/ubuntu/workspace/temp/ but as soon as I place a file called 'wibble' into a sub-directory of /home/ubuntu/workspace/temp/ I get an object back containing properties of the file in that directory only - nothing about the other empty directories.
{
"path": "/home/ubuntu/workspace/temp",
"name": "temp",
"children": [
{
"path": "/home/ubuntu/workspace/temp/my_dir_1",
"name": "my_dir_1",
"children": [
{
"path": "/home/ubuntu/workspace/temp/my_dir_1/wibble",
"name": "wibble",
"size": 0,
"extension": ""
}
],
"size": 0
}
],
"size": 0
}
Is this expected behavior?
I kind of imagined the returned object would contain details of the empty sub directories with no information on files inside them, because there aren't any.
Thanks,
Steve
Hi, thanks for writing this lib!
Is it possible generate a tree of folders only? e.g. instead of:
photos
├── summer
│ └── june
│ └── windsurf.jpg
└── winter
└── january
├── ski.png
└── snowboard.jpg
we get this:
photos
├── summer
│ └── june
└── winter
└── january
{
"path": "photos",
"name": "photos",
"size": 600,
"type": "directory",
"children": [
{
"path": "photos/summer",
"name": "summer",
"size": 400,
"type": "directory",
"children": [
{
"path": "photos/summer/june",
"name": "june",
"size": 400,
"type": "directory",
}
]
},
{
"path": "photos/winter",
"name": "winter",
"size": 200,
"type": "directory",
"children": [
{
"path": "photos/winter/january",
"name": "january",
"size": 200,
"type": "directory",
}
]
}
]
}
Current default output includes type
, size
, and extension
. It is impossible to remove these attributes, though they are cluttering the JSON since they are unnecessary for my purposes.
const output = dirTree(
mypath,
{attributes: ["extension", "type", "size"]}
);
By adding those three attributes to the call, it does the following:
extension
from filestype
from filestype
for directoriessize
for directoriessize
on filesThis is very inconsistent behavior so I'm unsure how to proceed.
Thanks in advance.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.