structify-project 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +38 -0
- package/dist/index.js +136 -0
- package/package.json +50 -0
- package/readme.md +125 -0
- package/tsconfig.json +11 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
8
|
+
const index_1 = require("./index");
|
|
9
|
+
// CLI args
|
|
10
|
+
const args = process.argv.slice(2);
|
|
11
|
+
const projectPath = args[0] || ".";
|
|
12
|
+
const outputBase = args[1] || "structure";
|
|
13
|
+
// Interactive prompts
|
|
14
|
+
(async () => {
|
|
15
|
+
const { format } = await inquirer_1.default.prompt([
|
|
16
|
+
{
|
|
17
|
+
type: "list",
|
|
18
|
+
name: "format",
|
|
19
|
+
message: "Choose output format:",
|
|
20
|
+
choices: ["txt", "json", "md", "yaml"],
|
|
21
|
+
default: "txt"
|
|
22
|
+
}
|
|
23
|
+
]);
|
|
24
|
+
const { nodeModules } = await inquirer_1.default.prompt([
|
|
25
|
+
{
|
|
26
|
+
type: "list",
|
|
27
|
+
name: "nodeModules",
|
|
28
|
+
message: "How should node_modules be handled?",
|
|
29
|
+
choices: [
|
|
30
|
+
{ name: "Skip (ignore completely)", value: "skip" },
|
|
31
|
+
{ name: "Name only (show folder but no contents)", value: "name" },
|
|
32
|
+
{ name: "Full (expand everything inside)", value: "full" }
|
|
33
|
+
],
|
|
34
|
+
default: "name"
|
|
35
|
+
}
|
|
36
|
+
]);
|
|
37
|
+
(0, index_1.generateStructure)(projectPath, outputBase, format, nodeModules);
|
|
38
|
+
})();
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.generateStructure = generateStructure;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const yaml_1 = __importDefault(require("yaml"));
|
|
43
|
+
/**
|
|
44
|
+
* Recursively builds a tree structure object for directories and files.
|
|
45
|
+
*/
|
|
46
|
+
function buildTreeObject(dir, nodeModulesMode = "name") {
|
|
47
|
+
const items = fs
|
|
48
|
+
.readdirSync(dir, { withFileTypes: true })
|
|
49
|
+
.sort((a, b) => Number(b.isDirectory()) - Number(a.isDirectory()));
|
|
50
|
+
return items
|
|
51
|
+
.map(item => {
|
|
52
|
+
if (item.name === "node_modules") {
|
|
53
|
+
if (nodeModulesMode === "skip")
|
|
54
|
+
return null;
|
|
55
|
+
if (nodeModulesMode === "name")
|
|
56
|
+
return { name: item.name, type: "directory" };
|
|
57
|
+
return {
|
|
58
|
+
name: item.name,
|
|
59
|
+
type: "directory",
|
|
60
|
+
children: buildTreeObject(path.join(dir, item.name), nodeModulesMode),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (item.isDirectory()) {
|
|
64
|
+
return {
|
|
65
|
+
name: item.name,
|
|
66
|
+
type: "directory",
|
|
67
|
+
children: buildTreeObject(path.join(dir, item.name), nodeModulesMode),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return { name: item.name, type: "file" };
|
|
71
|
+
})
|
|
72
|
+
.filter(Boolean);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Convert tree object to a text tree string
|
|
76
|
+
*/
|
|
77
|
+
function toTextTree(tree, prefix = "") {
|
|
78
|
+
let result = "";
|
|
79
|
+
tree.forEach((node, index) => {
|
|
80
|
+
const isLast = index === tree.length - 1;
|
|
81
|
+
const connector = isLast ? "└── " : "├── ";
|
|
82
|
+
result += `${prefix}${connector}${node.name}\n`;
|
|
83
|
+
if (node.type === "directory" && node.children) {
|
|
84
|
+
const newPrefix = prefix + (isLast ? " " : "│ ");
|
|
85
|
+
result += toTextTree(node.children, newPrefix);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Export tree in different formats
|
|
92
|
+
*/
|
|
93
|
+
function formatTree(projectName, tree, format) {
|
|
94
|
+
switch (format) {
|
|
95
|
+
case "txt":
|
|
96
|
+
return `${projectName}/\n${toTextTree(tree)}`;
|
|
97
|
+
case "json":
|
|
98
|
+
return JSON.stringify({ name: projectName, type: "directory", children: tree }, null, 2);
|
|
99
|
+
case "yaml":
|
|
100
|
+
return yaml_1.default.stringify({ name: projectName, type: "directory", children: tree });
|
|
101
|
+
case "md":
|
|
102
|
+
return treeToMarkdown(projectName, tree);
|
|
103
|
+
default:
|
|
104
|
+
return "";
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Markdown conversion
|
|
109
|
+
*/
|
|
110
|
+
function treeToMarkdown(projectName, tree, depth = 0) {
|
|
111
|
+
let md = depth === 0 ? `# Project Structure\n\n- ${projectName}/\n` : "";
|
|
112
|
+
const prefix = " ".repeat(depth + 1);
|
|
113
|
+
tree.forEach(node => {
|
|
114
|
+
md += `${prefix}- ${node.name}\n`;
|
|
115
|
+
if (node.type === "directory" && node.children) {
|
|
116
|
+
md += treeToMarkdown("", node.children, depth + 1);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
return md;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Generates a project structure file.
|
|
123
|
+
*/
|
|
124
|
+
function generateStructure(projectPath, outputFileBase, format, nodeModulesMode) {
|
|
125
|
+
const absPath = path.resolve(projectPath);
|
|
126
|
+
if (!fs.existsSync(absPath)) {
|
|
127
|
+
console.error(`❌ Path not found: ${absPath}`);
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
const projectName = path.basename(absPath);
|
|
131
|
+
const tree = buildTreeObject(absPath, nodeModulesMode);
|
|
132
|
+
const output = formatTree(projectName, tree, format);
|
|
133
|
+
const outputFile = `${outputFileBase}.${format}`;
|
|
134
|
+
fs.writeFileSync(outputFile, output, "utf-8");
|
|
135
|
+
console.log(`✅ Project structure written to ${outputFile}`);
|
|
136
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "structify-project",
|
|
3
|
+
"author": "Yashwanth Byalla",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "Interactive CLI to visualize and export project structure as text, JSON, Markdown, or YAML",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"start": "ts-node src/cli.ts",
|
|
9
|
+
"build": "tsc"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"structify-project": "dist/cli.js"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"project structure",
|
|
16
|
+
"directory tree",
|
|
17
|
+
"folder structure",
|
|
18
|
+
"codebase explorer",
|
|
19
|
+
"project map",
|
|
20
|
+
"project overview",
|
|
21
|
+
"project visualization",
|
|
22
|
+
"file tree generator",
|
|
23
|
+
"file structure",
|
|
24
|
+
"repo structure",
|
|
25
|
+
"repository explorer",
|
|
26
|
+
"project analyzer",
|
|
27
|
+
"documentation tool",
|
|
28
|
+
"code visualization",
|
|
29
|
+
"cli tool",
|
|
30
|
+
"developer tools",
|
|
31
|
+
"file system",
|
|
32
|
+
"structify project",
|
|
33
|
+
"tree view"
|
|
34
|
+
],
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"type": "commonjs",
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"fs": "^0.0.1-security",
|
|
39
|
+
"fs-extra": "^11.3.1",
|
|
40
|
+
"inquirer": "^12.9.2",
|
|
41
|
+
"path": "^0.12.7",
|
|
42
|
+
"yaml": "^2.8.1"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/inquirer": "^9.0.9",
|
|
46
|
+
"@types/node": "^24.3.0",
|
|
47
|
+
"@types/yaml": "^1.9.6",
|
|
48
|
+
"typescript": "^5.9.2"
|
|
49
|
+
}
|
|
50
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Structify Project
|
|
2
|
+
A command-line tool to **visualize and export project structures** in multiple formats (Tree, JSON, Markdown, YAML).
|
|
3
|
+
|
|
4
|
+
With **Structify Project**, you can quickly generate an overview of your project's file and folder hierarchy, making it easier to document, share, and analyze codebases.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Table of Contents
|
|
9
|
+
- [Install](#install)
|
|
10
|
+
- [Usage](#usage)
|
|
11
|
+
- [Options](#options)
|
|
12
|
+
- [Troubleshoot](#troubleshoot)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
# Install globally via NPM
|
|
20
|
+
npm install -g structify-project
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
# Run structify-project inside any project directory:
|
|
30
|
+
structify-project ./ output
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
'./' is the path to the project folder from where you want to get the structure
|
|
34
|
+
'output' can be any name with which you want to save the file
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Options with Interactive Mode
|
|
39
|
+
|
|
40
|
+
Once you run above command, You will be prompted to select output format and how to handle node_modules.
|
|
41
|
+
|
|
42
|
+
Step 1: Choose Output Format
|
|
43
|
+
You will see a menu like this:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
? Choose output format: (Use arrow keys)
|
|
47
|
+
❯ tree
|
|
48
|
+
json
|
|
49
|
+
markdown
|
|
50
|
+
yaml
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Structify Project supports multiple output formats. You can choose the one that best fits your use case.
|
|
54
|
+
|
|
55
|
+
| Format | Description |
|
|
56
|
+
|------------|-----------------------------------------------------------------------------|
|
|
57
|
+
| `tree` | Default tree-like text visualization of the project structure. |
|
|
58
|
+
| `json` | Outputs a JSON representation — great for programmatic usage and parsing. |
|
|
59
|
+
| `markdown` | Outputs a Markdown file — perfect for documentation and GitHub READMEs. |
|
|
60
|
+
| `yaml` | Outputs in YAML format — useful for configuration pipelines and tooling. |
|
|
61
|
+
|
|
62
|
+
✨ By default, Structify Project uses the **`tree`** format if no option is specified.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
Step 2: Choose Node Modules Handling
|
|
66
|
+
Next, you will be asked how to include node_modules:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
? How should node_modules be handled?
|
|
70
|
+
❯ Skip
|
|
71
|
+
Name only
|
|
72
|
+
Full
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Node Modules Handling
|
|
76
|
+
|
|
77
|
+
Structify Project gives you full control over how `node_modules` is included in the generated project structure.
|
|
78
|
+
This is useful because `node_modules` can be extremely large and often unnecessary in documentation.
|
|
79
|
+
|
|
80
|
+
| Option | Description |
|
|
81
|
+
|--------------|-----------------------------------------------------------------------------|
|
|
82
|
+
| `Skip` | Excludes `node_modules` entirely (**default**). |
|
|
83
|
+
| `Name only` | Shows just the `node_modules/` folder name, without its contents. |
|
|
84
|
+
| `Full` | Includes the **entire `node_modules` tree** (⚠️ can be very large & heavy). |
|
|
85
|
+
|
|
86
|
+
✨ Use `Skip` for cleaner outputs, `Name only` for awareness and `Full` only if you absolutely need the dependency tree.
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
✨ With these two prompts, Structify Project ensures you always generate the right format with the right level of detail for your project structure.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Troubleshoot
|
|
94
|
+
|
|
95
|
+
If Structify Project is not working as expected, here are some common issues and fixes:
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
### 1. Command Not Found
|
|
100
|
+
|
|
101
|
+
**Issue:** Running `structify-project` shows `command not found`.
|
|
102
|
+
**Fix:**
|
|
103
|
+
- Make sure you installed Structify Project globally:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npm install -g structify-project
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 2. Prompts Not Appearing (skips directly to output)
|
|
110
|
+
|
|
111
|
+
**Cause:** The CLI is likely pointing to an old build.
|
|
112
|
+
**Fix:**
|
|
113
|
+
- Ensure your src/cli.ts has the interactive code (inquirer.prompt).
|
|
114
|
+
- Rebuild your package:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npm run build
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 3. Huge Output (node_modules too large)
|
|
121
|
+
|
|
122
|
+
**Cause:** You selected --node-modules all, which includes all dependencies.
|
|
123
|
+
**Fix:**
|
|
124
|
+
- Use --node-modules skip (default) to exclude.
|
|
125
|
+
- Or --node-modules name to only show the folder.
|