Skip to content

Commit d5031f5

Browse files
committed
feat(core): implement Deno Tree file generator with complete API 🌳
- Add complete documentation with examples and API reference - Add Tree class with clear(), generate(), init(), remove(), set() methods - Implement file metadata collection and tree formatting - Implement singleton pattern for global tree instance - Include performance optimizations with ignoreDirs, maxDepth, maxFiles - Support directory ignoring and hidden file filtering
0 parents  commit d5031f5

File tree

8 files changed

+724
-0
lines changed

8 files changed

+724
-0
lines changed

.github/workflows/publish.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Publish
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
jobs:
9+
publish:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: read
13+
id-token: write
14+
15+
steps:
16+
- uses: actions/checkout@v4
17+
- uses: denoland/setup-deno@v2
18+
with:
19+
deno-version: v2.5.4
20+
21+
- name: Run lint and check
22+
run: deno lint src/ && deno check src/
23+
24+
- name: Publish package
25+
run: deno publish

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Deno
2+
.deno/
3+
deno.lock
4+
5+
# IDE
6+
.vscode/
7+
.idea/
8+
9+
# OS
10+
.DS_Store
11+
Thumbs.db

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 NeaByteLab
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
# Deno Tree [![Deno](https://img.shields.io/badge/Deno-2.5.4-blue)](https://deno.land) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
2+
3+
A file tree generator for Deno. Generate beautiful directory trees instantly from a single scan.
4+
5+
## Table of Contents
6+
7+
- [Installation](#installation)
8+
- [Quick Start](#quick-start)
9+
- [Configuration](#configuration)
10+
- [Tree Options](#tree-options)
11+
- [Performance Settings](#performance-settings)
12+
- [Basic Usage](#basic-usage)
13+
- [Simple Tree Generation](#simple-tree-generation)
14+
- [Multiple Tree Generation](#multiple-tree-generation)
15+
- [Promise Chain Style](#promise-chain-style)
16+
- [File Management](#file-management)
17+
- [Project Switching](#project-switching)
18+
- [API Reference](#api-reference)
19+
- [Main API](#main-api)
20+
- [Configuration Options](#configuration-options)
21+
- [File Metadata](#file-metadata)
22+
- [Troubleshooting](#troubleshooting)
23+
- [Common Issues](#common-issues)
24+
- [Debug Mode](#debug-mode)
25+
- [Contributing](#contributing)
26+
- [License](#license)
27+
28+
## Installation
29+
30+
```bash
31+
deno install @neabyte/deno-tree
32+
```
33+
34+
## Quick Start
35+
36+
```ts
37+
import tree from '@neabyte/deno-tree'
38+
39+
// Initialize with a directory
40+
await tree.init('/path/to/directory', {
41+
ignoreDirs: ['node_modules', '.git', 'dist'],
42+
maxFiles: 1000,
43+
showHidden: false,
44+
maxDepth: 3
45+
})
46+
47+
// Generate tree for the entire directory
48+
const result = await tree.generate('/path/to/directory')
49+
console.log(result)
50+
```
51+
52+
**Example Output:**
53+
54+
```
55+
.
56+
├── src/
57+
│ ├── components/
58+
│ │ ├── Button.tsx
59+
│ │ └── Modal.tsx
60+
│ ├── utils/
61+
│ │ └── helpers.ts
62+
│ └── index.ts
63+
├── tests/
64+
│ └── components.test.ts
65+
├── deno.json
66+
└── README.md
67+
```
68+
69+
## Configuration
70+
71+
### Tree Options
72+
73+
```ts
74+
interface TreeOptions {
75+
ignoreDirs?: string[] // Directories to ignore (default: [])
76+
maxFiles?: number // Maximum files to process (default: unlimited)
77+
showHidden?: boolean // Show hidden files/directories (default: false)
78+
maxDepth?: number // Maximum directory depth (default: unlimited)
79+
}
80+
```
81+
82+
### Performance Settings
83+
84+
```ts
85+
// For large directories - limit files and depth
86+
{
87+
maxFiles: 5000,
88+
maxDepth: 4,
89+
ignoreDirs: ['node_modules', '.git', 'dist', 'build', 'coverage']
90+
}
91+
92+
// For quick overview - shallow scan
93+
{
94+
maxFiles: 100,
95+
maxDepth: 2,
96+
showHidden: false
97+
}
98+
99+
// For complete scan - no limits
100+
{
101+
showHidden: true
102+
// No maxFiles or maxDepth limits
103+
}
104+
```
105+
106+
## Basic Usage
107+
108+
### Simple Tree Generation
109+
110+
```ts
111+
import tree from '@neabyte/deno-tree'
112+
113+
// Basic tree generation
114+
await tree.init('/path/to/project')
115+
const result = await tree.generate('/path/to/project')
116+
console.log(result)
117+
```
118+
119+
### Multiple Tree Generation
120+
121+
```ts
122+
import tree from '@neabyte/deno-tree'
123+
124+
// Scan parent directory once
125+
await tree.init('/workspace', {
126+
ignoreDirs: ['node_modules', '.git', 'dist'],
127+
maxFiles: 2000,
128+
showHidden: false,
129+
maxDepth: 2
130+
})
131+
132+
// Generate trees for multiple projects
133+
const projectA = await tree.generate('/workspace/project-a')
134+
const projectB = await tree.generate('/workspace/project-b')
135+
const projectC = await tree.generate('/workspace/project-c')
136+
137+
console.log('Project A Tree:', projectA)
138+
console.log('Project B Tree:', projectB)
139+
console.log('Project C Tree:', projectC)
140+
```
141+
142+
### Promise Chain Style
143+
144+
```ts
145+
import tree from '@neabyte/deno-tree'
146+
147+
tree
148+
.init('/path/to/project', {
149+
ignoreDirs: ['node_modules', '.git'],
150+
maxFiles: 500,
151+
showHidden: false,
152+
maxDepth: 2
153+
})
154+
.then(async () => {
155+
const result = await tree.generate('/path/to/project')
156+
console.log(result)
157+
})
158+
.catch((error) => {
159+
console.error(error)
160+
})
161+
```
162+
163+
### File Management
164+
165+
```ts
166+
import tree from '@neabyte/deno-tree'
167+
168+
// Add individual files to the tree
169+
await tree.set('/path/to/file.txt')
170+
await tree.set('/path/to/another-file.js')
171+
172+
// Remove files when they're deleted
173+
await tree.remove('/path/to/deleted-file.txt')
174+
await tree.remove('/path/to/deleted-directory')
175+
176+
// Clear all files and reset state
177+
tree.clear()
178+
179+
// Generate tree with updated metadata
180+
const result = await tree.generate('/path/to/directory')
181+
console.log(result)
182+
```
183+
184+
### Project Switching
185+
186+
```ts
187+
import tree from '@neabyte/deno-tree'
188+
189+
// Work with multiple projects
190+
await tree.init('/workspace/project-a', { maxFiles: 1000 })
191+
const treeA = await tree.generate('/workspace/project-a')
192+
console.log('Project A:', treeA)
193+
194+
// Clear and switch to different project
195+
tree.clear()
196+
await tree.init('/workspace/project-b', { maxFiles: 2000 })
197+
const treeB = await tree.generate('/workspace/project-b')
198+
console.log('Project B:', treeB)
199+
```
200+
201+
## API Reference
202+
203+
### Main API
204+
205+
| Method | Description | Parameters | Returns |
206+
| ------------ | -------------------------------------- | ------------------------------------- | ----------------- |
207+
| `clear()` | Clear all stored file metadata | None | `void` |
208+
| `generate()` | Generate formatted tree string | `rootPath: string` | `Promise<string>` |
209+
| `init()` | Scan directory and store file metadata | `path: string, options?: TreeOptions` | `Promise<void>` |
210+
| `remove()` | Remove file/directory from tree | `path: string` | `Promise<void>` |
211+
| `set()` | Add single file to tree metadata | `path: string` | `Promise<void>` |
212+
213+
### Configuration Options
214+
215+
| Property | Type | Required | Description | Example |
216+
| ------------ | -------- | -------- | ----------------------------- | -------------------------- |
217+
| `ignoreDirs` | string[] || Directories to ignore | `['node_modules', '.git']` |
218+
| `maxFiles` | number || Maximum files to process | `1000` |
219+
| `showHidden` | boolean || Show hidden files/directories | `false` |
220+
| `maxDepth` | number || Maximum directory depth | `3` |
221+
222+
### File Metadata
223+
224+
```ts
225+
interface FileMetadata {
226+
name: string // File name
227+
path: string // Full file path
228+
type: 'file' | 'directory' // File type
229+
parent?: string // Parent directory path
230+
size?: number // File size in bytes
231+
modified?: Date // Last modified date
232+
extension?: string // File extension
233+
}
234+
```
235+
236+
## Troubleshooting
237+
238+
### Common Issues
239+
240+
**Empty Tree Output**
241+
242+
- Verify the path exists and is accessible
243+
- Check if `maxFiles` limit was reached before scanning the target directory
244+
- Ensure `maxDepth` allows reaching the target directory
245+
246+
**Memory Issues**
247+
248+
- Reduce `maxFiles` limit for large directories
249+
- Use `maxDepth` to limit scanning depth
250+
- Add more directories to `ignoreDirs`
251+
252+
**Slow Performance**
253+
254+
- Increase `maxFiles` limit if hitting the cap too early
255+
- Reduce `maxDepth` for shallow scans
256+
- Add common build directories to `ignoreDirs`
257+
258+
### Debug Mode
259+
260+
```ts
261+
import tree from '@neabyte/deno-tree'
262+
263+
// Debug file storage
264+
await tree.init('/path/to/project', { maxFiles: 100 })
265+
console.log('Files stored:', tree.files.size)
266+
267+
// Debug specific path generation
268+
const result = await tree.generate('/path/to/project/src')
269+
console.log('Generated tree length:', result.length)
270+
console.log('Tree output:', result)
271+
```
272+
273+
## Contributing
274+
275+
Contributions are welcome! Please feel free to submit a [Pull Request](https://github.com/NeaByteLab/Deno-Tree/pulls).
276+
277+
## License
278+
279+
This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for more info.

0 commit comments

Comments
 (0)