@ninenity/neutrun 1.9.2 → 1.9.4

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.
@@ -6,77 +6,129 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.runTranslate = runTranslate;
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
- const ConsoleLog_1 = require("../Shared/ConsoleLog");
10
- async function translateText(text, targetLang) {
9
+ const Ui_1 = require("./Ui");
10
+ const PADRAO = [
11
+ { code: 'en-US', fileName: 'en_us.ts' },
12
+ { code: 'es-ES', fileName: 'es_es.ts' }
13
+ ];
14
+ /** Quantas traduções ao mesmo tempo. Acima disso o endpoint começa a responder 429. */
15
+ const EM_PARALELO = 6;
16
+ /** `en-US` → `en_us.ts`. Para quem passou um idioma que não está na tabela padrão. */
17
+ const arquivoDe = (code) => `${code.toLowerCase().replace(/-/g, '_')}.ts`;
18
+ /**
19
+ * As variáveis do texto saem antes de traduzir e voltam depois.
20
+ *
21
+ * `{user}` traduzido vira `{usuário}`, e a chave deixa de casar com o que o código passa —
22
+ * um bug que só aparece em produção, no idioma que ninguém testou.
23
+ */
24
+ async function traduzirTexto(text, targetLang) {
11
25
  if (!text || typeof text !== 'string')
12
- return text;
26
+ return { texto: text, ok: true };
13
27
  const variables = [];
14
- const maskedText = text.replace(/\{([^}]+)\}/g, (match) => {
28
+ const mascarado = text.replace(/\{([^}]+)\}/g, match => {
15
29
  variables.push(match);
16
30
  return `__VAR_${variables.length - 1}__`;
17
31
  });
18
32
  try {
19
33
  const langCode = targetLang.split('-')[0];
20
- const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=${langCode}&dt=t&q=${encodeURIComponent(maskedText)}`;
34
+ const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=${langCode}&dt=t&q=${encodeURIComponent(mascarado)}`;
21
35
  const response = await fetch(url);
36
+ if (!response.ok)
37
+ throw new Error(`HTTP ${response.status}`);
22
38
  const data = await response.json();
23
- let translated = '';
39
+ let traduzido = '';
24
40
  if (Array.isArray(data[0])) {
25
- for (const sentence of data[0]) {
41
+ for (const sentence of data[0])
26
42
  if (sentence[0])
27
- translated += sentence[0];
28
- }
43
+ traduzido += sentence[0];
29
44
  }
30
- if (!translated)
31
- translated = text;
32
- let restoredText = translated;
45
+ if (!traduzido)
46
+ return { texto: text, ok: false };
47
+ let restaurado = traduzido;
33
48
  variables.forEach((variable, index) => {
34
- restoredText = restoredText.replace(new RegExp(`__VAR_${index}__`, 'gi'), variable);
35
- restoredText = restoredText.replace(new RegExp(`__VAR_ ${index} __`, 'gi'), variable);
49
+ restaurado = restaurado.replace(new RegExp(`__VAR_${index}__`, 'gi'), variable);
50
+ restaurado = restaurado.replace(new RegExp(`__VAR_ ${index} __`, 'gi'), variable);
36
51
  });
37
- return restoredText;
52
+ return { texto: restaurado, ok: true };
38
53
  }
39
- catch (error) {
40
- (0, ConsoleLog_1.logError)(`Erro ao traduzir "${text}": ${error}`, 'AutoTranslate');
41
- return text;
54
+ catch {
55
+ return { texto: text, ok: false };
42
56
  }
43
57
  }
44
- async function translateDict(dict, targetLang) {
45
- const result = {};
46
- for (const [key, value] of Object.entries(dict)) {
47
- if (typeof value === 'object' && value !== null) {
48
- result[key] = await translateDict(value, targetLang);
49
- }
50
- else if (typeof value === 'string') {
51
- (0, ConsoleLog_1.logInfo)(`Translating [${key}]: "${value}"`, 'AutoTranslate');
52
- result[key] = await translateText(value, targetLang);
53
- }
58
+ /** Todo texto do dicionário, achatado num caminho de chaves. */
59
+ function colher(dict, caminho = []) {
60
+ const saida = [];
61
+ for (const [chave, valor] of Object.entries(dict)) {
62
+ if (typeof valor === 'string')
63
+ saida.push({ caminho: [...caminho, chave], texto: valor });
64
+ else if (valor && typeof valor === 'object')
65
+ saida.push(...colher(valor, [...caminho, chave]));
54
66
  }
55
- return result;
67
+ return saida;
56
68
  }
57
- async function runTranslate(projectDir = process.cwd()) {
69
+ const plantar = (dict, caminho, texto) => {
70
+ let atual = dict;
71
+ for (let i = 0; i < caminho.length - 1; i += 1) {
72
+ const chave = caminho[i];
73
+ if (!atual[chave] || typeof atual[chave] !== 'object')
74
+ atual[chave] = {};
75
+ atual = atual[chave];
76
+ }
77
+ atual[caminho[caminho.length - 1]] = texto;
78
+ };
79
+ /** Roda `trabalho` sobre a lista com no máximo `teto` em voo ao mesmo tempo. */
80
+ async function comTeto(itens, teto, trabalho) {
81
+ let proximo = 0;
82
+ const trilhas = Array.from({ length: Math.min(teto, itens.length) }, async () => {
83
+ while (proximo < itens.length) {
84
+ const meu = proximo;
85
+ proximo += 1;
86
+ await trabalho(itens[meu]);
87
+ }
88
+ });
89
+ await Promise.all(trilhas);
90
+ }
91
+ async function runTranslate(projectDir = process.cwd(), report = Ui_1.plainReporter, idiomas) {
58
92
  const translateDir = path_1.default.join(projectDir, 'src', 'Shared', 'Translate');
59
93
  const tptFile = path_1.default.join(translateDir, 'tpt_tsl.ts');
60
94
  if (!fs_1.default.existsSync(tptFile)) {
61
- (0, ConsoleLog_1.logError)(`Arquivo template tpt_tsl.ts não encontrado em ${translateDir}`, 'AutoTranslate');
62
- return;
95
+ throw new Error(`não achei o template tpt_tsl.ts em ${translateDir}. Rode \`neutrun locate\` antes — é ele que gera o dicionário base.`);
63
96
  }
64
97
  delete require.cache[require.resolve(tptFile)];
65
98
  const templateModule = require(tptFile);
66
99
  const baseDict = templateModule.default?.dict || templateModule.dict || {};
67
- const targetLanguages = [
68
- { code: 'en-US', fileName: 'en_us.ts' },
69
- { code: 'es-ES', fileName: 'es_es.ts' }
70
- ];
71
- (0, ConsoleLog_1.logInfo)('Iniciando Tradução Automática das chaves...', 'AutoTranslate');
72
- for (const lang of targetLanguages) {
73
- (0, ConsoleLog_1.logInfo)(`Traduzindo dicionário para: [${lang.code}]...`, 'AutoTranslate');
74
- const translatedDict = await translateDict(baseDict, lang.code);
75
- const fileContent = `export default {\n locale: '${lang.code}',\n dict: ${JSON.stringify(translatedDict, null, 2)}\n}\n`;
76
- const outputPath = path_1.default.join(translateDir, lang.fileName);
77
- fs_1.default.writeFileSync(outputPath, fileContent, 'utf-8');
78
- (0, ConsoleLog_1.logSuccess)(`Dicionário gerado com sucesso: Translate/${lang.fileName}`, 'AutoTranslate');
100
+ const alvos = idiomas?.length
101
+ ? idiomas.map(code => ({ code, fileName: arquivoDe(code) }))
102
+ : PADRAO;
103
+ const textos = colher(baseDict);
104
+ const resultado = { chaves: textos.length, idiomas: [], falhas: 0 };
105
+ if (textos.length === 0) {
106
+ report.warn('o dicionário base está vazio — nada para traduzir');
107
+ return resultado;
108
+ }
109
+ for (const alvo of alvos) {
110
+ report.start(`traduzindo para ${alvo.code}`);
111
+ report.total(textos.length, alvo.code);
112
+ const traduzido = {};
113
+ let falhasDoIdioma = 0;
114
+ await comTeto(textos, EM_PARALELO, async (item) => {
115
+ const { texto, ok } = await traduzirTexto(item.texto, alvo.code);
116
+ if (!ok)
117
+ falhasDoIdioma += 1;
118
+ plantar(traduzido, item.caminho, texto);
119
+ report.tick(item.caminho.join('.'));
120
+ });
121
+ const conteudo = `export default {\n locale: '${alvo.code}',\n dict: ${JSON.stringify(traduzido, null, 2)}\n}\n`;
122
+ fs_1.default.writeFileSync(path_1.default.join(translateDir, alvo.fileName), conteudo, 'utf-8');
123
+ resultado.idiomas.push(alvo.code);
124
+ resultado.falhas += falhasDoIdioma;
125
+ if (falhasDoIdioma > 0) {
126
+ report.warn(`${alvo.fileName}: ${textos.length - falhasDoIdioma}/${textos.length} chaves — ${falhasDoIdioma} ficaram em português`);
127
+ }
128
+ else {
129
+ report.ok(`${alvo.fileName}: ${textos.length} chaves`);
130
+ }
79
131
  }
80
- (0, ConsoleLog_1.logSuccess)('Todas as traduções foram concluídas com sucesso!', 'AutoTranslate');
132
+ return resultado;
81
133
  }
82
134
  //# sourceMappingURL=Translate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Translate.js","sourceRoot":"","sources":["../../src/CLI/Translate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Translate.js","sourceRoot":"","sources":["../../src/CLI/Translate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * A cara da CLI: banner, spinner, barra de progresso e o resumo do fim.
3
+ *
4
+ * A regra que governa o arquivo inteiro: **animação só quando alguém está olhando.**
5
+ * Spinner e barra de progresso funcionam reescrevendo a linha atual com códigos de
6
+ * escape; num terminal isso é movimento, e num arquivo de log é lixo — `\r` e sequências
7
+ * `` empilhadas em cada linha, num arquivo que alguém vai ler depois justamente
8
+ * porque algo deu errado. Por isso `rich` olha para o TTY, para `CI` e para `NO_COLOR`
9
+ * antes de decidir, e o modo pobre imprime uma linha por evento — que é o que se quer ler
10
+ * num `docker logs`.
11
+ *
12
+ * Nada aqui decide o que a CLI faz; só como ela aparece. Os comandos falam com o
13
+ * `Reporter`, e é a `Ui` que escolhe entre desenhar um spinner e escrever uma linha.
14
+ */
15
+ export interface UiOptions {
16
+ /** `false` desliga cor e animação. Ausente = decide pelo ambiente. */
17
+ color?: boolean;
18
+ /** Só erros e o resultado. Para quem chama a CLI de dentro de um script. */
19
+ quiet?: boolean;
20
+ stream?: NodeJS.WriteStream;
21
+ }
22
+ /**
23
+ * O que um comando conta para quem está olhando.
24
+ *
25
+ * Fica separado da `Ui` porque `runLocalize` e `runTranslate` também rodam fora da CLI —
26
+ * o bot chama os dois por `tsx -e` — e ali não deve existir spinner nenhum. O comando
27
+ * reporta o que aconteceu; quem escolhe a forma é o dono da saída.
28
+ */
29
+ export interface Reporter {
30
+ /** Começou uma etapa longa. */
31
+ start(label: string): void;
32
+ /** A mesma etapa, com texto novo. Não cria linha nova no modo rico. */
33
+ update(label: string): void;
34
+ /** O total de itens ficou conhecido: dá para trocar o spinner por uma barra. */
35
+ total(count: number, label?: string): void;
36
+ /** Mais um item pronto. */
37
+ tick(label?: string): void;
38
+ ok(label: string): void;
39
+ warn(label: string): void;
40
+ fail(label: string): void;
41
+ /** Uma linha solta, sem estado. */
42
+ note(label: string): void;
43
+ }
44
+ /** O reporter de quem não tem terminal: uma linha por evento, e nada mais. */
45
+ export declare const plainReporter: Reporter;
46
+ /** O reporter de quem chamou a função direto e não quer saída nenhuma. */
47
+ export declare const silentReporter: Reporter;
48
+ /** `1m03s`, `840ms`. Duração que se lê de relance. */
49
+ export declare const duracao: (ms: number) => string;
50
+ export declare class Ui implements Reporter {
51
+ /** Pode animar: tem terminal, tem cor, e ninguém pediu silêncio. */
52
+ readonly rich: boolean;
53
+ private readonly quiet;
54
+ private readonly stream;
55
+ private fiando?;
56
+ private barra?;
57
+ private feitos;
58
+ private readonly inicio;
59
+ constructor(options?: UiOptions);
60
+ /** O logotipo. Só aparece com terminal: num log ele é seis linhas de nada. */
61
+ banner(version: string): void;
62
+ titulo(texto: string, detalhe?: string): void;
63
+ start(label: string): void;
64
+ update(label: string): void;
65
+ /**
66
+ * Troca o spinner por uma barra quando o total aparece.
67
+ *
68
+ * Enquanto não se sabe quantos são, "traduzindo…" é tudo que dá para dizer com verdade.
69
+ * Assim que o total é conhecido, a barra passa a responder a única pergunta que
70
+ * interessa numa espera longa — quanto falta —, e é por isso que a troca acontece no
71
+ * meio do comando em vez de escolher um dos dois no começo.
72
+ */
73
+ total(count: number, label?: string): void;
74
+ tick(label?: string): void;
75
+ ok(label: string): void;
76
+ warn(label: string): void;
77
+ /** Erro sai mesmo em `--quiet`: silêncio sobre falha é o silêncio errado. */
78
+ fail(label: string): void;
79
+ note(label: string): void;
80
+ /** O resumo do fim: o que foi feito, em quanto tempo. */
81
+ resumo(linhas: Array<[string, string]>, titulo?: string): void;
82
+ /** Fecha o que estiver animando. Idempotente, e chamado antes de qualquer escrita. */
83
+ parar(): void;
84
+ }
85
+ //# sourceMappingURL=Ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Ui.d.ts","sourceRoot":"","sources":["../../src/CLI/Ui.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,SAAS;IACxB,sEAAsE;IACtE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,4EAA4E;IAC5E,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,CAAA;CAC5B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,+BAA+B;IAC/B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,uEAAuE;IACvE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,gFAAgF;IAChF,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1C,2BAA2B;IAC3B,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,mCAAmC;IACnC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED,8EAA8E;AAC9E,eAAO,MAAM,aAAa,EAAE,QAS3B,CAAA;AAED,0EAA0E;AAC1E,eAAO,MAAM,cAAc,EAAE,QAS5B,CAAA;AAsCD,sDAAsD;AACtD,eAAO,MAAM,OAAO,GAAI,IAAI,MAAM,KAAG,MAKpC,CAAA;AAED,qBAAa,EAAG,YAAW,QAAQ;IACjC,oEAAoE;IACpE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,MAAM,CAAC,CAAK;IACpB,OAAO,CAAC,KAAK,CAAC,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;gBAEvB,OAAO,GAAE,SAAc;IAqBpC,8EAA8E;IAC9E,MAAM,CAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAW9B,MAAM,CAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAK9C,KAAK,CAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAU3B,MAAM,CAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAM5B;;;;;;;OAOG;IACH,KAAK,CAAE,KAAK,EAAE,MAAM,EAAE,KAAK,SAAc,GAAG,IAAI;IA8BhD,IAAI,CAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAO3B,EAAE,CAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAWxB,IAAI,CAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAW1B,6EAA6E;IAC7E,IAAI,CAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAU1B,IAAI,CAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAU1B,yDAAyD;IACzD,MAAM,CAAE,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,SAAW,GAAG,IAAI;IAWjE,sFAAsF;IACtF,KAAK,IAAK,IAAI;CAUf"}
package/dist/CLI/Ui.js ADDED
@@ -0,0 +1,246 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Ui = exports.duracao = exports.silentReporter = exports.plainReporter = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const cli_progress_1 = __importDefault(require("cli-progress"));
9
+ const ora_1 = __importDefault(require("ora"));
10
+ /** O reporter de quem não tem terminal: uma linha por evento, e nada mais. */
11
+ exports.plainReporter = {
12
+ start: label => console.log(chalk_1.default.cyan(`→ ${label}`)),
13
+ update: () => undefined,
14
+ total: () => undefined,
15
+ tick: () => undefined,
16
+ ok: label => console.log(chalk_1.default.green(`✓ ${label}`)),
17
+ warn: label => console.log(chalk_1.default.yellow(`! ${label}`)),
18
+ fail: label => console.log(chalk_1.default.red(`✗ ${label}`)),
19
+ note: label => console.log(chalk_1.default.gray(` ${label}`))
20
+ };
21
+ /** O reporter de quem chamou a função direto e não quer saída nenhuma. */
22
+ exports.silentReporter = {
23
+ start: () => undefined,
24
+ update: () => undefined,
25
+ total: () => undefined,
26
+ tick: () => undefined,
27
+ ok: () => undefined,
28
+ warn: () => undefined,
29
+ fail: () => undefined,
30
+ note: () => undefined
31
+ };
32
+ const SIMBOLO = {
33
+ ok: '✔',
34
+ warn: '▲',
35
+ fail: '✖',
36
+ seta: '›',
37
+ ponto: '·'
38
+ };
39
+ /**
40
+ * O degradê do banner, do ciano ao magenta.
41
+ *
42
+ * Sem `gradient-string` de propósito: é mais uma dependência num pacote que já é
43
+ * dependência de todo bot do ecossistema, para pintar sete letras. `chalk` já faz cor de
44
+ * 256 e a conta cabe em três linhas.
45
+ */
46
+ const degrade = (texto, passo, total) => {
47
+ const t = total <= 1 ? 0 : passo / (total - 1);
48
+ const r = Math.round(120 + t * 100);
49
+ const g = Math.round(220 - t * 110);
50
+ const b = 255;
51
+ return chalk_1.default.rgb(r, g, b)(texto);
52
+ };
53
+ /**
54
+ * A marca, em uma linha.
55
+ *
56
+ * Não é arte ASCII de seis linhas, e por dois motivos. Blocos como `█` e `╗` dependem da
57
+ * fonte do terminal: no `cmd.exe` com fonte raster, num `ssh` de celular, num log de
58
+ * container, aquilo vira uma cerca de quadrados — a primeira impressão da ferramenta
59
+ * sendo um bug de encoding. E uma CLI que se roda dez vezes por dia não pode gastar oito
60
+ * linhas se apresentando em cada uma.
61
+ *
62
+ * O degradê fica nas letras, que são ASCII e existem em qualquer fonte.
63
+ */
64
+ const MARCA = 'NEUTRUN';
65
+ /** `1m03s`, `840ms`. Duração que se lê de relance. */
66
+ const duracao = (ms) => {
67
+ if (ms < 1_000)
68
+ return `${Math.round(ms)}ms`;
69
+ if (ms < 60_000)
70
+ return `${(ms / 1_000).toFixed(1)}s`;
71
+ const minutos = Math.floor(ms / 60_000);
72
+ return `${minutos}m${String(Math.round((ms % 60_000) / 1_000)).padStart(2, '0')}s`;
73
+ };
74
+ exports.duracao = duracao;
75
+ class Ui {
76
+ /** Pode animar: tem terminal, tem cor, e ninguém pediu silêncio. */
77
+ rich;
78
+ quiet;
79
+ stream;
80
+ fiando;
81
+ barra;
82
+ feitos = 0;
83
+ inicio = Date.now();
84
+ constructor(options = {}) {
85
+ this.stream = options.stream ?? process.stdout;
86
+ this.quiet = options.quiet === true;
87
+ /*
88
+ * `CI` e `NO_COLOR` entram na conta junto com o TTY.
89
+ *
90
+ * O TTY sozinho não basta: um runner de CI pode alocar pseudo-terminal e ainda assim
91
+ * guardar a saída num arquivo, que é onde o spinner vira ruído. E `NO_COLOR` é a
92
+ * convenção que já existe para "não pinte nada" — respeitar é de graça.
93
+ */
94
+ const ambienteDeixa = this.stream.isTTY === true &&
95
+ !process.env.CI &&
96
+ !process.env.NO_COLOR &&
97
+ process.env.TERM !== 'dumb';
98
+ this.rich = (options.color ?? ambienteDeixa) && !this.quiet;
99
+ if (options.color === false)
100
+ chalk_1.default.level = 0;
101
+ }
102
+ /** O logotipo. Só aparece com terminal: num log ele é seis linhas de nada. */
103
+ banner(version) {
104
+ if (!this.rich)
105
+ return;
106
+ const letras = [...MARCA]
107
+ .map((letra, indice) => chalk_1.default.bold(degrade(letra, indice, MARCA.length)))
108
+ .join('');
109
+ this.stream.write(`\n ${chalk_1.default.dim('◆')} ${letras} ${chalk_1.default.dim(SIMBOLO.ponto)} ${chalk_1.default.cyan(`v${version}`)}\n` +
110
+ ` ${chalk_1.default.gray('framework do ecossistema Ninenity')}\n\n`);
111
+ }
112
+ titulo(texto, detalhe) {
113
+ if (this.quiet)
114
+ return;
115
+ this.stream.write(`${chalk_1.default.bold.white(texto)}${detalhe ? chalk_1.default.gray(` ${detalhe}`) : ''}\n`);
116
+ }
117
+ start(label) {
118
+ if (this.quiet)
119
+ return;
120
+ this.parar();
121
+ if (!this.rich) {
122
+ this.stream.write(`${chalk_1.default.cyan(SIMBOLO.seta)} ${label}\n`);
123
+ return;
124
+ }
125
+ this.fiando = (0, ora_1.default)({ text: label, stream: this.stream, spinner: 'dots' }).start();
126
+ }
127
+ update(label) {
128
+ if (this.quiet)
129
+ return;
130
+ if (this.fiando)
131
+ this.fiando.text = label;
132
+ else if (this.barra)
133
+ this.barra.update(this.feitos, { label });
134
+ }
135
+ /**
136
+ * Troca o spinner por uma barra quando o total aparece.
137
+ *
138
+ * Enquanto não se sabe quantos são, "traduzindo…" é tudo que dá para dizer com verdade.
139
+ * Assim que o total é conhecido, a barra passa a responder a única pergunta que
140
+ * interessa numa espera longa — quanto falta —, e é por isso que a troca acontece no
141
+ * meio do comando em vez de escolher um dos dois no começo.
142
+ */
143
+ total(count, label = 'progresso') {
144
+ if (this.quiet || count <= 0)
145
+ return;
146
+ this.parar();
147
+ this.feitos = 0;
148
+ /*
149
+ * A barra exige TTY de verdade, e não só `rich`.
150
+ *
151
+ * `--color` liga `rich` à força — o que faz sentido para cor e para o spinner, que o
152
+ * `ora` degrada sozinho imprimindo uma linha por quadro. A barra não degrada: sem TTY
153
+ * ela simplesmente não desenha, e o total sumia da saída sem deixar rastro.
154
+ */
155
+ if (!this.rich || this.stream.isTTY !== true) {
156
+ this.stream.write(`${chalk_1.default.cyan(SIMBOLO.seta)} ${label}: ${count} item(ns)\n`);
157
+ return;
158
+ }
159
+ this.barra = new cli_progress_1.default.SingleBar({
160
+ format: ` ${chalk_1.default.cyan('{bar}')} ${chalk_1.default.bold('{percentage}%')} ${chalk_1.default.gray('{value}/{total}')} ${chalk_1.default.dim('{label}')}`,
161
+ barCompleteChar: '█',
162
+ barIncompleteChar: '░',
163
+ hideCursor: true,
164
+ stream: this.stream,
165
+ barsize: 24,
166
+ clearOnComplete: true
167
+ }, cli_progress_1.default.Presets.shades_classic);
168
+ this.barra.start(count, 0, { label });
169
+ }
170
+ tick(label) {
171
+ if (this.quiet)
172
+ return;
173
+ this.feitos += 1;
174
+ if (this.barra)
175
+ this.barra.update(this.feitos, { label: label ?? '' });
176
+ else if (this.fiando && label)
177
+ this.fiando.text = label;
178
+ }
179
+ ok(label) {
180
+ if (this.quiet)
181
+ return;
182
+ if (this.fiando) {
183
+ this.fiando.succeed(label);
184
+ this.fiando = undefined;
185
+ return;
186
+ }
187
+ this.parar();
188
+ this.stream.write(`${chalk_1.default.green(SIMBOLO.ok)} ${label}\n`);
189
+ }
190
+ warn(label) {
191
+ if (this.quiet)
192
+ return;
193
+ if (this.fiando) {
194
+ this.fiando.warn(label);
195
+ this.fiando = undefined;
196
+ return;
197
+ }
198
+ this.parar();
199
+ this.stream.write(`${chalk_1.default.yellow(SIMBOLO.warn)} ${label}\n`);
200
+ }
201
+ /** Erro sai mesmo em `--quiet`: silêncio sobre falha é o silêncio errado. */
202
+ fail(label) {
203
+ if (this.fiando) {
204
+ this.fiando.fail(label);
205
+ this.fiando = undefined;
206
+ return;
207
+ }
208
+ this.parar();
209
+ process.stderr.write(`${chalk_1.default.red(SIMBOLO.fail)} ${label}\n`);
210
+ }
211
+ note(label) {
212
+ if (this.quiet)
213
+ return;
214
+ if (this.fiando || this.barra) {
215
+ // Escrever por baixo de um spinner embaralha a linha dele: vira texto do próprio.
216
+ this.update(label);
217
+ return;
218
+ }
219
+ this.stream.write(` ${chalk_1.default.gray(label)}\n`);
220
+ }
221
+ /** O resumo do fim: o que foi feito, em quanto tempo. */
222
+ resumo(linhas, titulo = 'Pronto') {
223
+ this.parar();
224
+ if (this.quiet)
225
+ return;
226
+ const largura = Math.max(...linhas.map(([rotulo]) => rotulo.length), 0);
227
+ this.stream.write(`\n${chalk_1.default.green.bold(`${SIMBOLO.ok} ${titulo}`)} ${chalk_1.default.gray(`em ${(0, exports.duracao)(Date.now() - this.inicio)}`)}\n`);
228
+ for (const [rotulo, valor] of linhas) {
229
+ this.stream.write(` ${chalk_1.default.gray(rotulo.padEnd(largura))} ${chalk_1.default.white(valor)}\n`);
230
+ }
231
+ this.stream.write('\n');
232
+ }
233
+ /** Fecha o que estiver animando. Idempotente, e chamado antes de qualquer escrita. */
234
+ parar() {
235
+ if (this.barra) {
236
+ this.barra.stop();
237
+ this.barra = undefined;
238
+ }
239
+ if (this.fiando) {
240
+ this.fiando.stop();
241
+ this.fiando = undefined;
242
+ }
243
+ }
244
+ }
245
+ exports.Ui = Ui;
246
+ //# sourceMappingURL=Ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Ui.js","sourceRoot":"","sources":["../../src/CLI/Ui.ts"],"names":[],"mappings":"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"}