mdsmith 1.2.1 β 1.2.2
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 +0 -19
- package/README.md +0 -0
- package/package.json +1 -1
- package/bin/beta.js +0 -117
- package/bin/vers/303/243o2.js +0 -997
package/README-MDSMITH.md
CHANGED
|
@@ -8,9 +8,6 @@ CLI para gerar READMEs e arquivos Markdown
|
|
|
8
8
|
- **Gerenciador de Pacotes:** npm
|
|
9
9
|
- **Tipo:** Node.js Project
|
|
10
10
|
|
|
11
|
-
## π Tecnologias
|
|
12
|
-
|
|
13
|
-
|
|
14
11
|
## π Estrutura do Projeto
|
|
15
12
|
```
|
|
16
13
|
π bin
|
|
@@ -41,26 +38,10 @@ CLI para gerar READMEs e arquivos Markdown
|
|
|
41
38
|
|
|
42
39
|
```
|
|
43
40
|
|
|
44
|
-
## π Primeiros Passos
|
|
45
|
-
|
|
46
|
-
|
|
47
41
|
```bash
|
|
48
42
|
npm install
|
|
49
43
|
```
|
|
50
44
|
|
|
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
45
|
---
|
|
65
46
|
|
|
66
47
|
Gerado por **mdSmith**
|
package/README.md
ADDED
|
Binary file
|
package/package.json
CHANGED
package/bin/beta.js
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// npx mdsmith --help # ajuda
|
|
4
|
-
// npx mdsmith --tree # mostra estrutura
|
|
5
|
-
// npx mdsmith --deps # mostra dependΓͺncias
|
|
6
|
-
// npx mdsmith --readme # gera README
|
|
7
|
-
|
|
8
|
-
const fs = require("fs");
|
|
9
|
-
|
|
10
|
-
const path = require("path");
|
|
11
|
-
|
|
12
|
-
const projectRoot = process.cwd();
|
|
13
|
-
|
|
14
|
-
if(!fs.existsSync(path.join(process.cwd(), "package.json"))){
|
|
15
|
-
console.log("Package.json nΓ£o encontrado.\nVerifique se vocΓͺ estΓ‘ rodando o comando na raiz do projeto.")
|
|
16
|
-
process.exit(1)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const packageJson = JSON.parse(fs.readFileSync(path.join(projectRoot, "package.json"), "utf-8"));
|
|
20
|
-
|
|
21
|
-
const args = process.argv.slice(2)
|
|
22
|
-
|
|
23
|
-
const IGNORE_DIRS = ["node_modules", ".git", ".vscode"];
|
|
24
|
-
|
|
25
|
-
function formatDependencies(deps) {
|
|
26
|
-
if (!deps || Object.keys(deps).length === 0) {
|
|
27
|
-
return "Projeto sem dependΓͺncias.";
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return Object.entries(deps)
|
|
31
|
-
.map(([name, version]) => `- ${name} ${version}`)
|
|
32
|
-
.join("\n");
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function scanDir(dirPath, padding) {
|
|
36
|
-
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
37
|
-
|
|
38
|
-
let treeContent = ""
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
for (const entry of entries) {
|
|
42
|
-
|
|
43
|
-
const fullPath = path.join(dirPath, entry.name);
|
|
44
|
-
|
|
45
|
-
if (entry.isDirectory()) {
|
|
46
|
-
if (IGNORE_DIRS.includes(entry.name)){
|
|
47
|
-
treeContent += `${" ".repeat(padding*2)} π ${entry.name}\n`
|
|
48
|
-
} else {
|
|
49
|
-
treeContent += `${" ".repeat(padding*2)} π ${entry.name}\n`
|
|
50
|
-
padding ++
|
|
51
|
-
treeContent += scanDir(fullPath, padding)
|
|
52
|
-
padding --
|
|
53
|
-
}
|
|
54
|
-
} else {
|
|
55
|
-
treeContent += `${" ".repeat(padding*2)} π ${entry.name}\n`
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return treeContent
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function generateReadme(packageJson, tree){
|
|
63
|
-
const content = `
|
|
64
|
-
# ${packageJson.name || "Nome nΓ£o informado."}
|
|
65
|
-
|
|
66
|
-
${packageJson.description || "Projeto Node.js analisado automaticamente pelo mdSmith."}
|
|
67
|
-
|
|
68
|
-
## π InformaΓ§Γ΅es
|
|
69
|
-
- **VersΓ£o:** ${packageJson.version || "VersΓ£o nΓ£o informada."}
|
|
70
|
-
- **Gerenciador:** npm
|
|
71
|
-
- **Tipo:** Backend Node.js
|
|
72
|
-
|
|
73
|
-
## π DependΓͺncias
|
|
74
|
-
${formatDependencies(packageJson.dependencies)}
|
|
75
|
-
|
|
76
|
-
## π Estrutura do Projeto
|
|
77
|
-
\`\`\`
|
|
78
|
-
${tree}
|
|
79
|
-
\`\`\`
|
|
80
|
-
|
|
81
|
-
π *README gerado automaticamente pelo **mdSmith***
|
|
82
|
-
`
|
|
83
|
-
|
|
84
|
-
return content
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if(args.length == 0){
|
|
89
|
-
console.log(`
|
|
90
|
-
Bem vindo ao mdSmith!
|
|
91
|
-
Analisador de projetos Node.js
|
|
92
|
-
|
|
93
|
-
Digite npx mdsmith --help se quiser ver os comandos disponΓveis
|
|
94
|
-
`);
|
|
95
|
-
process.exit(0);
|
|
96
|
-
} else if(args.includes("--help")){
|
|
97
|
-
console.log(`
|
|
98
|
-
npx mdsmith --help Mostra os comandos possΓveis
|
|
99
|
-
npx mdsmith --tree Mostra a estrutura do projeto
|
|
100
|
-
npx mdsmith --deps Mostra as dependΓͺncias
|
|
101
|
-
npx mdsmith --readme Gera um README automaticamente
|
|
102
|
-
`)
|
|
103
|
-
} else if (args.includes("--tree")){
|
|
104
|
-
console.log("\nπ³ Estrutura do projeto:\n");
|
|
105
|
-
console.log(scanDir(projectRoot, 0))
|
|
106
|
-
} else if (args.includes("--deps")){
|
|
107
|
-
console.log(`O projeto ${packageJson.name} na versΓ£o ${packageJson.version}, tem as seguintes dependencias:`)
|
|
108
|
-
const deps = packageJson.dependencies || "Projeto sem depedencias"
|
|
109
|
-
console.log(deps)
|
|
110
|
-
} else if (args.includes("--readme")){
|
|
111
|
-
const content = generateReadme(packageJson, scanDir(projectRoot, 0))
|
|
112
|
-
|
|
113
|
-
fs.writeFileSync("README-MDSMITH.md", content)
|
|
114
|
-
console.log("β
README-MDSMITH.md gerado com sucesso!")
|
|
115
|
-
} else {
|
|
116
|
-
console.log("β Comando nΓ£o reconhecido. Use npx mdsmith --help para ver as opΓ§Γ΅es.")
|
|
117
|
-
}
|
package/bin/vers/303/243o2.js
DELETED
|
@@ -1,997 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// npx mdsmith --help # show help
|
|
4
|
-
// npx mdsmith --init # create config file
|
|
5
|
-
// npx mdsmith --tree # show project structure
|
|
6
|
-
// npx mdsmith --deps # list dependencies
|
|
7
|
-
// npx mdsmith --readme # generate README
|
|
8
|
-
// npx mdsmith --analyze # project analyze
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const TECH_MAP = {
|
|
12
|
-
// Frameworks
|
|
13
|
-
express: "Express",
|
|
14
|
-
fastify: "Fastify",
|
|
15
|
-
koa: "Koa",
|
|
16
|
-
hapi: "Hapi",
|
|
17
|
-
"@nestjs/core": "NestJS",
|
|
18
|
-
|
|
19
|
-
// ORMs
|
|
20
|
-
prisma: "Prisma",
|
|
21
|
-
"@prisma/client": "Prisma",
|
|
22
|
-
sequelize: "Sequelize",
|
|
23
|
-
mongoose: "Mongoose",
|
|
24
|
-
typeorm: "TypeORM",
|
|
25
|
-
drizzle: "Drizzle ORM",
|
|
26
|
-
|
|
27
|
-
// Databases
|
|
28
|
-
pg: "PostgreSQL",
|
|
29
|
-
mysql: "MySQL",
|
|
30
|
-
mysql2: "MySQL",
|
|
31
|
-
sqlite3: "SQLite",
|
|
32
|
-
mongodb: "MongoDB",
|
|
33
|
-
|
|
34
|
-
// Auth
|
|
35
|
-
jsonwebtoken: "JWT",
|
|
36
|
-
passport: "Passport",
|
|
37
|
-
|
|
38
|
-
// AI
|
|
39
|
-
openai: "OpenAI",
|
|
40
|
-
langchain: "LangChain",
|
|
41
|
-
|
|
42
|
-
// Infra / Tools
|
|
43
|
-
docker: "Docker",
|
|
44
|
-
"swagger-ui-express": "Swagger",
|
|
45
|
-
puppeteer: "Puppeteer",
|
|
46
|
-
nodemailer: "Nodemailer"
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const i18n = {
|
|
51
|
-
en: {
|
|
52
|
-
projectInfo: "Project Info",
|
|
53
|
-
dependencies: "Dependencies",
|
|
54
|
-
projectStructure: "Project Structure",
|
|
55
|
-
availableScripts: "Available Scripts",
|
|
56
|
-
version: "Version",
|
|
57
|
-
packageManager: "Package Manager",
|
|
58
|
-
type: "Type",
|
|
59
|
-
generatedBy: "Generated by"
|
|
60
|
-
},
|
|
61
|
-
pt: {
|
|
62
|
-
projectInfo: "InformaΓ§Γ΅es do Projeto",
|
|
63
|
-
dependencies: "DependΓͺncias",
|
|
64
|
-
projectStructure: "Estrutura do Projeto",
|
|
65
|
-
availableScripts: "Scripts DisponΓveis",
|
|
66
|
-
version: "VersΓ£o",
|
|
67
|
-
packageManager: "Gerenciador de Pacotes",
|
|
68
|
-
type: "Tipo",
|
|
69
|
-
generatedBy: "Gerado por"
|
|
70
|
-
},
|
|
71
|
-
es: {
|
|
72
|
-
projectInfo: "InformaciΓ³n del Proyecto",
|
|
73
|
-
dependencies: "Dependencias",
|
|
74
|
-
projectStructure: "Estructura del Proyecto",
|
|
75
|
-
availableScripts: "Scripts Disponibles",
|
|
76
|
-
version: "VersiΓ³n",
|
|
77
|
-
packageManager: "Administrador de Paquetes",
|
|
78
|
-
type: "Tipo",
|
|
79
|
-
generatedBy: "Generado por"
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const fs = require("fs");
|
|
84
|
-
|
|
85
|
-
const path = require("path");
|
|
86
|
-
|
|
87
|
-
const prompts = require('prompts');
|
|
88
|
-
|
|
89
|
-
const projectRoot = process.cwd();
|
|
90
|
-
|
|
91
|
-
if(!fs.existsSync(path.join(process.cwd(), "package.json"))){
|
|
92
|
-
console.log(`
|
|
93
|
-
Error: package.json not found.
|
|
94
|
-
Please run mdsmith from the project root.
|
|
95
|
-
`)
|
|
96
|
-
process.exit(1)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
let packageJson
|
|
100
|
-
|
|
101
|
-
try {
|
|
102
|
-
packageJson = JSON.parse(
|
|
103
|
-
fs.readFileSync(path.join(projectRoot, "package.json"), "utf-8")
|
|
104
|
-
)
|
|
105
|
-
} catch {
|
|
106
|
-
console.log("Invalid package.json file.")
|
|
107
|
-
process.exit(1)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const args = process.argv.slice(2)
|
|
111
|
-
|
|
112
|
-
const defaultConfig = {
|
|
113
|
-
ignore: ["node_modules", ".git", ".vscode"],
|
|
114
|
-
depth: Infinity,
|
|
115
|
-
emojis: true
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function healthChecks(packageJson, projectRoot, analysis) {
|
|
119
|
-
const checks = []
|
|
120
|
-
|
|
121
|
-
if (!analysis.testing) {
|
|
122
|
-
checks.push({
|
|
123
|
-
type: "warning",
|
|
124
|
-
message: "No test runner configured."
|
|
125
|
-
})
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (!analysis.linting) {
|
|
129
|
-
checks.push({
|
|
130
|
-
type: "info",
|
|
131
|
-
message: "No ESLint detected."
|
|
132
|
-
})
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (!analysis.formatting) {
|
|
136
|
-
checks.push({
|
|
137
|
-
type: "info",
|
|
138
|
-
message: "No Prettier detected."
|
|
139
|
-
})
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (!packageJson.engines?.node) {
|
|
143
|
-
checks.push({
|
|
144
|
-
type: "critical",
|
|
145
|
-
message: "Node version not defined in package.json engines."
|
|
146
|
-
})
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (!fs.existsSync(path.join(projectRoot, "Dockerfile"))) {
|
|
150
|
-
checks.push({
|
|
151
|
-
type: "info",
|
|
152
|
-
message: "No Dockerfile found."
|
|
153
|
-
})
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return checks
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
function formatDependencies(deps) {
|
|
161
|
-
if (!deps || Object.keys(deps).length === 0) {
|
|
162
|
-
return "No dependencies found.\n";
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return Object.entries(deps)
|
|
166
|
-
.map(([name, version]) => `- ${name} ${version}`)
|
|
167
|
-
.join("\n");
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
function scanDir(dirPath, padding, config) {
|
|
171
|
-
let entries
|
|
172
|
-
try {
|
|
173
|
-
entries = fs.readdirSync(dirPath, { withFileTypes: true })
|
|
174
|
-
.sort((a, b) => {
|
|
175
|
-
if (a.isDirectory() && !b.isDirectory()) return -1
|
|
176
|
-
if (!a.isDirectory() && b.isDirectory()) return 1
|
|
177
|
-
return a.name.localeCompare(b.name)
|
|
178
|
-
})
|
|
179
|
-
} catch {
|
|
180
|
-
return ""
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
let treeContent = ""
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
for (const entry of entries) {
|
|
187
|
-
|
|
188
|
-
const fullPath = path.join(dirPath, entry.name);
|
|
189
|
-
|
|
190
|
-
if (entry.isDirectory()) {
|
|
191
|
-
if (config.ignore.includes(entry.name)){
|
|
192
|
-
continue
|
|
193
|
-
} else {
|
|
194
|
-
treeContent += `${" ".repeat(padding*2)} π ${entry.name}\n`
|
|
195
|
-
if (config.depth === null || padding < config.depth){
|
|
196
|
-
padding ++
|
|
197
|
-
treeContent += scanDir(fullPath, padding, config)
|
|
198
|
-
padding --
|
|
199
|
-
} else {
|
|
200
|
-
treeContent += `${" ".repeat((padding + 1) * 2)} Β·Β·Β· \n`
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
} else {
|
|
204
|
-
if (config.ignore.includes(entry.name)){
|
|
205
|
-
continue
|
|
206
|
-
} else{
|
|
207
|
-
treeContent += `${" ".repeat(padding*2)} π ${entry.name}\n`
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
return treeContent
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
async function buscarNome(nome) {
|
|
216
|
-
if (!nome) {
|
|
217
|
-
const confirm = await prompts({
|
|
218
|
-
type: 'confirm',
|
|
219
|
-
name: 'value',
|
|
220
|
-
message: 'Project name not found in package.json. Provide one?',
|
|
221
|
-
initial: true
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
if (!confirm.value) {
|
|
225
|
-
console.log("\nProject name will be set as Unnamed Project.\n");
|
|
226
|
-
return "Unnamed Project";
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const response = await prompts({
|
|
230
|
-
type: 'text',
|
|
231
|
-
name: 'value',
|
|
232
|
-
message: 'Enter the project name:'
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
console.log(`\nProject name set to "${response.value}".\n`);
|
|
236
|
-
return response.value || "Unnamed Project";
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
return nome;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
async function buscarDescricao(descricao) {
|
|
243
|
-
if (!descricao) {
|
|
244
|
-
const confirm = await prompts({
|
|
245
|
-
type: 'confirm',
|
|
246
|
-
name: 'value',
|
|
247
|
-
message: 'Project description not found. Provide one?',
|
|
248
|
-
initial: true
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
if (!confirm.value) {
|
|
252
|
-
console.log("\nDescription placeholder added.\n");
|
|
253
|
-
return "*Project description goes here*";
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
const response = await prompts({
|
|
257
|
-
type: 'text',
|
|
258
|
-
name: 'value',
|
|
259
|
-
message: 'Enter the project description:'
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
console.log("\nDescription saved.\n");
|
|
263
|
-
return response.value || "*Project description goes here*";
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
return descricao;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
function detectarTipoProjeto(packageJson) {
|
|
270
|
-
const deps = {
|
|
271
|
-
...packageJson.dependencies,
|
|
272
|
-
...packageJson.devDependencies
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
if (deps.react) return "Frontend React"
|
|
276
|
-
if (deps.next) return "Next.js Application"
|
|
277
|
-
if (deps.express) return "API REST (Express)"
|
|
278
|
-
if (deps.typescript) return "Projeto TypeScript"
|
|
279
|
-
|
|
280
|
-
return "Node.js Project"
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
function formatScripts(scripts) {
|
|
284
|
-
if (!scripts || Object.keys(scripts).length === 0) {
|
|
285
|
-
return "No scripts available.\n";
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
return Object.entries(scripts)
|
|
289
|
-
.map(([name, script]) => `- ${name} -> ${script}`)
|
|
290
|
-
.join("\n");
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
function detectarEnvVars(projectRoot) {
|
|
294
|
-
const envPath = path.join(projectRoot, ".env")
|
|
295
|
-
|
|
296
|
-
if (!fs.existsSync(envPath)) return []
|
|
297
|
-
|
|
298
|
-
const content = fs.readFileSync(envPath, "utf-8")
|
|
299
|
-
|
|
300
|
-
const vars = content
|
|
301
|
-
.split("\n")
|
|
302
|
-
.map(line => line.trim())
|
|
303
|
-
.filter(line =>
|
|
304
|
-
line &&
|
|
305
|
-
!line.startsWith("#") &&
|
|
306
|
-
line.includes("=")
|
|
307
|
-
)
|
|
308
|
-
.map(line => line.replace(/^export\s+/, ""))
|
|
309
|
-
.map(line => line.split("=")[0].trim())
|
|
310
|
-
|
|
311
|
-
return vars
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
function gerarEnvSection(vars) {
|
|
315
|
-
if (!vars.length) return ""
|
|
316
|
-
|
|
317
|
-
let section = "## π Environment Variables\n\n"
|
|
318
|
-
section += "Create a `.env` file in the project root with the following variables:\n\n"
|
|
319
|
-
|
|
320
|
-
vars.forEach(v => {
|
|
321
|
-
section += `- ${v}\n`
|
|
322
|
-
})
|
|
323
|
-
|
|
324
|
-
return section + "\n"
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
function detectarPorta(scanData) {
|
|
328
|
-
const filesToScan = [...scanData.jsFiles, ...scanData.tsFiles]
|
|
329
|
-
|
|
330
|
-
for (const filePath of filesToScan) {
|
|
331
|
-
try {
|
|
332
|
-
const content = fs.readFileSync(filePath, "utf-8")
|
|
333
|
-
|
|
334
|
-
// π Regex robusta: pega .listen(...) mesmo com quebra de linha
|
|
335
|
-
const listenRegex = /\.listen\s*\(\s*([\s\S]*?)\)/g
|
|
336
|
-
|
|
337
|
-
let match
|
|
338
|
-
|
|
339
|
-
while ((match = listenRegex.exec(content)) !== null) {
|
|
340
|
-
const rawArgument = match[1].split(",")[0].trim()
|
|
341
|
-
|
|
342
|
-
// =============================
|
|
343
|
-
// β
1οΈβ£ NΓΊmero direto
|
|
344
|
-
// =============================
|
|
345
|
-
const directNumber = rawArgument.match(/^\d+$/)
|
|
346
|
-
if (directNumber) {
|
|
347
|
-
return directNumber[0]
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// =============================
|
|
351
|
-
// β
2οΈβ£ Fallback inline
|
|
352
|
-
// =============================
|
|
353
|
-
const inlineFallback = rawArgument.match(/\|\|\s*(\d+)/)
|
|
354
|
-
if (inlineFallback) {
|
|
355
|
-
return inlineFallback[1]
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
// =============================
|
|
359
|
-
// β
3οΈβ£ process.env.PORT
|
|
360
|
-
// =============================
|
|
361
|
-
if (rawArgument.includes("process.env.PORT")) {
|
|
362
|
-
return "process.env.PORT"
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// =============================
|
|
366
|
-
// β
4οΈβ£ Resolver variΓ‘vel
|
|
367
|
-
// =============================
|
|
368
|
-
const variableName = rawArgument.replace(/[^a-zA-Z0-9_]/g, "")
|
|
369
|
-
|
|
370
|
-
if (!variableName) continue
|
|
371
|
-
|
|
372
|
-
const variableRegex = new RegExp(
|
|
373
|
-
`(const|let|var)\\s+${variableName}\\s*=\\s*([\\s\\S]*?);`
|
|
374
|
-
)
|
|
375
|
-
|
|
376
|
-
const variableMatch = content.match(variableRegex)
|
|
377
|
-
|
|
378
|
-
if (variableMatch) {
|
|
379
|
-
const variableValue = variableMatch[2]
|
|
380
|
-
|
|
381
|
-
const fallbackMatch = variableValue.match(/\|\|\s*(\d+)/)
|
|
382
|
-
if (fallbackMatch) {
|
|
383
|
-
return fallbackMatch[1]
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
const numberMatch = variableValue.match(/\d+/)
|
|
387
|
-
if (numberMatch) {
|
|
388
|
-
return numberMatch[0]
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
} catch (err) {
|
|
394
|
-
continue
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
return null
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
async function perguntarPortaManual() {
|
|
402
|
-
const response = await prompts({
|
|
403
|
-
type: "text",
|
|
404
|
-
name: "port",
|
|
405
|
-
message: "β οΈ NΓ£o consegui detectar a porta automaticamente.\nDigite a porta da API (ou deixe vazio para pular):",
|
|
406
|
-
validate: value => {
|
|
407
|
-
if (!value) return true
|
|
408
|
-
return /^\d+$/.test(value) || "Digite apenas nΓΊmeros"
|
|
409
|
-
}
|
|
410
|
-
})
|
|
411
|
-
|
|
412
|
-
return response.port || null
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
function scanProjectFiles(projectRoot) {
|
|
416
|
-
const result = {
|
|
417
|
-
allFiles: [],
|
|
418
|
-
jsFiles: [],
|
|
419
|
-
tsFiles: [],
|
|
420
|
-
envFiles: [],
|
|
421
|
-
hasDockerfile: false,
|
|
422
|
-
hasPrisma: false,
|
|
423
|
-
hasSrcFolder: false,
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
function walk(dir) {
|
|
427
|
-
let files
|
|
428
|
-
try {
|
|
429
|
-
files = fs.readdirSync(dir)
|
|
430
|
-
} catch {
|
|
431
|
-
return
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
for (const file of files) {
|
|
435
|
-
const fullPath = path.join(dir, file)
|
|
436
|
-
|
|
437
|
-
// ignorar node_modules e .git
|
|
438
|
-
if (
|
|
439
|
-
fullPath.includes("node_modules") ||
|
|
440
|
-
fullPath.includes(".git")
|
|
441
|
-
) continue
|
|
442
|
-
|
|
443
|
-
let stat
|
|
444
|
-
try {
|
|
445
|
-
const stat = fs.lstatSync(fullPath)
|
|
446
|
-
|
|
447
|
-
if (stat.isSymbolicLink()) continue
|
|
448
|
-
} catch {
|
|
449
|
-
continue
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
if (stat.isDirectory()) {
|
|
453
|
-
if (file === "src") {
|
|
454
|
-
result.hasSrcFolder = true
|
|
455
|
-
}
|
|
456
|
-
walk(fullPath)
|
|
457
|
-
} else {
|
|
458
|
-
result.allFiles.push(fullPath)
|
|
459
|
-
|
|
460
|
-
if (file.endsWith(".js")) result.jsFiles.push(fullPath)
|
|
461
|
-
if (file.endsWith(".ts")) result.tsFiles.push(fullPath)
|
|
462
|
-
if (file.startsWith(".env")) result.envFiles.push(fullPath)
|
|
463
|
-
|
|
464
|
-
if (file === "Dockerfile") result.hasDockerfile = true
|
|
465
|
-
if (fullPath.includes("prisma")) result.hasPrisma = true
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
walk(projectRoot)
|
|
471
|
-
|
|
472
|
-
return result
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
function gerarGettingStarted(packageManager = "npm", scripts = {}, hasPrisma) {
|
|
476
|
-
const lines = []
|
|
477
|
-
|
|
478
|
-
lines.push(
|
|
479
|
-
packageManager === "npm"
|
|
480
|
-
? "npm install"
|
|
481
|
-
: `${packageManager} install`
|
|
482
|
-
)
|
|
483
|
-
|
|
484
|
-
if (hasPrisma) {
|
|
485
|
-
lines.push("npx prisma migrate dev")
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
if (scripts.dev) {
|
|
489
|
-
lines.push(getRunCommand("dev", packageManager))
|
|
490
|
-
} else if (scripts.start) {
|
|
491
|
-
lines.push(getRunCommand("start", packageManager))
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
return `
|
|
495
|
-
## π Getting Started
|
|
496
|
-
|
|
497
|
-
\`\`\`bash
|
|
498
|
-
${lines.join("\n")}
|
|
499
|
-
\`\`\`
|
|
500
|
-
|
|
501
|
-
`
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
function getRunCommand(script, packageManager) {
|
|
506
|
-
if (packageManager === "yarn") return `yarn ${script}`
|
|
507
|
-
if (packageManager === "pnpm") return `pnpm ${script}`
|
|
508
|
-
return `npm run ${script}`
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
async function generateReadme(packageJson, tree, config){
|
|
514
|
-
|
|
515
|
-
const deps = {
|
|
516
|
-
...packageJson.dependencies,
|
|
517
|
-
...packageJson.devDependencies
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
const techStack = detectarTechStack(deps)
|
|
521
|
-
const techSection = gerarTechStackSection(techStack)
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
const envVars = detectarEnvVars(projectRoot)
|
|
527
|
-
const envSection = gerarEnvSection(envVars)
|
|
528
|
-
|
|
529
|
-
const nomeProjeto = await buscarNome(packageJson.name);
|
|
530
|
-
const descricaoProjeto = await buscarDescricao(packageJson.description);
|
|
531
|
-
const idioma = await escolherLingua()
|
|
532
|
-
const t = i18n[idioma] || i18n.en
|
|
533
|
-
|
|
534
|
-
const packageManager = detectarPackageManager(projectRoot)
|
|
535
|
-
|
|
536
|
-
const scanData = scanProjectFiles(projectRoot)
|
|
537
|
-
let port = detectarPorta(scanData)
|
|
538
|
-
|
|
539
|
-
if (!port) {
|
|
540
|
-
port = await perguntarPortaManual()
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
const commands = analisarScripts(packageJson.scripts, packageManager)
|
|
544
|
-
|
|
545
|
-
const hasPrisma = detectarPrisma(projectRoot, packageJson)
|
|
546
|
-
const dbSection = hasPrisma ? gerarDatabaseSection(packageManager) : ""
|
|
547
|
-
|
|
548
|
-
const gettingStartedCommands = gerarGettingStarted(
|
|
549
|
-
packageManager,
|
|
550
|
-
packageJson.scripts,
|
|
551
|
-
hasPrisma
|
|
552
|
-
)
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
const content = `
|
|
557
|
-
# ${nomeProjeto}
|
|
558
|
-
|
|
559
|
-
${descricaoProjeto}
|
|
560
|
-
|
|
561
|
-
## ${config.emojis ? "π" : ""} ${t.projectInfo}
|
|
562
|
-
- **${t.version}:** ${packageJson.version || "Not specified"}
|
|
563
|
-
- **${t.packageManager}:** ${packageManager}
|
|
564
|
-
- **${t.type}:** ${detectarTipoProjeto(packageJson)}
|
|
565
|
-
|
|
566
|
-
${techSection}
|
|
567
|
-
|
|
568
|
-
## ${config.emojis ? "π" : ""} ${t.projectStructure}
|
|
569
|
-
\`\`\`
|
|
570
|
-
${tree}
|
|
571
|
-
\`\`\`
|
|
572
|
-
|
|
573
|
-
${gettingStartedCommands}
|
|
574
|
-
|
|
575
|
-
${envSection}
|
|
576
|
-
${dbSection}
|
|
577
|
-
|
|
578
|
-
${port ? `
|
|
579
|
-
## π Server
|
|
580
|
-
|
|
581
|
-
After starting, the server will run at:
|
|
582
|
-
|
|
583
|
-
http://localhost:${port}
|
|
584
|
-
|
|
585
|
-
` : ""}
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
---
|
|
589
|
-
|
|
590
|
-
${t.generatedBy} **mdSmith**
|
|
591
|
-
`
|
|
592
|
-
|
|
593
|
-
return content
|
|
594
|
-
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
function detectarPrisma(projectRoot, packageJson) {
|
|
598
|
-
const deps = {
|
|
599
|
-
...packageJson.dependencies,
|
|
600
|
-
...packageJson.devDependencies
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
const hasPrismaDep = deps.prisma || deps["@prisma/client"]
|
|
604
|
-
const hasPrismaFolder = fs.existsSync(path.join(projectRoot, "prisma"))
|
|
605
|
-
|
|
606
|
-
return hasPrismaDep && hasPrismaFolder
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
function gerarDatabaseSection(packageManager) {
|
|
610
|
-
let section = "## π Database Setup\n\n"
|
|
611
|
-
section += "Run Prisma migrations:\n\n"
|
|
612
|
-
section += "```bash\n"
|
|
613
|
-
|
|
614
|
-
if (packageManager === "npm") {
|
|
615
|
-
section += "npx prisma migrate dev\n"
|
|
616
|
-
section += "npx prisma generate\n"
|
|
617
|
-
} else {
|
|
618
|
-
section += "npx prisma migrate dev\n"
|
|
619
|
-
section += "npx prisma generate\n"
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
section += "```\n\n"
|
|
623
|
-
|
|
624
|
-
return section
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
async function escolherLingua() {
|
|
630
|
-
const response = await prompts({
|
|
631
|
-
type: 'select',
|
|
632
|
-
name: 'lang',
|
|
633
|
-
message: 'Choose README language',
|
|
634
|
-
choices: [
|
|
635
|
-
{ title: 'English', value: 'en' },
|
|
636
|
-
{ title: 'PortuguΓͺs', value: 'pt' },
|
|
637
|
-
{ title: 'EspaΓ±ol', value: 'es' }
|
|
638
|
-
],
|
|
639
|
-
initial: 0
|
|
640
|
-
});
|
|
641
|
-
|
|
642
|
-
return response.lang || 'en';
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
function loadConfig(projectRoot) {
|
|
646
|
-
const configPath = path.join(projectRoot, "mdsmith.config.json")
|
|
647
|
-
|
|
648
|
-
if (!fs.existsSync(configPath)) {
|
|
649
|
-
return defaultConfig
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
try {
|
|
653
|
-
const fileContent = fs.readFileSync(configPath, "utf-8")
|
|
654
|
-
const userConfig = JSON.parse(fileContent)
|
|
655
|
-
|
|
656
|
-
return {
|
|
657
|
-
...defaultConfig,
|
|
658
|
-
...userConfig,
|
|
659
|
-
ignore: [
|
|
660
|
-
...defaultConfig.ignore,
|
|
661
|
-
...(userConfig.ignore || [])
|
|
662
|
-
]
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
} catch (error) {
|
|
667
|
-
console.log("Failed to read mdsmith.config.json. Using default configuration.")
|
|
668
|
-
return defaultConfig
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
function analisarProjeto(packageJson, projectRoot) {
|
|
673
|
-
const deps = {
|
|
674
|
-
...packageJson.dependencies,
|
|
675
|
-
...packageJson.devDependencies
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
const analysis = {
|
|
679
|
-
frontend: deps.react ? "React" :
|
|
680
|
-
deps.next ? "Next.js" :
|
|
681
|
-
null,
|
|
682
|
-
|
|
683
|
-
backend: deps.express ? "Express" :
|
|
684
|
-
deps.fastify ? "Fastify" :
|
|
685
|
-
null,
|
|
686
|
-
|
|
687
|
-
language: deps.typescript ? "TypeScript" : "JavaScript",
|
|
688
|
-
|
|
689
|
-
bundler: deps.vite ? "Vite" :
|
|
690
|
-
deps.webpack ? "Webpack" :
|
|
691
|
-
null,
|
|
692
|
-
|
|
693
|
-
styling: deps.tailwindcss ? "TailwindCSS" :
|
|
694
|
-
deps.sass ? "Sass" :
|
|
695
|
-
null,
|
|
696
|
-
|
|
697
|
-
database: deps.mongoose ? "MongoDB" :
|
|
698
|
-
deps.prisma ? "Prisma" :
|
|
699
|
-
deps.pg ? "PostgreSQL" :
|
|
700
|
-
null,
|
|
701
|
-
|
|
702
|
-
testing: deps.jest ? "Jest" :
|
|
703
|
-
deps.vitest ? "Vitest" :
|
|
704
|
-
null,
|
|
705
|
-
|
|
706
|
-
linting: deps.eslint ? "ESLint" : null,
|
|
707
|
-
|
|
708
|
-
formatting: deps.prettier ? "Prettier" : null,
|
|
709
|
-
|
|
710
|
-
node: detectarNodeVersion(projectRoot, packageJson)
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
if (analysis.frontend && analysis.backend) {
|
|
714
|
-
analysis.architecture = "Fullstack"
|
|
715
|
-
} else if (analysis.frontend) {
|
|
716
|
-
analysis.architecture = "Frontend"
|
|
717
|
-
} else if (analysis.backend) {
|
|
718
|
-
analysis.architecture = "Backend"
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
return analysis
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
function detectarPackageManager(projectRoot) {
|
|
725
|
-
if (fs.existsSync(path.join(projectRoot, "pnpm-lock.yaml"))) {
|
|
726
|
-
return "pnpm"
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
if (fs.existsSync(path.join(projectRoot, "yarn.lock"))) {
|
|
730
|
-
return "yarn"
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
if (fs.existsSync(path.join(projectRoot, "package-lock.json"))) {
|
|
734
|
-
return "npm"
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
return "npm"
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
function analisarScripts(scripts = {}, packageManager) {
|
|
741
|
-
const commands = {
|
|
742
|
-
install: packageManager === "npm"
|
|
743
|
-
? "npm install"
|
|
744
|
-
: `${packageManager} install`
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
if (scripts.dev) {
|
|
748
|
-
commands.dev = `${packageManager} run dev`
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
if (scripts.build) {
|
|
752
|
-
commands.build = `${packageManager} run build`
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
if (scripts.start) {
|
|
756
|
-
commands.start = packageManager === "npm"
|
|
757
|
-
? "npm start"
|
|
758
|
-
: `${packageManager} start`
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
if (scripts.preview) {
|
|
762
|
-
commands.preview = `${packageManager} run preview`
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
return commands
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
function diagnosticarExecucao(commands) {
|
|
769
|
-
const warnings = []
|
|
770
|
-
|
|
771
|
-
if (!commands.dev && !commands.start) {
|
|
772
|
-
warnings.push("No development or start script found.")
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
if (commands.build && !commands.start) {
|
|
776
|
-
warnings.push("Build script found but no start script for production.")
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
return warnings
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
function detectarNodeVersion(projectRoot, packageJson) {
|
|
783
|
-
if (packageJson.engines && packageJson.engines.node) {
|
|
784
|
-
return packageJson.engines.node
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
const nvmrcPath = path.join(projectRoot, ".nvmrc")
|
|
788
|
-
if (fs.existsSync(nvmrcPath)) {
|
|
789
|
-
return fs.readFileSync(nvmrcPath, "utf-8").trim()
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
const nodeVersionPath = path.join(projectRoot, ".node-version")
|
|
793
|
-
if (fs.existsSync(nodeVersionPath)) {
|
|
794
|
-
return fs.readFileSync(nodeVersionPath, "utf-8").trim()
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
return process.version
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
function detectarTechStack(deps = {}) {
|
|
801
|
-
const stack = new Set()
|
|
802
|
-
|
|
803
|
-
for (const dep in deps) {
|
|
804
|
-
if (TECH_MAP[dep]) {
|
|
805
|
-
stack.add(TECH_MAP[dep])
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
return Array.from(stack).sort()
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
function gerarTechStackSection(stack) {
|
|
813
|
-
if (!stack.length) return ""
|
|
814
|
-
|
|
815
|
-
let section = "## π Tech Stack\n\n"
|
|
816
|
-
|
|
817
|
-
stack.forEach(tech => {
|
|
818
|
-
section += `- ${tech}\n`
|
|
819
|
-
})
|
|
820
|
-
|
|
821
|
-
return section + "\n"
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
function formatarAnalise(analysis) {
|
|
826
|
-
console.log(`
|
|
827
|
-
Project Analysis
|
|
828
|
-
ββββββββββββββββββββββββ
|
|
829
|
-
`)
|
|
830
|
-
|
|
831
|
-
const entries = Object.entries(analysis)
|
|
832
|
-
|
|
833
|
-
for (const [key, value] of entries) {
|
|
834
|
-
if (value) {
|
|
835
|
-
const label = key.charAt(0).toUpperCase() + key.slice(1)
|
|
836
|
-
console.log(`β ${label}: ${value}`)
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
console.log("")
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
function formatarExecucao(commands, warnings) {
|
|
844
|
-
console.log(`Project Execution Strategy
|
|
845
|
-
ββββββββββββββββββββββββ`)
|
|
846
|
-
|
|
847
|
-
console.log(`Install:`)
|
|
848
|
-
console.log(` ${commands.install}\n`)
|
|
849
|
-
|
|
850
|
-
if (commands.dev) {
|
|
851
|
-
console.log(`Development:`)
|
|
852
|
-
console.log(` ${commands.dev}\n`)
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
if (commands.build && commands.start) {
|
|
856
|
-
console.log(`Production:`)
|
|
857
|
-
console.log(` ${commands.build}`)
|
|
858
|
-
console.log(` ${commands.start}\n`)
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
if (commands.preview) {
|
|
862
|
-
console.log(`Preview:`)
|
|
863
|
-
console.log(` ${commands.preview}\n`)
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
if (warnings.length > 0) {
|
|
867
|
-
console.log(`Warnings:`)
|
|
868
|
-
warnings.forEach(w => console.log(` β ${w}`))
|
|
869
|
-
console.log()
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
async function main() {
|
|
876
|
-
const config = loadConfig(projectRoot)
|
|
877
|
-
|
|
878
|
-
if(args.length == 0){
|
|
879
|
-
console.log(`
|
|
880
|
-
mdSmith
|
|
881
|
-
Node.js project analyzer
|
|
882
|
-
ββββββββββββββββββββββββ
|
|
883
|
-
|
|
884
|
-
Run "mdsmith --help" to view available commands.
|
|
885
|
-
`);
|
|
886
|
-
process.exit(0);
|
|
887
|
-
}else if (args.includes("--init")) {
|
|
888
|
-
|
|
889
|
-
const configPath = path.join(projectRoot, "mdsmith.config.json")
|
|
890
|
-
|
|
891
|
-
if (fs.existsSync(configPath)) {
|
|
892
|
-
console.log("mdsmith.config.json already exists.")
|
|
893
|
-
process.exit(0)
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
fs.writeFileSync(
|
|
897
|
-
configPath,
|
|
898
|
-
JSON.stringify(defaultConfig, null, 2)
|
|
899
|
-
)
|
|
900
|
-
|
|
901
|
-
console.log("Configuration file created.")
|
|
902
|
-
process.exit(0)
|
|
903
|
-
|
|
904
|
-
} else if(args.includes("--help")){
|
|
905
|
-
console.log(`
|
|
906
|
-
mdSmith β Available Commands
|
|
907
|
-
ββββββββββββββββββββββββ
|
|
908
|
-
|
|
909
|
-
--help Show help
|
|
910
|
-
--init Create config file
|
|
911
|
-
--tree Show project structure
|
|
912
|
-
--deps List dependencies
|
|
913
|
-
--readme Generate README
|
|
914
|
-
--analyze Project analysis
|
|
915
|
-
`)
|
|
916
|
-
process.exit(0)
|
|
917
|
-
} else if (args.includes("--tree")){
|
|
918
|
-
console.log(`
|
|
919
|
-
Project Structure
|
|
920
|
-
ββββββββββββββββββββββββ
|
|
921
|
-
`);
|
|
922
|
-
console.log(scanDir(projectRoot, 0, config))
|
|
923
|
-
process.exit(0)
|
|
924
|
-
} else if (args.includes("--analyze")){
|
|
925
|
-
const analysis = analisarProjeto(packageJson, projectRoot)
|
|
926
|
-
const packageManager = detectarPackageManager(projectRoot)
|
|
927
|
-
|
|
928
|
-
formatarAnalise(analysis)
|
|
929
|
-
|
|
930
|
-
const commands = analisarScripts(packageJson.scripts, packageManager)
|
|
931
|
-
const warnings = diagnosticarExecucao(commands)
|
|
932
|
-
|
|
933
|
-
formatarExecucao(commands, warnings)
|
|
934
|
-
|
|
935
|
-
const issues = healthChecks(packageJson, projectRoot, analysis)
|
|
936
|
-
|
|
937
|
-
if (issues.length > 0) {
|
|
938
|
-
console.log("Health Checks")
|
|
939
|
-
console.log("ββββββββββββββββββββββββ")
|
|
940
|
-
issues.forEach(issue => {
|
|
941
|
-
let icon = "β "
|
|
942
|
-
|
|
943
|
-
if (issue.type === "critical") icon = "β"
|
|
944
|
-
if (issue.type === "info") icon = "βΉ"
|
|
945
|
-
|
|
946
|
-
console.log(`${icon} ${issue.message}`)
|
|
947
|
-
})
|
|
948
|
-
console.log()
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
process.exit(0)
|
|
952
|
-
} else if (args.includes("--deps")){
|
|
953
|
-
console.log(`
|
|
954
|
-
Dependencies
|
|
955
|
-
ββββββββββββββββββββββββ
|
|
956
|
-
`)
|
|
957
|
-
const deps = formatDependencies(packageJson.dependencies)
|
|
958
|
-
console.log(`${deps}\n`)
|
|
959
|
-
console.log()
|
|
960
|
-
process.exit(0)
|
|
961
|
-
} else if (args.includes("--readme")){
|
|
962
|
-
const content = await generateReadme(packageJson, scanDir(projectRoot, 0, config), config)
|
|
963
|
-
|
|
964
|
-
console.log(`
|
|
965
|
-
README Preview
|
|
966
|
-
ββββββββββββββββββββββββ
|
|
967
|
-
`)
|
|
968
|
-
|
|
969
|
-
console.log(content)
|
|
970
|
-
|
|
971
|
-
const confirmResponse = await prompts({
|
|
972
|
-
type: 'confirm',
|
|
973
|
-
name: 'generate',
|
|
974
|
-
message: 'Generate README-MDSMITH.md?',
|
|
975
|
-
initial: true
|
|
976
|
-
});
|
|
977
|
-
|
|
978
|
-
if (confirmResponse.generate) {
|
|
979
|
-
fs.writeFileSync("README-MDSMITH.md", content);
|
|
980
|
-
console.log("\nREADME-MDSMITH.md created.\n");
|
|
981
|
-
} else {
|
|
982
|
-
console.log("\nOperation cancelled.\n");
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
process.exit(0);
|
|
986
|
-
|
|
987
|
-
} else {
|
|
988
|
-
console.log(`
|
|
989
|
-
Unknown command.
|
|
990
|
-
Run "mdsmith --help" for usage.
|
|
991
|
-
`)
|
|
992
|
-
process.exit(0)
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
main()
|
|
997
|
-
|