zenithix 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/index.js +244 -0
- package/package.json +32 -0
package/index.js
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import select from '@inquirer/select';
|
|
4
|
+
import checkbox from '@inquirer/checkbox';
|
|
5
|
+
import input from '@inquirer/input';
|
|
6
|
+
import { cyan, green, red, bold, reset, gray } from 'kolorist';
|
|
7
|
+
import figures from 'figures';
|
|
8
|
+
import ora from 'ora';
|
|
9
|
+
import degit from 'degit';
|
|
10
|
+
import fs from 'fs-extra';
|
|
11
|
+
import { execa } from 'execa';
|
|
12
|
+
import path from 'path';
|
|
13
|
+
|
|
14
|
+
let currentLang = 'pt-BR';
|
|
15
|
+
|
|
16
|
+
const content = {
|
|
17
|
+
'pt-BR': {
|
|
18
|
+
title: '💎 Zenithix CLI 📦 1.0.0',
|
|
19
|
+
mainMenu: 'Menu principal',
|
|
20
|
+
optStart: 'Iniciar projeto de bot de discord',
|
|
21
|
+
optConfig: '≡ Configurações',
|
|
22
|
+
optExit: '× Sair',
|
|
23
|
+
configTitle: 'Configurações',
|
|
24
|
+
optLang: 'Idioma',
|
|
25
|
+
optBack: 'Voltar',
|
|
26
|
+
langSelect: 'Alterar idioma da CLI',
|
|
27
|
+
bye: '\n👋 Valeu por usar a Zenithix CLI!\n🤝 Discord: http://discord.gg/tTu8dGN\n',
|
|
28
|
+
social: `\n👋 Discord: ${cyan('http://discord.gg/tTu8dGN')}\n🐱 Github /`
|
|
29
|
+
},
|
|
30
|
+
'en-US': {
|
|
31
|
+
title: '💎 Zenithix CLI 📦 1.0.0',
|
|
32
|
+
mainMenu: 'Main Menu',
|
|
33
|
+
optStart: 'Start Discord bot project',
|
|
34
|
+
optConfig: '≡ Settings',
|
|
35
|
+
optExit: '× Exit',
|
|
36
|
+
configTitle: 'Settings',
|
|
37
|
+
optLang: 'Language',
|
|
38
|
+
optBack: 'Back',
|
|
39
|
+
langSelect: 'Change CLI language',
|
|
40
|
+
bye: '\n👋 Thanks for using Zenithix CLI!\n🤝 Discord: http://discord.gg/tTu8dGN\n',
|
|
41
|
+
social: `\n👋 Discord: ${cyan('http://discord.gg/tTu8dGN')}\n🐱 Github /`
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
function clearConsole() {
|
|
46
|
+
console.clear();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function drawHeader(path = '') {
|
|
50
|
+
clearConsole();
|
|
51
|
+
const t = content[currentLang];
|
|
52
|
+
console.log(cyan(bold(t.title)));
|
|
53
|
+
console.log(`${cyan('🔹 ' + t.mainMenu)} ${path}\n`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function mainMenu() {
|
|
57
|
+
drawHeader();
|
|
58
|
+
const t = content[currentLang];
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const value = await select({
|
|
62
|
+
message: ' ',
|
|
63
|
+
choices: [
|
|
64
|
+
{ name: green(t.optStart), value: 'start' },
|
|
65
|
+
{ name: cyan(t.optConfig), value: 'config' },
|
|
66
|
+
{ name: red(t.optExit), value: 'exit' },
|
|
67
|
+
],
|
|
68
|
+
theme: { prefix: '' }
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
switch (value) {
|
|
72
|
+
case 'start': await createBotFlow(); break;
|
|
73
|
+
case 'config': await configMenu(); break;
|
|
74
|
+
case 'exit':
|
|
75
|
+
console.log(cyan(t.bye));
|
|
76
|
+
process.exit();
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
} catch (error) {
|
|
80
|
+
if (error.name === 'ExitPromptError') {
|
|
81
|
+
console.log(cyan('\n' + t.bye));
|
|
82
|
+
process.exit(0);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function createBotFlow() {
|
|
88
|
+
const t = content[currentLang];
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
drawHeader(`› ${t.optStart}`);
|
|
92
|
+
|
|
93
|
+
const currentFolder = path.basename(process.cwd());
|
|
94
|
+
|
|
95
|
+
// 1. Pergunta do Nome com lógica de sumir o ./
|
|
96
|
+
const nameInput = await input({
|
|
97
|
+
message: `📂 Nome do projeto ${reset(cyan(`${currentFolder}/`))}`,
|
|
98
|
+
default: './',
|
|
99
|
+
theme: {
|
|
100
|
+
prefix: cyan('◇'),
|
|
101
|
+
},
|
|
102
|
+
// O transformer agora retorna vazio quando isFinal é true,
|
|
103
|
+
// garantindo que o "./" não fique sobrando na tela.
|
|
104
|
+
transformer: (value, { isFinal }) => {
|
|
105
|
+
if (isFinal) return '';
|
|
106
|
+
return cyan(value);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Define o nome real: se for ./ usa a pasta atual, senão usa o que escreveu
|
|
111
|
+
const name = (nameInput === './') ? currentFolder : nameInput;
|
|
112
|
+
const targetDir = (nameInput === './') ? process.cwd() : path.join(process.cwd(), name);
|
|
113
|
+
|
|
114
|
+
// Mostra o "verificado" com o nome escolhido logo abaixo, como na sua imagem
|
|
115
|
+
console.log(`${green(' ' + figures.tick)} ${bold(cyan(name))}\n`);
|
|
116
|
+
|
|
117
|
+
// 2. Pergunta do Banco
|
|
118
|
+
const db = await select({
|
|
119
|
+
message: '🧰 Predefinição de banco de dados',
|
|
120
|
+
choices: [
|
|
121
|
+
{ name: red('Nenhum'), value: 'none' },
|
|
122
|
+
{ name: 'MongoDB 🍃 (mongoose)', value: 'mongo' }
|
|
123
|
+
],
|
|
124
|
+
theme: { prefix: cyan('◇') }
|
|
125
|
+
});
|
|
126
|
+
console.log('');
|
|
127
|
+
|
|
128
|
+
// 3. Pergunta dos Extras
|
|
129
|
+
const extras = await checkbox({
|
|
130
|
+
message: '✨ Recursos extras',
|
|
131
|
+
choices: [{ name: '☁️ Arquivos Discloud', value: 'discloud', checked: true }],
|
|
132
|
+
theme: {
|
|
133
|
+
prefix: cyan('◇'),
|
|
134
|
+
icon: { checked: green(figures.circleFilled), unchecked: figures.circle, cursor: '›' }
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
console.log('');
|
|
138
|
+
|
|
139
|
+
// 4. Pergunta das Dependências
|
|
140
|
+
const deps = await select({
|
|
141
|
+
message: `🚢 Instalar dependências? ${reset(gray('npm'))}`,
|
|
142
|
+
choices: [{ name: green('Sim'), value: true }, { name: red('Não'), value: false }],
|
|
143
|
+
theme: { prefix: cyan('◇') }
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
console.log('');
|
|
147
|
+
const loader = ora('Gerando projeto...').start();
|
|
148
|
+
|
|
149
|
+
try {
|
|
150
|
+
const emitter = degit('https://github.com/FTWmuggui/zenithix-template.git', { force: true });
|
|
151
|
+
await emitter.clone(targetDir);
|
|
152
|
+
|
|
153
|
+
const pkgPath = path.join(targetDir, 'package.json');
|
|
154
|
+
const envJsPath = path.join(targetDir, 'src/settings/env.js');
|
|
155
|
+
const botIndexPath = path.join(targetDir, 'src/index.js');
|
|
156
|
+
const dbPath = path.join(targetDir, 'src/database');
|
|
157
|
+
const envFiles = [path.join(targetDir, '.env'), path.join(targetDir, '.env.dev')];
|
|
158
|
+
|
|
159
|
+
const pkg = await fs.readJson(pkgPath);
|
|
160
|
+
pkg.name = name.toLowerCase().replace(/\s+/g, '-');
|
|
161
|
+
|
|
162
|
+
if (db === 'none') {
|
|
163
|
+
await fs.remove(dbPath);
|
|
164
|
+
if (await fs.pathExists(envJsPath)) {
|
|
165
|
+
let envJs = await fs.readFile(envJsPath, 'utf8');
|
|
166
|
+
envJs = envJs.replace(/MONGO_URI: z\.string\(.*\)\.min\(1\),?/g, '');
|
|
167
|
+
envJs = envJs.replace(/MONGO_URI: process\.env\.MONGO_URI,?/g, '');
|
|
168
|
+
await fs.writeFile(envJsPath, envJs);
|
|
169
|
+
}
|
|
170
|
+
for (const file of envFiles) {
|
|
171
|
+
if (await fs.pathExists(file)) {
|
|
172
|
+
let envContent = await fs.readFile(file, 'utf8');
|
|
173
|
+
envContent = envContent.replace(/MONGO_URI=.*\n?/g, '');
|
|
174
|
+
await fs.writeFile(file, envContent);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (await fs.pathExists(botIndexPath)) {
|
|
178
|
+
let botIdx = await fs.readFile(botIndexPath, 'utf8');
|
|
179
|
+
botIdx = botIdx.replace(/import\s+"\.\/database\/index\.js";/g, '// Database disabled');
|
|
180
|
+
await fs.writeFile(botIndexPath, botIdx);
|
|
181
|
+
}
|
|
182
|
+
delete pkg.dependencies['mongoose'];
|
|
183
|
+
delete pkg.dependencies['mongodb'];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (!extras.includes('discloud')) {
|
|
187
|
+
await fs.remove(path.join(targetDir, 'discloud.config'));
|
|
188
|
+
await fs.remove(path.join(targetDir, '.discloudignore'));
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
192
|
+
loader.succeed(green('Projeto gerado com sucesso!'));
|
|
193
|
+
|
|
194
|
+
if (deps) {
|
|
195
|
+
const iLoader = ora('Instalando dependências...').start();
|
|
196
|
+
try {
|
|
197
|
+
await execa('npm', ['install'], { cwd: targetDir });
|
|
198
|
+
iLoader.succeed(green('Dependências instaladas com sucesso!'));
|
|
199
|
+
} catch (e) {
|
|
200
|
+
iLoader.fail(red('Erro ao instalar dependências.'));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
console.log(`\n${green('✔')} ${bold('Bot configurado com sucesso!')}`);
|
|
205
|
+
console.log(t.social);
|
|
206
|
+
|
|
207
|
+
} catch (err) {
|
|
208
|
+
loader.fail(red('Erro ao gerar projeto: ' + err.message));
|
|
209
|
+
}
|
|
210
|
+
} catch (e) { process.exit(0); }
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async function configMenu() {
|
|
214
|
+
const t = content[currentLang];
|
|
215
|
+
drawHeader(`› ${t.configTitle}`);
|
|
216
|
+
try {
|
|
217
|
+
const v = await select({
|
|
218
|
+
message: '\u200B',
|
|
219
|
+
choices: [{ name: `🌐 ${t.optLang}`, value: 'l' }, { name: `↵ ${t.optBack}`, value: 'b' }],
|
|
220
|
+
theme: { prefix: '' }
|
|
221
|
+
});
|
|
222
|
+
if (v === 'l') await langMenu(); else await mainMenu();
|
|
223
|
+
} catch (e) { process.exit(0); }
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async function langMenu() {
|
|
227
|
+
const t = content[currentLang];
|
|
228
|
+
drawHeader(`› ${t.configTitle} › ${t.optLang}`);
|
|
229
|
+
try {
|
|
230
|
+
const v = await select({
|
|
231
|
+
message: cyan(`🔹 ${t.langSelect}`),
|
|
232
|
+
choices: [
|
|
233
|
+
{ name: '\x1b[32m💚 Português (BR)\x1b[0m', value: 'pt-BR' },
|
|
234
|
+
{ name: '\x1b[36m🦅 Inglês (US)\x1b[0m', value: 'en-US' },
|
|
235
|
+
{ name: '↵ Voltar', value: 'back' }
|
|
236
|
+
],
|
|
237
|
+
theme: { prefix: '' }
|
|
238
|
+
});
|
|
239
|
+
if (v && v !== 'back') { currentLang = v; await langMenu(); }
|
|
240
|
+
else await configMenu();
|
|
241
|
+
} catch (e) { process.exit(0); }
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
mainMenu();
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "zenithix",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI onde permite a geração para uma base de bot de discord",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [],
|
|
10
|
+
"author": "",
|
|
11
|
+
"license": "ISC",
|
|
12
|
+
"type": "module",
|
|
13
|
+
"bin": {
|
|
14
|
+
"zenithix": "./index.js"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"index.js"
|
|
18
|
+
],
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@clack/prompts": "^1.0.0",
|
|
21
|
+
"@inquirer/checkbox": "^5.0.4",
|
|
22
|
+
"@inquirer/input": "^5.0.4",
|
|
23
|
+
"@inquirer/select": "^5.0.4",
|
|
24
|
+
"degit": "^2.8.4",
|
|
25
|
+
"execa": "^9.6.1",
|
|
26
|
+
"figures": "^6.1.0",
|
|
27
|
+
"fs-extra": "^11.3.3",
|
|
28
|
+
"kolorist": "^1.8.0",
|
|
29
|
+
"ora": "^9.3.0",
|
|
30
|
+
"prompts": "^2.4.2"
|
|
31
|
+
}
|
|
32
|
+
}
|