mdsmith 1.1.2 β 1.2.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/README-MDSMITH.md +47 -11
- package/bin/index.js +69 -247
- package/bin/vers/303/243o2.js +997 -0
- package/mdsmith.config.json +2 -1
- package/package.json +4 -1
- package/src/analysis/index.js +149 -0
- package/src/config/index.js +43 -0
- package/src/detectors/index.js +203 -0
- package/src/formatters/index.js +53 -0
- package/src/generators/index.js +27 -0
- package/src/interactive/index.js +95 -0
- package/src/readme/index.js +286 -0
- package/src/scanner/index.js +113 -0
package/README-MDSMITH.md
CHANGED
|
@@ -1,30 +1,66 @@
|
|
|
1
1
|
|
|
2
|
-
#
|
|
2
|
+
# mdsmith
|
|
3
3
|
|
|
4
4
|
CLI para gerar READMEs e arquivos Markdown
|
|
5
5
|
|
|
6
|
-
## π
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
6
|
+
## π InformaΓ§Γ΅es do Projeto
|
|
7
|
+
- **VersΓ£o:** 1.2.0
|
|
8
|
+
- **Gerenciador de Pacotes:** npm
|
|
9
|
+
- **Tipo:** Node.js Project
|
|
10
10
|
|
|
11
|
-
##
|
|
12
|
-
No dependencies found.
|
|
11
|
+
## π Tecnologias
|
|
13
12
|
|
|
14
13
|
|
|
15
|
-
## π
|
|
14
|
+
## π Estrutura do Projeto
|
|
16
15
|
```
|
|
17
16
|
π bin
|
|
18
17
|
π beta.js
|
|
19
18
|
π index.js
|
|
19
|
+
π versΓ£o2.js
|
|
20
|
+
π src
|
|
21
|
+
π analysis
|
|
22
|
+
π index.js
|
|
23
|
+
π config
|
|
24
|
+
π index.js
|
|
25
|
+
π detectors
|
|
26
|
+
π index.js
|
|
27
|
+
π formatters
|
|
28
|
+
π index.js
|
|
29
|
+
π generators
|
|
30
|
+
π index.js
|
|
31
|
+
π interactive
|
|
32
|
+
π index.js
|
|
33
|
+
π readme
|
|
34
|
+
π index.js
|
|
35
|
+
π scanner
|
|
36
|
+
π index.js
|
|
20
37
|
π mdsmith.config.json
|
|
38
|
+
π package-lock.json
|
|
21
39
|
π package.json
|
|
22
40
|
π README-MDSMITH.md
|
|
23
41
|
|
|
24
42
|
```
|
|
25
43
|
|
|
26
|
-
##
|
|
27
|
-
No scripts available.
|
|
44
|
+
## π Primeiros Passos
|
|
28
45
|
|
|
29
46
|
|
|
30
|
-
|
|
47
|
+
```bash
|
|
48
|
+
npm install
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## π VariΓ‘veis de Ambiente
|
|
54
|
+
Crie um arquivo `.env` na raiz do projeto com as seguintes variΓ‘veis:
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
## π ConfiguraΓ§Γ£o do Banco de Dados
|
|
58
|
+
Execute as migrations do Prisma:
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
Gerado por **mdSmith**
|
package/bin/index.js
CHANGED
|
@@ -5,18 +5,24 @@
|
|
|
5
5
|
// npx mdsmith --tree # show project structure
|
|
6
6
|
// npx mdsmith --deps # list dependencies
|
|
7
7
|
// npx mdsmith --readme # generate README
|
|
8
|
+
// npx mdsmith --analyze # project analyze
|
|
9
|
+
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
const fs = require("fs");
|
|
11
13
|
|
|
12
14
|
const path = require("path");
|
|
13
15
|
|
|
14
|
-
const
|
|
16
|
+
const core = require("../src/generators")
|
|
17
|
+
const detectors = require("../src/detectors")
|
|
18
|
+
const scanner = require("../src/scanner")
|
|
19
|
+
const readme = require("../src/readme")
|
|
20
|
+
const configModule = require("../src/config")
|
|
21
|
+
const analysisModule = require("../src/analysis")
|
|
22
|
+
const formatters = require("../src/formatters")
|
|
23
|
+
|
|
15
24
|
|
|
16
|
-
const
|
|
17
|
-
input: process.stdin,
|
|
18
|
-
output: process.stdout
|
|
19
|
-
});
|
|
25
|
+
const prompts = require('prompts');
|
|
20
26
|
|
|
21
27
|
const projectRoot = process.cwd();
|
|
22
28
|
|
|
@@ -28,229 +34,21 @@ Please run mdsmith from the project root.
|
|
|
28
34
|
process.exit(1)
|
|
29
35
|
}
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const args = process.argv.slice(2)
|
|
34
|
-
|
|
35
|
-
const defaultConfig = {
|
|
36
|
-
ignore: ["node_modules", ".git", ".vscode"],
|
|
37
|
-
depth: Infinity
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
function formatDependencies(deps) {
|
|
42
|
-
if (!deps || Object.keys(deps).length === 0) {
|
|
43
|
-
return "No dependencies found.\n";
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return Object.entries(deps)
|
|
47
|
-
.map(([name, version]) => `- ${name} ${version}`)
|
|
48
|
-
.join("\n");
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function scanDir(dirPath, padding, config) {
|
|
52
|
-
const entries = fs.readdirSync(dirPath, { withFileTypes: true })
|
|
53
|
-
.sort((a, b) => {
|
|
54
|
-
if (a.isDirectory() && !b.isDirectory()) return -1
|
|
55
|
-
if (!a.isDirectory() && b.isDirectory()) return 1
|
|
56
|
-
return a.name.localeCompare(b.name)
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
let treeContent = ""
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
for (const entry of entries) {
|
|
63
|
-
|
|
64
|
-
const fullPath = path.join(dirPath, entry.name);
|
|
65
|
-
|
|
66
|
-
if (entry.isDirectory()) {
|
|
67
|
-
if (config.ignore.includes(entry.name)){
|
|
68
|
-
continue
|
|
69
|
-
} else {
|
|
70
|
-
treeContent += `${" ".repeat(padding*2)} π ${entry.name}\n`
|
|
71
|
-
if (config.depth === null || padding < config.depth){
|
|
72
|
-
padding ++
|
|
73
|
-
treeContent += scanDir(fullPath, padding, config)
|
|
74
|
-
padding --
|
|
75
|
-
} else {
|
|
76
|
-
treeContent += `${" ".repeat((padding + 1) * 2)} Β·Β·Β· \n`
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
} else {
|
|
80
|
-
if (config.ignore.includes(entry.name)){
|
|
81
|
-
continue
|
|
82
|
-
} else{
|
|
83
|
-
treeContent += `${" ".repeat(padding*2)} π ${entry.name}\n`
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return treeContent
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function perguntar(pergunta) {
|
|
92
|
-
return new Promise(resolve => {
|
|
93
|
-
rl.question(pergunta, resolve);
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async function buscarNome(nome){
|
|
98
|
-
if(!nome || nome == "" || nome == false){
|
|
99
|
-
|
|
100
|
-
let respostaValida = false
|
|
101
|
-
let resposta = ""
|
|
102
|
-
while(!respostaValida){
|
|
103
|
-
resposta = await perguntar(`
|
|
104
|
-
Project name not found in package.json.
|
|
105
|
-
Would you like to provide one? (y/n): `)
|
|
106
|
-
resposta = resposta.trim().toLowerCase()
|
|
107
|
-
|
|
108
|
-
if(resposta == "y" || resposta == "n"){
|
|
109
|
-
respostaValida = true
|
|
110
|
-
}else {
|
|
111
|
-
console.log("Please type y or n.")
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if(resposta == "n"){
|
|
117
|
-
console.log("\nProject name will be set as Unnamed Project.\n")
|
|
118
|
-
return "Unnamed Project"
|
|
119
|
-
}if(resposta == "y"){
|
|
120
|
-
let nome = await perguntar("Enter the project name: ")
|
|
121
|
-
console.log(`Project name set to "${nome}".`)
|
|
122
|
-
return nome
|
|
123
|
-
}else{
|
|
124
|
-
console.error("Failed to generate project name.")
|
|
125
|
-
process.exit(1)
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return nome
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
async function buscarDescricao(descricao){
|
|
133
|
-
if(!descricao || descricao == "" || descricao == false){
|
|
134
|
-
|
|
135
|
-
let respostaValida = false
|
|
136
|
-
let resposta = ""
|
|
137
|
-
while(!respostaValida){
|
|
138
|
-
resposta = await perguntar(`
|
|
139
|
-
Project description not found.
|
|
140
|
-
Would you like to provide one? (y/n): `)
|
|
141
|
-
resposta = resposta.trim().toLowerCase()
|
|
142
|
-
|
|
143
|
-
if(resposta == "y" || resposta == "n"){
|
|
144
|
-
respostaValida = true
|
|
145
|
-
}else {
|
|
146
|
-
console.log("Please type y or n.")
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if(resposta == "n"){
|
|
152
|
-
console.log("\nDescription placeholder added.\n")
|
|
153
|
-
return "*Project description goes here*"
|
|
154
|
-
}if(resposta == "y"){
|
|
155
|
-
let descricao = await perguntar("Enter the project description: ")
|
|
156
|
-
console.log("\nDescription saved.\n")
|
|
157
|
-
return descricao
|
|
158
|
-
}else{
|
|
159
|
-
console.error("Failed to generate project description.")
|
|
160
|
-
process.exit(1)
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return descricao
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function detectarTipoProjeto(packageJson) {
|
|
168
|
-
const deps = {
|
|
169
|
-
...packageJson.dependencies,
|
|
170
|
-
...packageJson.devDependencies
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
if (deps.react) return "Frontend React"
|
|
174
|
-
if (deps.next) return "Next.js Application"
|
|
175
|
-
if (deps.express) return "API REST (Express)"
|
|
176
|
-
if (deps.typescript) return "Projeto TypeScript"
|
|
177
|
-
|
|
178
|
-
return "Node.js Project"
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function formatScripts(scripts) {
|
|
182
|
-
if (!scripts || Object.keys(scripts).length === 0) {
|
|
183
|
-
return "No scripts available.\n";
|
|
184
|
-
}
|
|
37
|
+
let packageJson
|
|
185
38
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
39
|
+
try {
|
|
40
|
+
packageJson = JSON.parse(
|
|
41
|
+
fs.readFileSync(path.join(projectRoot, "package.json"), "utf-8")
|
|
42
|
+
)
|
|
43
|
+
} catch {
|
|
44
|
+
console.log("Invalid package.json file.")
|
|
45
|
+
process.exit(1)
|
|
189
46
|
}
|
|
190
47
|
|
|
191
|
-
|
|
192
|
-
async function generateReadme(packageJson, tree){
|
|
193
|
-
|
|
194
|
-
const nomeProjeto = await buscarNome(packageJson.name);
|
|
195
|
-
const descricaoProjeto = await buscarDescricao(packageJson.description);
|
|
196
|
-
|
|
197
|
-
const content = `
|
|
198
|
-
# ${nomeProjeto}
|
|
199
|
-
|
|
200
|
-
${descricaoProjeto}
|
|
201
|
-
|
|
202
|
-
## π Project Info
|
|
203
|
-
- **Version:** ${packageJson.version || "Not specified"}
|
|
204
|
-
- **Package Manager:** npm
|
|
205
|
-
- **Type:** ${detectarTipoProjeto(packageJson)}
|
|
206
|
-
|
|
207
|
-
## π Dependencies
|
|
208
|
-
${formatDependencies(packageJson.dependencies)}
|
|
209
|
-
|
|
210
|
-
## π Project Structure
|
|
211
|
-
\`\`\`
|
|
212
|
-
${tree}
|
|
213
|
-
\`\`\`
|
|
214
|
-
|
|
215
|
-
## π Available Scripts
|
|
216
|
-
${formatScripts(packageJson.scripts)}
|
|
217
|
-
|
|
218
|
-
Generated by **mdSmith**
|
|
219
|
-
`
|
|
220
|
-
|
|
221
|
-
return content
|
|
222
|
-
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
function loadConfig(projectRoot) {
|
|
226
|
-
const configPath = path.join(projectRoot, "mdsmith.config.json")
|
|
227
|
-
|
|
228
|
-
if (!fs.existsSync(configPath)) {
|
|
229
|
-
return defaultConfig
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
try {
|
|
233
|
-
const fileContent = fs.readFileSync(configPath, "utf-8")
|
|
234
|
-
const userConfig = JSON.parse(fileContent)
|
|
235
|
-
|
|
236
|
-
return {
|
|
237
|
-
...defaultConfig,
|
|
238
|
-
...userConfig,
|
|
239
|
-
ignore: [
|
|
240
|
-
...defaultConfig.ignore,
|
|
241
|
-
...(userConfig.ignore || [])
|
|
242
|
-
]
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
} catch (error) {
|
|
247
|
-
console.log("Failed to read mdsmith.config.json. Using default configuration.")
|
|
248
|
-
return defaultConfig
|
|
249
|
-
}
|
|
250
|
-
}
|
|
48
|
+
const args = process.argv.slice(2)
|
|
251
49
|
|
|
252
50
|
async function main() {
|
|
253
|
-
const config = loadConfig(projectRoot)
|
|
51
|
+
const config = configModule.loadConfig(projectRoot)
|
|
254
52
|
|
|
255
53
|
if(args.length == 0){
|
|
256
54
|
console.log(`
|
|
@@ -272,7 +70,7 @@ Run "mdsmith --help" to view available commands.
|
|
|
272
70
|
|
|
273
71
|
fs.writeFileSync(
|
|
274
72
|
configPath,
|
|
275
|
-
JSON.stringify(defaultConfig, null, 2)
|
|
73
|
+
JSON.stringify(configModule.defaultConfig, null, 2)
|
|
276
74
|
)
|
|
277
75
|
|
|
278
76
|
console.log("Configuration file created.")
|
|
@@ -288,6 +86,7 @@ mdSmith β Available Commands
|
|
|
288
86
|
--tree Show project structure
|
|
289
87
|
--deps List dependencies
|
|
290
88
|
--readme Generate README
|
|
89
|
+
--analyze Project analysis
|
|
291
90
|
`)
|
|
292
91
|
process.exit(0)
|
|
293
92
|
} else if (args.includes("--tree")){
|
|
@@ -295,18 +94,47 @@ mdSmith β Available Commands
|
|
|
295
94
|
Project Structure
|
|
296
95
|
ββββββββββββββββββββββββ
|
|
297
96
|
`);
|
|
298
|
-
console.log(scanDir(projectRoot, 0, config))
|
|
97
|
+
console.log(scanner.scanDir(projectRoot, 0, config))
|
|
299
98
|
process.exit(0)
|
|
99
|
+
} else if (args.includes("--analyze")){
|
|
100
|
+
const analysis = analysisModule.analisarProjeto(packageJson, projectRoot)
|
|
101
|
+
const packageManager = detectors.detectarPackageManager(projectRoot)
|
|
102
|
+
|
|
103
|
+
formatters.formatarAnalise(analysis)
|
|
104
|
+
|
|
105
|
+
const commands = analysisModule.analisarScripts(packageJson.scripts, packageManager)
|
|
106
|
+
const warnings = analysisModule.diagnosticarExecucao(commands)
|
|
107
|
+
|
|
108
|
+
formatters.formatarExecucao(commands, warnings)
|
|
109
|
+
|
|
110
|
+
const issues = analysisModule.healthChecks(packageJson, projectRoot, analysis)
|
|
111
|
+
|
|
112
|
+
if (issues.length > 0) {
|
|
113
|
+
console.log("Health Checks")
|
|
114
|
+
console.log("ββββββββββββββββββββββββ")
|
|
115
|
+
issues.forEach(issue => {
|
|
116
|
+
let icon = "β "
|
|
117
|
+
|
|
118
|
+
if (issue.type === "critical") icon = "β"
|
|
119
|
+
if (issue.type === "info") icon = "βΉ"
|
|
120
|
+
|
|
121
|
+
console.log(`${icon} ${issue.message}`)
|
|
122
|
+
})
|
|
123
|
+
console.log()
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
process.exit(0)
|
|
300
127
|
} else if (args.includes("--deps")){
|
|
301
128
|
console.log(`
|
|
302
129
|
Dependencies
|
|
303
130
|
ββββββββββββββββββββββββ
|
|
304
131
|
`)
|
|
305
|
-
const deps = formatDependencies(packageJson.dependencies)
|
|
306
|
-
console.log(deps)
|
|
132
|
+
const deps = core.formatDependencies(packageJson.dependencies)
|
|
133
|
+
console.log(`${deps}\n`)
|
|
134
|
+
console.log()
|
|
307
135
|
process.exit(0)
|
|
308
136
|
} else if (args.includes("--readme")){
|
|
309
|
-
const content = await generateReadme(packageJson, scanDir(projectRoot, 0, config))
|
|
137
|
+
const content = await readme.generateReadme(packageJson, scanner.scanDir(projectRoot, 0, config), config)
|
|
310
138
|
|
|
311
139
|
console.log(`
|
|
312
140
|
README Preview
|
|
@@ -315,28 +143,22 @@ README Preview
|
|
|
315
143
|
|
|
316
144
|
console.log(content)
|
|
317
145
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
146
|
+
const confirmResponse = await prompts({
|
|
147
|
+
type: 'confirm',
|
|
148
|
+
name: 'generate',
|
|
149
|
+
message: 'Generate README-MDSMITH.md?',
|
|
150
|
+
initial: true
|
|
151
|
+
});
|
|
324
152
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
console.log("\nPlease type y or n.")
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
if (confirm === "y") {
|
|
333
|
-
fs.writeFileSync("README-MDSMITH.md", content)
|
|
334
|
-
console.log("\nREADME-MDSMITH.md created.\n")
|
|
335
|
-
process.exit(0)
|
|
153
|
+
if (confirmResponse.generate) {
|
|
154
|
+
fs.writeFileSync("README-MDSMITH.md", content);
|
|
155
|
+
console.log("\nREADME-MDSMITH.md created.\n");
|
|
336
156
|
} else {
|
|
337
|
-
console.log("\nOperation cancelled.\n")
|
|
338
|
-
process.exit(0)
|
|
157
|
+
console.log("\nOperation cancelled.\n");
|
|
339
158
|
}
|
|
159
|
+
|
|
160
|
+
process.exit(0);
|
|
161
|
+
|
|
340
162
|
} else {
|
|
341
163
|
console.log(`
|
|
342
164
|
Unknown command.
|