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.
Files changed (2) hide show
  1. package/index.js +244 -0
  2. 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
+ }