blytz 1.1.0 → 1.1.1
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 +55 -32
- package/package.json +1 -1
- package/src/processReadme.js +8 -6
- package/src/template.js +17 -12
package/bin/cli.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import fs from 'fs';
|
|
4
4
|
import path from 'path';
|
|
5
|
+
import readline from 'readline/promises';
|
|
5
6
|
|
|
6
7
|
import processReadme from '../src/processReadme.js';
|
|
7
8
|
|
|
@@ -80,45 +81,63 @@ function getLicenseName(licenseContent) {
|
|
|
80
81
|
return firstLine || '';
|
|
81
82
|
}
|
|
82
83
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
console.error("Error: No README.md found in this directory. Try --init.");
|
|
97
|
-
process.exit(1);
|
|
84
|
+
async function promptForTitleAndDescription() {
|
|
85
|
+
const rl = readline.createInterface({
|
|
86
|
+
input: process.stdin,
|
|
87
|
+
output: process.stdout,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
const titleContent = (await rl.question('Add title: ')).trim();
|
|
92
|
+
const descriptionContent = (await rl.question('Add description: ')).trim();
|
|
93
|
+
return { titleContent, descriptionContent };
|
|
94
|
+
} finally {
|
|
95
|
+
rl.close();
|
|
96
|
+
}
|
|
98
97
|
}
|
|
99
98
|
|
|
100
|
-
|
|
101
|
-
console.
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
async function main() {
|
|
100
|
+
console.log("Scanning for project files...");
|
|
101
|
+
|
|
102
|
+
const targetDir = process.cwd();
|
|
103
|
+
const readmePath = path.join(targetDir, 'README.md');
|
|
104
|
+
const packageJsonPath = path.join(targetDir, 'package.json');
|
|
105
|
+
const requirementsPath = path.join(targetDir, 'requirements.txt');
|
|
106
|
+
const licensePath = path.join(targetDir, 'LICENSE');
|
|
107
|
+
const readmeExists = fs.existsSync(readmePath);
|
|
108
|
+
const hasPackageJson = fs.existsSync(packageJsonPath);
|
|
109
|
+
const hasRequirements = fs.existsSync(requirementsPath);
|
|
110
|
+
const hasLicense = fs.existsSync(licensePath);
|
|
111
|
+
|
|
112
|
+
if (!readmeExists && !shouldInit && !shouldForce) {
|
|
113
|
+
console.error("Error: No README.md found in this directory. Try --init.");
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
104
116
|
|
|
105
|
-
if (
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
117
|
+
if (readmeExists && shouldInit && !shouldForce) {
|
|
118
|
+
console.error("README.md already exists. Try --force.");
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
109
121
|
|
|
110
|
-
|
|
122
|
+
if (!hasPackageJson && !hasRequirements) {
|
|
123
|
+
console.error("Error: No package.json or requirements.txt found in this directory.");
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
console.log("Files found. Processing README...");
|
|
111
128
|
|
|
112
|
-
try {
|
|
113
129
|
if (shouldForce && readmeExists) {
|
|
114
130
|
fs.unlinkSync(readmePath);
|
|
115
131
|
}
|
|
116
132
|
|
|
117
|
-
// 1. Read the raw text of both files
|
|
118
133
|
const readmeContent = fs.existsSync(readmePath) ? fs.readFileSync(readmePath, 'utf-8') : '';
|
|
119
134
|
const fileTree = buildFileTree(targetDir);
|
|
120
135
|
const projectName = path.basename(targetDir);
|
|
121
136
|
const licenseName = hasLicense ? getLicenseName(fs.readFileSync(licensePath, 'utf-8')) : '';
|
|
137
|
+
const shouldPromptMetadata = !shouldUpdate;
|
|
138
|
+
const { titleContent, descriptionContent } = shouldPromptMetadata
|
|
139
|
+
? await promptForTitleAndDescription()
|
|
140
|
+
: { titleContent: '', descriptionContent: '' };
|
|
122
141
|
let context;
|
|
123
142
|
let projectType;
|
|
124
143
|
|
|
@@ -132,6 +151,8 @@ try {
|
|
|
132
151
|
dependencies: collectDependencies(packageJson),
|
|
133
152
|
scripts: collectScripts(packageJson),
|
|
134
153
|
fileTree,
|
|
154
|
+
titleContent,
|
|
155
|
+
descriptionContent,
|
|
135
156
|
licenseName,
|
|
136
157
|
username: packageJson.author || process.env.USERNAME || 'Unknown Author',
|
|
137
158
|
projectName: packageJson.name || projectName,
|
|
@@ -147,6 +168,8 @@ try {
|
|
|
147
168
|
dependencies: collectPythonDependencies(requirementsContent),
|
|
148
169
|
scripts: new Map(),
|
|
149
170
|
fileTree,
|
|
171
|
+
titleContent,
|
|
172
|
+
descriptionContent,
|
|
150
173
|
licenseName,
|
|
151
174
|
username: process.env.USERNAME || 'Unknown Author',
|
|
152
175
|
projectName,
|
|
@@ -156,15 +179,15 @@ try {
|
|
|
156
179
|
projectType = 'python';
|
|
157
180
|
}
|
|
158
181
|
|
|
159
|
-
// 3. Feed everything into your pure engine
|
|
160
182
|
const updatedReadme = processReadme(readmeContent, projectType, context);
|
|
161
183
|
|
|
162
|
-
// 4. Overwrite the existing README.md with the new content
|
|
163
184
|
fs.writeFileSync(readmePath, updatedReadme, 'utf-8');
|
|
164
185
|
|
|
165
186
|
console.log("Success! README.md has been auto-fixed.");
|
|
166
|
-
|
|
167
|
-
} catch (error) {
|
|
168
|
-
console.error("An error occurred during processing:", error.message);
|
|
169
|
-
process.exit(1);
|
|
170
187
|
}
|
|
188
|
+
|
|
189
|
+
(main()
|
|
190
|
+
.catch(error => {
|
|
191
|
+
console.error("An error occurred during processing:", error.message);
|
|
192
|
+
process.exit(1);
|
|
193
|
+
}));
|
package/package.json
CHANGED
package/src/processReadme.js
CHANGED
|
@@ -2,16 +2,18 @@ import getDefaultContent from "./template.js";
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
//Core engine: processes README content and returns updated version
|
|
5
|
-
export default function processReadme(content, projectType, context = {}) {
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
export default function processReadme(content, projectType, context = {}) {
|
|
6
|
+
const { titleContent = "" } = context ?? {};
|
|
7
|
+
|
|
8
|
+
const normalizedContent = (content || "").replace(/^##(?=\S)/gm, "## ");
|
|
8
9
|
|
|
9
10
|
// Split into sections
|
|
10
11
|
const sections = normalizedContent.split("## ");
|
|
11
12
|
const sectionMap = {};
|
|
12
13
|
|
|
13
14
|
// Extract intro (title + description)
|
|
14
|
-
const intro = sections[0].trim();
|
|
15
|
+
const intro = sections[0].trim();
|
|
16
|
+
const finalIntro = titleContent ? `# ${titleContent}` : intro;
|
|
15
17
|
|
|
16
18
|
// Parse sections
|
|
17
19
|
sections.slice(1).forEach(section => {
|
|
@@ -65,7 +67,7 @@ export default function processReadme(content, projectType, context = {}) {
|
|
|
65
67
|
.join(" ");
|
|
66
68
|
|
|
67
69
|
// Rebuild README
|
|
68
|
-
let newReadme =
|
|
70
|
+
let newReadme = finalIntro ? finalIntro + "\n\n" : "";
|
|
69
71
|
|
|
70
72
|
// Ordered sections
|
|
71
73
|
requiredSections.forEach(section => {
|
|
@@ -80,4 +82,4 @@ export default function processReadme(content, projectType, context = {}) {
|
|
|
80
82
|
});
|
|
81
83
|
|
|
82
84
|
return newReadme.trim();
|
|
83
|
-
}
|
|
85
|
+
}
|
package/src/template.js
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import getProjectStructure from "./fileTree.js";
|
|
2
2
|
|
|
3
3
|
export default function getDefaultContent(section, projectType, context = {}) {
|
|
4
|
-
const {
|
|
5
|
-
packages = [],
|
|
6
|
-
dependencies = [],
|
|
7
|
-
scripts = new Map(),
|
|
4
|
+
const {
|
|
5
|
+
packages = [],
|
|
6
|
+
dependencies = [],
|
|
7
|
+
scripts = new Map(),
|
|
8
8
|
fileTree = null,
|
|
9
|
+
descriptionContent = "",
|
|
9
10
|
licenseName = "",
|
|
10
11
|
username = "Unknown",
|
|
11
|
-
projectName = "this project",
|
|
12
|
-
isMonorepo = false,
|
|
13
|
-
} = context ?? {};
|
|
12
|
+
projectName = "this project",
|
|
13
|
+
isMonorepo = false,
|
|
14
|
+
} = context ?? {};
|
|
14
15
|
|
|
15
16
|
const safeProjectType = projectType || "unknown";
|
|
16
17
|
const safeSection = (section || "").toLowerCase().trim();
|
|
17
18
|
|
|
18
|
-
switch (safeSection) {
|
|
19
|
-
case "description":
|
|
20
|
-
return getDescriptionContent(safeProjectType, projectName, isMonorepo);
|
|
19
|
+
switch (safeSection) {
|
|
20
|
+
case "description":
|
|
21
|
+
return getDescriptionContent(safeProjectType, projectName, isMonorepo, descriptionContent);
|
|
21
22
|
case "installation":
|
|
22
23
|
return getInstallationContent(safeProjectType, packages, isMonorepo);
|
|
23
24
|
case "usage":
|
|
@@ -35,8 +36,12 @@ export default function getDefaultContent(section, projectType, context = {}) {
|
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
function getDescriptionContent(projectType, projectName, isMonorepo) {
|
|
39
|
-
|
|
39
|
+
function getDescriptionContent(projectType, projectName, isMonorepo, descriptionContent) {
|
|
40
|
+
if (descriptionContent) {
|
|
41
|
+
return descriptionContent;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const name = projectName || "this project";
|
|
40
45
|
if (projectType === "node") {
|
|
41
46
|
if (isMonorepo) {
|
|
42
47
|
return `${name} is a Node.js monorepo containing multiple packages. Add a brief description of its purpose and what problem it solves.`;
|