folder-generator 1.3.9 → 3.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/bin/cli.js CHANGED
@@ -1,6 +1,5 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
  const fs = require('fs');
3
- const path = require('path');
4
3
  const chalk = require('chalk');
5
4
  const { parseStructure, createFiles } = require('../lib/generator');
6
5
  const yargs = require('yargs/yargs');
@@ -27,23 +26,18 @@ async function main() {
27
26
  if (argv.file) {
28
27
  try {
29
28
  input = fs.readFileSync(argv.file, 'utf8');
30
- } catch (err) {
29
+ } catch {
31
30
  console.error(chalk.red(`Error reading file: ${argv.file}`));
32
31
  process.exit(1);
33
32
  }
34
33
  } else if (argv.input) {
35
34
  input = argv.input;
36
35
  } else if (!process.stdin.isTTY) {
37
- // Read from stdin if piped
38
36
  const chunks = [];
39
37
  for await (const chunk of process.stdin) chunks.push(chunk);
40
38
  input = Buffer.concat(chunks).toString('utf8');
41
39
  } else {
42
40
  console.error(chalk.red('Error: No input provided'));
43
- console.log(chalk.yellow('Usage:'));
44
- console.log(chalk.yellow(' foldgen --input "your/structure"'));
45
- console.log(chalk.yellow(' foldgen --file structure.txt'));
46
- console.log(chalk.yellow(' echo "structure" | foldgen'));
47
41
  process.exit(1);
48
42
  }
49
43
 
@@ -51,11 +45,11 @@ async function main() {
51
45
  console.log(chalk.yellow('\nParsing structure...'));
52
46
  const structure = parseStructure(input);
53
47
  createFiles(structure);
54
- console.log(chalk.bold.green('\n✔ Folder structure created successfully!'));
55
- } catch (error) {
56
- console.error(chalk.red('\n✖ Error creating structure:'), error.message);
48
+ console.log(chalk.green.bold('\n✔ Folder structure created successfully!\n'));
49
+ } catch (err) {
50
+ console.error(chalk.red('\n✖ Error:'), err.message);
57
51
  process.exit(1);
58
52
  }
59
53
  }
60
54
 
61
- main();
55
+ main();
package/lib/generator.js CHANGED
@@ -2,25 +2,46 @@ const fs = require('fs');
2
2
  const path = require('path');
3
3
  const chalk = require('chalk');
4
4
 
5
+ /**
6
+ * Entry point parser
7
+ * Automatically detects tree-format vs indented-path format
8
+ */
5
9
  function parseStructure(text) {
10
+ if (text.includes('├──') || text.includes('└──')) {
11
+ return parseTreeFormat(text);
12
+ }
13
+ return parseIndentedPathFormat(text);
14
+ }
15
+
16
+ /**
17
+ * =========================
18
+ * TREE FORMAT PARSER (OLD)
19
+ * =========================
20
+ * Supports:
21
+ * ├── backend/
22
+ * │ └── main.go
23
+ */
24
+ function parseTreeFormat(text) {
6
25
  const lines = text.split('\n').filter(line => line.trim());
7
- const root = { name: '', children: [] };
26
+ const root = { name: '', children: [], isDirectory: true };
8
27
  let stack = [{ node: root, depth: -1 }];
9
28
 
10
29
  for (const line of lines) {
11
- // Calculate depth based on leading whitespace
12
30
  const depth = (line.match(/^[ │├└─]*/)[0].length) / 4;
13
- const name = line.replace(/^[ │├└─]*/, '').trim();
14
31
 
32
+ let name = line.replace(/^[ │├└─]*/, '').split('//')[0].trim();
15
33
  if (!name) continue;
16
34
 
17
- // Find correct parent
35
+ const isDirectory = name.endsWith('/');
36
+ if (isDirectory) name = name.slice(0, -1);
37
+
18
38
  while (depth <= stack[stack.length - 1].depth) {
19
39
  stack.pop();
20
40
  }
21
41
 
22
42
  const parent = stack[stack.length - 1].node;
23
- const newNode = { name, children: [] };
43
+ const newNode = { name, children: [], isDirectory };
44
+
24
45
  parent.children.push(newNode);
25
46
  stack.push({ node: newNode, depth });
26
47
  }
@@ -28,26 +49,88 @@ function parseStructure(text) {
28
49
  return root;
29
50
  }
30
51
 
52
+ /**
53
+ * =====================================
54
+ * INDENTED + PATH FORMAT PARSER (NEW)
55
+ * =====================================
56
+ * Supports:
57
+ *
58
+ * backend/
59
+ * cmd/server/main.go
60
+ * internal/config/config.go
61
+ */
62
+ function parseIndentedPathFormat(text) {
63
+ const lines = text.split('\n').filter(line => line.trim());
64
+ const root = { name: '', children: [], isDirectory: true };
65
+ const stack = [{ node: root, indent: -1 }];
66
+
67
+ for (const line of lines) {
68
+ const indent = line.match(/^\s*/)[0].length;
69
+ const raw = line.trim();
70
+ const isExplicitDir = raw.endsWith('/');
71
+
72
+ const trimmed = raw.replace(/\/$/, '');
73
+
74
+ while (stack.length && indent <= stack[stack.length - 1].indent) {
75
+ stack.pop();
76
+ }
77
+
78
+ let parent = stack[stack.length - 1].node;
79
+ const parts = trimmed.split('/');
80
+
81
+ parts.forEach((part, index) => {
82
+ const isLast = index === parts.length - 1;
83
+
84
+ // ✅ FIX: directory only if NOT last OR explicitly marked
85
+ const isDirectory = !isLast || isExplicitDir;
86
+
87
+ let existing = parent.children.find(c => c.name === part);
88
+ if (!existing) {
89
+ existing = {
90
+ name: part,
91
+ children: [],
92
+ isDirectory
93
+ };
94
+ parent.children.push(existing);
95
+ }
96
+
97
+ parent = existing;
98
+ });
99
+
100
+ // Push only real directories
101
+ if (isExplicitDir) {
102
+ stack.push({ node: parent, indent });
103
+ }
104
+ }
105
+
106
+ return root;
107
+ }
108
+
109
+
110
+ /**
111
+ * ======================
112
+ * FILE CREATION (OLD)
113
+ * ======================
114
+ */
31
115
  function createFiles(node, currentPath = '.') {
32
116
  if (!node) return;
33
117
 
34
- const fullPath = path.join(currentPath, node.name);
35
-
36
- if (node.name.includes('.')) {
37
- // It's a file
38
- fs.mkdirSync(path.dirname(fullPath), { recursive: true });
39
- fs.writeFileSync(fullPath, '');
40
- console.log(chalk.green(`✓ Created file: ${fullPath}`));
41
- } else if (node.name) {
42
- // It's a directory
43
- fs.mkdirSync(fullPath, { recursive: true });
44
- console.log(chalk.blue(`✓ Created directory: ${fullPath}`));
118
+ const fullPath = node.name ? path.join(currentPath, node.name) : currentPath;
119
+
120
+ if (node.name) {
121
+ if (node.isDirectory) {
122
+ fs.mkdirSync(fullPath, { recursive: true });
123
+ console.log(chalk.blue(`✓ Created directory: ${fullPath}`));
124
+ } else {
125
+ fs.mkdirSync(path.dirname(fullPath), { recursive: true });
126
+ fs.writeFileSync(fullPath, '');
127
+ console.log(chalk.green(`✓ Created file: ${fullPath}`));
128
+ }
45
129
  }
46
130
 
47
- // Process children
48
131
  node.children.forEach(child => {
49
- createFiles(child, node.name ? fullPath : currentPath);
132
+ createFiles(child, fullPath);
50
133
  });
51
134
  }
52
135
 
53
- module.exports = { parseStructure, createFiles };
136
+ module.exports = { parseStructure, createFiles };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "folder-generator",
3
- "version": "1.3.9",
3
+ "version": "3.0.0",
4
4
  "description": "CLI tool to generate folder structures from text input",
5
5
  "bin": {
6
6
  "foldgen": "./bin/cli.js"