trello-cli-unofficial 0.7.3 → 0.7.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.
- package/README.md +36 -1
- package/bun.lock +5 -0
- package/dist/main.js +2793 -128
- package/package.json +3 -3
- package/src/i18n/README.md +150 -0
- package/src/i18n/index.ts +61 -0
- package/src/i18n/locales/en.json +129 -0
- package/src/i18n/locales/pt-BR.json +129 -0
- package/src/presentation/cli/AuthController.ts +5 -5
- package/src/presentation/cli/BoardController.ts +9 -9
- package/src/presentation/cli/CardController.ts +51 -38
- package/src/presentation/cli/ConfigController.ts +15 -14
- package/src/presentation/cli/MainMenuController.ts +12 -9
- package/test_trigger.txt +0 -3
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trello-cli-unofficial",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.4",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Unofficial Trello CLI using Power-Up authentication, built with Bun for maximum performance",
|
|
7
7
|
"author": "Matheus Caiser <matheus.kaiser@gmail.com> (https://www.mrdeveloper.com.br/)",
|
|
@@ -41,8 +41,7 @@
|
|
|
41
41
|
"install.sh",
|
|
42
42
|
"main.ts",
|
|
43
43
|
"scripts",
|
|
44
|
-
"src"
|
|
45
|
-
"test_trigger.txt"
|
|
44
|
+
"src"
|
|
46
45
|
],
|
|
47
46
|
"engines": {
|
|
48
47
|
"bun": ">=1.0.0"
|
|
@@ -75,6 +74,7 @@
|
|
|
75
74
|
"commander": "^14.0.2",
|
|
76
75
|
"dotenv": "^17.2.3",
|
|
77
76
|
"fs-extra": "^11.3.2",
|
|
77
|
+
"i18next": "^25.6.1",
|
|
78
78
|
"inquirer": "^12.10.0"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Internacionalização (i18n)
|
|
2
|
+
|
|
3
|
+
Este projeto usa **i18next** para suportar múltiplos idiomas.
|
|
4
|
+
|
|
5
|
+
## Idiomas Suportados
|
|
6
|
+
|
|
7
|
+
- 🇧🇷 **Português (pt-BR)** - Padrão para sistemas em Português
|
|
8
|
+
- 🇺🇸 **English (en)** - Padrão para outros sistemas
|
|
9
|
+
|
|
10
|
+
## Detecção Automática
|
|
11
|
+
|
|
12
|
+
O idioma é detectado automaticamente baseado na variável de ambiente `LANG` do sistema.
|
|
13
|
+
|
|
14
|
+
## Como Usar
|
|
15
|
+
|
|
16
|
+
### Importando a função de tradução
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { t } from "@/i18n";
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Tradução simples
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
console.log(t("auth.notAuthenticated"));
|
|
26
|
+
// 🇧🇷: "🔐 Você não está autenticado!"
|
|
27
|
+
// 🇺🇸: "🔐 You are not authenticated!"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Tradução com interpolação
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
console.log(t("board.notFound", { name: "My Board" }));
|
|
34
|
+
// 🇧🇷: "❌ Board não encontrado: My Board"
|
|
35
|
+
// 🇺🇸: "❌ Board not found: My Board"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Mudando o idioma manualmente
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { changeLanguage } from "@/i18n";
|
|
42
|
+
|
|
43
|
+
changeLanguage("en"); // Muda para Inglês
|
|
44
|
+
changeLanguage("pt-BR"); // Muda para Português
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Obtendo o idioma atual
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { getCurrentLanguage } from "@/i18n";
|
|
51
|
+
|
|
52
|
+
const currentLang = getCurrentLanguage();
|
|
53
|
+
console.log(currentLang); // 'pt-BR' ou 'en'
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Estrutura dos Arquivos
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
src/i18n/
|
|
60
|
+
├── index.ts # Configuração e funções helper
|
|
61
|
+
└── locales/
|
|
62
|
+
├── pt-BR.json # Traduções em Português
|
|
63
|
+
└── en.json # Traduções em Inglês
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Adicionando Novas Traduções
|
|
67
|
+
|
|
68
|
+
1. Adicione a chave em `src/i18n/locales/pt-BR.json`:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"myFeature": {
|
|
73
|
+
"message": "Minha mensagem em português"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
2. Adicione a mesma chave em `src/i18n/locales/en.json`:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"myFeature": {
|
|
83
|
+
"message": "My message in English"
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
3. Use no código:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { t } from "@/i18n";
|
|
92
|
+
|
|
93
|
+
console.log(t("myFeature.message"));
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Exemplo Completo
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { t } from "@/i18n";
|
|
100
|
+
import inquirer from "inquirer";
|
|
101
|
+
|
|
102
|
+
export class AuthController {
|
|
103
|
+
async setupToken(): Promise<void> {
|
|
104
|
+
const { token } = await inquirer.prompt([
|
|
105
|
+
{
|
|
106
|
+
type: "input",
|
|
107
|
+
name: "token",
|
|
108
|
+
message: t("auth.enterToken"),
|
|
109
|
+
validate: (input) => input.startsWith("ATTA") || t("auth.tokenInvalid"),
|
|
110
|
+
},
|
|
111
|
+
]);
|
|
112
|
+
|
|
113
|
+
console.log(t("auth.tokenSaved"));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Testando Diferentes Idiomas
|
|
119
|
+
|
|
120
|
+
### Linux/macOS
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Testar em Português
|
|
124
|
+
LANG=pt_BR.UTF-8 bun run main.ts
|
|
125
|
+
|
|
126
|
+
# Testar em Inglês
|
|
127
|
+
LANG=en_US.UTF-8 bun run main.ts
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Windows (PowerShell)
|
|
131
|
+
|
|
132
|
+
```powershell
|
|
133
|
+
# Testar em Português
|
|
134
|
+
$env:LANG = "pt_BR.UTF-8"; bun run main.ts
|
|
135
|
+
|
|
136
|
+
# Testar em Inglês
|
|
137
|
+
$env:LANG = "en_US.UTF-8"; bun run main.ts
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Boas Práticas
|
|
141
|
+
|
|
142
|
+
1. ✅ **Use chaves descritivas**: `auth.notAuthenticated` em vez de `msg1`
|
|
143
|
+
2. ✅ **Organize por feature**: `auth.*`, `card.*`, `board.*`
|
|
144
|
+
3. ✅ **Mantenha consistência**: Use os mesmos emojis em ambos os idiomas
|
|
145
|
+
4. ✅ **Interpole valores dinâmicos**: Use `{{variavel}}` para valores que mudam
|
|
146
|
+
5. ✅ **Fallback para inglês**: Sempre mantenha o inglês completo como fallback
|
|
147
|
+
|
|
148
|
+
## TypeScript Support
|
|
149
|
+
|
|
150
|
+
O projeto está configurado com tipos para i18next. O TypeScript vai autocompletar as chaves de tradução disponíveis!
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import i18next from 'i18next';
|
|
2
|
+
import en from './locales/en.json';
|
|
3
|
+
import ptBR from './locales/pt-BR.json';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Detecta o idioma do sistema
|
|
7
|
+
* Retorna 'pt-BR' ou 'en' baseado na variável de ambiente LANG
|
|
8
|
+
*/
|
|
9
|
+
function detectLanguage(): string {
|
|
10
|
+
const lang = process.env.LANG || process.env.LANGUAGE || 'en_US';
|
|
11
|
+
|
|
12
|
+
// Mapeia common locales para nossos idiomas suportados
|
|
13
|
+
if (lang.startsWith('pt')) {
|
|
14
|
+
return 'pt-BR';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return 'en';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Inicializa i18next
|
|
21
|
+
i18next.init({
|
|
22
|
+
lng: detectLanguage(),
|
|
23
|
+
fallbackLng: 'en',
|
|
24
|
+
resources: {
|
|
25
|
+
'pt-BR': {
|
|
26
|
+
translation: ptBR,
|
|
27
|
+
},
|
|
28
|
+
'en': {
|
|
29
|
+
translation: en,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
interpolation: {
|
|
33
|
+
escapeValue: false, // React já faz escape, não precisamos aqui
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Função helper para tradução
|
|
39
|
+
* @param key - Chave da tradução (ex: 'auth.notAuthenticated')
|
|
40
|
+
* @param options - Opções de interpolação (ex: { name: 'João' })
|
|
41
|
+
*/
|
|
42
|
+
export function t(key: string, options?: Record<string, any>): string {
|
|
43
|
+
return i18next.t(key, options);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Muda o idioma da aplicação
|
|
48
|
+
* @param language - Código do idioma ('pt-BR' ou 'en')
|
|
49
|
+
*/
|
|
50
|
+
export function changeLanguage(language: 'pt-BR' | 'en'): void {
|
|
51
|
+
i18next.changeLanguage(language);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Retorna o idioma atual
|
|
56
|
+
*/
|
|
57
|
+
export function getCurrentLanguage(): string {
|
|
58
|
+
return i18next.language;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export default i18next;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"yes": "Yes",
|
|
4
|
+
"no": "No",
|
|
5
|
+
"cancel": "Cancel",
|
|
6
|
+
"back": "Back",
|
|
7
|
+
"exit": "Exit",
|
|
8
|
+
"success": "✅ Success!",
|
|
9
|
+
"error": "❌ Error!",
|
|
10
|
+
"loading": "⏳ Loading..."
|
|
11
|
+
},
|
|
12
|
+
"auth": {
|
|
13
|
+
"notAuthenticated": "🔐 You are not authenticated!",
|
|
14
|
+
"enterToken": "Please enter your Trello token:",
|
|
15
|
+
"tokenInvalid": "❌ Invalid token! Token must start with 'ATTA' and be at least 11 characters long.",
|
|
16
|
+
"tokenSaved": "✅ Token saved successfully!",
|
|
17
|
+
"authenticated": "✅ You are already authenticated!"
|
|
18
|
+
},
|
|
19
|
+
"menu": {
|
|
20
|
+
"title": "� Main Menu - Trello CLI Unofficial",
|
|
21
|
+
"boards": "📋 View my boards",
|
|
22
|
+
"explore": "📝 Explore board",
|
|
23
|
+
"create": "➕ Create card",
|
|
24
|
+
"config": "⚙️ Settings",
|
|
25
|
+
"exit": "🚪 Exit",
|
|
26
|
+
"goodbye": "👋 Goodbye!",
|
|
27
|
+
"exploreInDevelopment": "� Explore board - Under development",
|
|
28
|
+
"configTitle": "⚙️ Settings",
|
|
29
|
+
"configToken": "🔑 Configure token",
|
|
30
|
+
"configView": "👀 View current configuration",
|
|
31
|
+
"configReset": "🔄 Reset configuration",
|
|
32
|
+
"configBack": "⬅️ Back",
|
|
33
|
+
"currentConfig": "� Current configuration:",
|
|
34
|
+
"tokenConfigured": "Token configured:",
|
|
35
|
+
"configFile": "Config file: ~/.trello-cli-unofficial/config.json",
|
|
36
|
+
"confirmReset": "Are you sure you want to reset all configuration?",
|
|
37
|
+
"configResetted": "✅ Configuration resetted!",
|
|
38
|
+
"selectBoard": "Select a board:",
|
|
39
|
+
"selectList": "Select a list:",
|
|
40
|
+
"selectCard": "Select a card:"
|
|
41
|
+
},
|
|
42
|
+
"board": {
|
|
43
|
+
"loading": "⏳ Loading boards...",
|
|
44
|
+
"empty": "📋 No boards found.",
|
|
45
|
+
"notFound": "❌ Board \"{{name}}\" not found",
|
|
46
|
+
"lists": "📝 Lists of Board: {{name}}",
|
|
47
|
+
"yourBoards": "📋 Your Trello Boards:"
|
|
48
|
+
},
|
|
49
|
+
"list": {
|
|
50
|
+
"loading": "⏳ Loading lists...",
|
|
51
|
+
"empty": "📝 No lists found in this board.",
|
|
52
|
+
"notFound": "❌ List \"{{listName}}\" not found in board \"{{boardName}}\"",
|
|
53
|
+
"cards": "🃏 Cards of List: {{name}}",
|
|
54
|
+
"boardLists": "📋 Lists from board \"{{boardName}}\":"
|
|
55
|
+
},
|
|
56
|
+
"card": {
|
|
57
|
+
"loading": "⏳ Loading cards...",
|
|
58
|
+
"empty": "🃏 No cards found in this list.",
|
|
59
|
+
"notFound": "❌ Card with ID \"{{cardId}}\" not found",
|
|
60
|
+
"created": "✅ Card created successfully!",
|
|
61
|
+
"updated": "✅ Card updated successfully!",
|
|
62
|
+
"deleted": "✅ Card deleted successfully!",
|
|
63
|
+
"moved": "✅ Card moved successfully!",
|
|
64
|
+
"enterName": "Card name:",
|
|
65
|
+
"enterDescription": "Description (optional):",
|
|
66
|
+
"confirmDelete": "Are you sure you want to delete \"{{name}}\"?",
|
|
67
|
+
"listCards": "📋 Cards from list \"{{listName}}\" in board \"{{boardName}}\":",
|
|
68
|
+
"emptyList": "📭 This list is empty.",
|
|
69
|
+
"selectBoard": "Select board:",
|
|
70
|
+
"selectList": "Select list:",
|
|
71
|
+
"selectCard": "Select a card:",
|
|
72
|
+
"whatToDo": "What would you like to do?",
|
|
73
|
+
"newName": "New name:",
|
|
74
|
+
"newDescription": "New description:",
|
|
75
|
+
"moveToWhichList": "Move to which list?",
|
|
76
|
+
"cardName": "📝 Name: {{name}}",
|
|
77
|
+
"cardUrl": "🔗 URL: {{url}}",
|
|
78
|
+
"cardId": "🆔 ID: {{id}}",
|
|
79
|
+
"movedTo": "➡️ To: {{listName}}",
|
|
80
|
+
"actions": {
|
|
81
|
+
"view": "👁️ View Details",
|
|
82
|
+
"create": "➕ Create Card",
|
|
83
|
+
"edit": "✏️ Edit Card",
|
|
84
|
+
"move": "🔄 Move Card",
|
|
85
|
+
"delete": "🗑️ Delete Card",
|
|
86
|
+
"back": "⬅️ Back"
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"errors": {
|
|
90
|
+
"general": "❌ An error occurred: {{message}}",
|
|
91
|
+
"generic": "❌ Error:",
|
|
92
|
+
"network": "❌ Network error. Check your connection.",
|
|
93
|
+
"invalidInput": "❌ Invalid input: {{field}}",
|
|
94
|
+
"required": "❌ Required field: {{field}}"
|
|
95
|
+
},
|
|
96
|
+
"commands": {
|
|
97
|
+
"boards": {
|
|
98
|
+
"description": "List all available boards",
|
|
99
|
+
"success": "📋 Boards loaded successfully!"
|
|
100
|
+
},
|
|
101
|
+
"lists": {
|
|
102
|
+
"description": "List the lists of a specific board",
|
|
103
|
+
"boardRequired": "❌ Board name is required",
|
|
104
|
+
"success": "📝 Lists loaded successfully!"
|
|
105
|
+
},
|
|
106
|
+
"cards": {
|
|
107
|
+
"description": "List the cards of a specific list",
|
|
108
|
+
"boardRequired": "❌ Board name is required",
|
|
109
|
+
"listRequired": "❌ List name is required",
|
|
110
|
+
"success": "🃏 Cards loaded successfully!"
|
|
111
|
+
},
|
|
112
|
+
"createCard": {
|
|
113
|
+
"description": "Create a new card in a list",
|
|
114
|
+
"nameRequired": "❌ Card name is required",
|
|
115
|
+
"success": "✅ Card '{{name}}' created successfully!"
|
|
116
|
+
},
|
|
117
|
+
"moveCard": {
|
|
118
|
+
"description": "Move a card to another list",
|
|
119
|
+
"cardIdRequired": "❌ Card ID is required",
|
|
120
|
+
"targetListRequired": "❌ Target list ID is required",
|
|
121
|
+
"success": "✅ Card moved successfully!"
|
|
122
|
+
},
|
|
123
|
+
"deleteCard": {
|
|
124
|
+
"description": "Delete a card",
|
|
125
|
+
"cardIdRequired": "❌ Card ID is required",
|
|
126
|
+
"success": "✅ Card deleted successfully!"
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"yes": "Sim",
|
|
4
|
+
"no": "Não",
|
|
5
|
+
"cancel": "Cancelar",
|
|
6
|
+
"back": "Voltar",
|
|
7
|
+
"exit": "Sair",
|
|
8
|
+
"success": "✅ Sucesso!",
|
|
9
|
+
"error": "❌ Erro!",
|
|
10
|
+
"loading": "⏳ Carregando..."
|
|
11
|
+
},
|
|
12
|
+
"auth": {
|
|
13
|
+
"notAuthenticated": "🔐 Você não está autenticado!",
|
|
14
|
+
"enterToken": "Por favor, insira seu token do Trello:",
|
|
15
|
+
"tokenInvalid": "❌ Token inválido! O token deve começar com 'ATTA' e ter pelo menos 11 caracteres.",
|
|
16
|
+
"tokenSaved": "✅ Token salvo com sucesso!",
|
|
17
|
+
"authenticated": "✅ Você já está autenticado!"
|
|
18
|
+
},
|
|
19
|
+
"menu": {
|
|
20
|
+
"title": "� Menu Principal - Trello CLI Unofficial",
|
|
21
|
+
"boards": "📋 Ver meus quadros",
|
|
22
|
+
"explore": "📝 Explorar quadro",
|
|
23
|
+
"create": "➕ Criar cartão",
|
|
24
|
+
"config": "⚙️ Configurações",
|
|
25
|
+
"exit": "🚪 Sair",
|
|
26
|
+
"goodbye": "👋 Até logo!",
|
|
27
|
+
"exploreInDevelopment": "🚧 Explorar quadro - Em desenvolvimento",
|
|
28
|
+
"configTitle": "⚙️ Configurações",
|
|
29
|
+
"configToken": "� Configurar token",
|
|
30
|
+
"configView": "👀 Ver configuração atual",
|
|
31
|
+
"configReset": "🔄 Resetar configuração",
|
|
32
|
+
"configBack": "⬅️ Voltar",
|
|
33
|
+
"currentConfig": "� Configuração atual:",
|
|
34
|
+
"tokenConfigured": "Token configurado:",
|
|
35
|
+
"configFile": "Arquivo de config: ~/.trello-cli-unofficial/config.json",
|
|
36
|
+
"confirmReset": "Tem certeza que deseja resetar toda a configuração?",
|
|
37
|
+
"configResetted": "✅ Configuração resetada!",
|
|
38
|
+
"selectBoard": "Selecione um board:",
|
|
39
|
+
"selectList": "Selecione uma lista:",
|
|
40
|
+
"selectCard": "Selecione um card:"
|
|
41
|
+
},
|
|
42
|
+
"board": {
|
|
43
|
+
"loading": "⏳ Carregando boards...",
|
|
44
|
+
"empty": "📋 Nenhum board encontrado.",
|
|
45
|
+
"notFound": "❌ Quadro \"{{name}}\" não encontrado",
|
|
46
|
+
"lists": "📝 Listas do Board: {{name}}",
|
|
47
|
+
"yourBoards": "📋 Seus Quadros do Trello:"
|
|
48
|
+
},
|
|
49
|
+
"list": {
|
|
50
|
+
"loading": "⏳ Carregando listas...",
|
|
51
|
+
"empty": "📝 Nenhuma lista encontrada neste board.",
|
|
52
|
+
"notFound": "❌ Lista \"{{listName}}\" não encontrada no quadro \"{{boardName}}\"",
|
|
53
|
+
"cards": "🃏 Cards da Lista: {{name}}",
|
|
54
|
+
"boardLists": "📋 Listas do quadro \"{{boardName}}\":"
|
|
55
|
+
},
|
|
56
|
+
"card": {
|
|
57
|
+
"loading": "⏳ Carregando cards...",
|
|
58
|
+
"empty": "🃏 Nenhum card encontrado nesta lista.",
|
|
59
|
+
"notFound": "❌ Cartão com ID \"{{cardId}}\" não encontrado",
|
|
60
|
+
"created": "✅ Cartão criado com sucesso!",
|
|
61
|
+
"updated": "✅ Cartão atualizado com sucesso!",
|
|
62
|
+
"deleted": "✅ Cartão deletado com sucesso!",
|
|
63
|
+
"moved": "✅ Cartão movido com sucesso!",
|
|
64
|
+
"enterName": "Nome do cartão:",
|
|
65
|
+
"enterDescription": "Descrição (opcional):",
|
|
66
|
+
"confirmDelete": "Tem certeza que deseja deletar \"{{name}}\"?",
|
|
67
|
+
"listCards": "📋 Cartões da lista \"{{listName}}\" no quadro \"{{boardName}}\":",
|
|
68
|
+
"emptyList": "📭 Esta lista está vazia.",
|
|
69
|
+
"selectBoard": "Selecione o quadro:",
|
|
70
|
+
"selectList": "Selecione a lista:",
|
|
71
|
+
"selectCard": "Selecione um cartão:",
|
|
72
|
+
"whatToDo": "O que deseja fazer?",
|
|
73
|
+
"newName": "Novo nome:",
|
|
74
|
+
"newDescription": "Nova descrição:",
|
|
75
|
+
"moveToWhichList": "Mover para qual lista?",
|
|
76
|
+
"cardName": "📝 Nome: {{name}}",
|
|
77
|
+
"cardUrl": "🔗 URL: {{url}}",
|
|
78
|
+
"cardId": "🆔 ID: {{id}}",
|
|
79
|
+
"movedTo": "➡️ Para: {{listName}}",
|
|
80
|
+
"actions": {
|
|
81
|
+
"view": "👁️ Ver Detalhes",
|
|
82
|
+
"create": "➕ Criar Card",
|
|
83
|
+
"edit": "✏️ Editar Card",
|
|
84
|
+
"move": "🔄 Mover Card",
|
|
85
|
+
"delete": "🗑️ Deletar Card",
|
|
86
|
+
"back": "⬅️ Voltar"
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"errors": {
|
|
90
|
+
"general": "❌ Ocorreu um erro: {{message}}",
|
|
91
|
+
"generic": "❌ Erro:",
|
|
92
|
+
"network": "❌ Erro de rede. Verifique sua conexão.",
|
|
93
|
+
"invalidInput": "❌ Entrada inválida: {{field}}",
|
|
94
|
+
"required": "❌ Campo obrigatório: {{field}}"
|
|
95
|
+
},
|
|
96
|
+
"commands": {
|
|
97
|
+
"boards": {
|
|
98
|
+
"description": "Lista todos os boards disponíveis",
|
|
99
|
+
"success": "📋 Boards carregados com sucesso!"
|
|
100
|
+
},
|
|
101
|
+
"lists": {
|
|
102
|
+
"description": "Lista as listas de um board específico",
|
|
103
|
+
"boardRequired": "❌ Nome do board é obrigatório",
|
|
104
|
+
"success": "📝 Listas carregadas com sucesso!"
|
|
105
|
+
},
|
|
106
|
+
"cards": {
|
|
107
|
+
"description": "Lista os cards de uma lista específica",
|
|
108
|
+
"boardRequired": "❌ Nome do board é obrigatório",
|
|
109
|
+
"listRequired": "❌ Nome da lista é obrigatório",
|
|
110
|
+
"success": "🃏 Cards carregados com sucesso!"
|
|
111
|
+
},
|
|
112
|
+
"createCard": {
|
|
113
|
+
"description": "Cria um novo card em uma lista",
|
|
114
|
+
"nameRequired": "❌ Nome do card é obrigatório",
|
|
115
|
+
"success": "✅ Card '{{name}}' criado com sucesso!"
|
|
116
|
+
},
|
|
117
|
+
"moveCard": {
|
|
118
|
+
"description": "Move um card para outra lista",
|
|
119
|
+
"cardIdRequired": "❌ ID do card é obrigatório",
|
|
120
|
+
"targetListRequired": "❌ ID da lista de destino é obrigatório",
|
|
121
|
+
"success": "✅ Card movido com sucesso!"
|
|
122
|
+
},
|
|
123
|
+
"deleteCard": {
|
|
124
|
+
"description": "Deleta um card",
|
|
125
|
+
"cardIdRequired": "❌ ID do card é obrigatório",
|
|
126
|
+
"success": "✅ Card deletado com sucesso!"
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ConfigRepository } from '@domain/repositories';
|
|
2
2
|
import { AuthenticateUserUseCase } from '@application/use-cases';
|
|
3
3
|
import inquirer from 'inquirer';
|
|
4
|
+
import { t } from '@/i18n';
|
|
4
5
|
|
|
5
6
|
export class AuthController {
|
|
6
7
|
private authenticateUseCase: AuthenticateUserUseCase;
|
|
@@ -12,7 +13,7 @@ export class AuthController {
|
|
|
12
13
|
async ensureAuthenticated(): Promise<void> {
|
|
13
14
|
const result = await this.authenticateUseCase.execute();
|
|
14
15
|
if (!result.success) {
|
|
15
|
-
console.log(
|
|
16
|
+
console.log(t('auth.notAuthenticated'));
|
|
16
17
|
await this.setupToken();
|
|
17
18
|
}
|
|
18
19
|
}
|
|
@@ -22,14 +23,13 @@ export class AuthController {
|
|
|
22
23
|
{
|
|
23
24
|
type: 'input',
|
|
24
25
|
name: 'token',
|
|
25
|
-
message: '
|
|
26
|
-
validate: input =>
|
|
27
|
-
input.startsWith('ATTA') || 'Token deve começar com ATTA',
|
|
26
|
+
message: t('auth.enterToken'),
|
|
27
|
+
validate: input => input.startsWith('ATTA') || t('auth.tokenInvalid'),
|
|
28
28
|
},
|
|
29
29
|
]);
|
|
30
30
|
|
|
31
31
|
const result = await this.authenticateUseCase.execute(token);
|
|
32
|
-
console.log(result.message);
|
|
32
|
+
console.log(result.success ? t('auth.tokenSaved') : result.message);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
async getConfig() {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { TrelloRepository } from '@domain/repositories';
|
|
2
|
+
|
|
2
3
|
import { GetBoardsUseCase, GetCardsUseCase, GetListsUseCase } from '@application/use-cases';
|
|
4
|
+
import { t } from '@/i18n';
|
|
3
5
|
|
|
4
6
|
export class BoardController {
|
|
5
7
|
private getBoardsUseCase: GetBoardsUseCase;
|
|
@@ -15,7 +17,7 @@ export class BoardController {
|
|
|
15
17
|
async showBoards(): Promise<void> {
|
|
16
18
|
const boards = await this.getBoardsUseCase.execute();
|
|
17
19
|
|
|
18
|
-
console.log('
|
|
20
|
+
console.log(t('board.yourBoards'));
|
|
19
21
|
boards.forEach((board, index) => {
|
|
20
22
|
console.log(`${index + 1}. ${board.name}`);
|
|
21
23
|
console.log(` 🔗 ${board.url}`);
|
|
@@ -28,12 +30,12 @@ export class BoardController {
|
|
|
28
30
|
const board = boards.find(b => b.name === boardName);
|
|
29
31
|
|
|
30
32
|
if (!board) {
|
|
31
|
-
throw new Error(
|
|
33
|
+
throw new Error(t('board.notFound', { name: boardName }));
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
const lists = await this.getListsUseCase.execute(board.id);
|
|
35
37
|
|
|
36
|
-
console.log(
|
|
38
|
+
console.log(t('list.boardLists', { boardName }));
|
|
37
39
|
lists.forEach((list, index) => {
|
|
38
40
|
console.log(`${index + 1}. ${list.name}`);
|
|
39
41
|
console.log(` 🆔 ${list.id}\n`);
|
|
@@ -45,23 +47,21 @@ export class BoardController {
|
|
|
45
47
|
const board = boards.find(b => b.name === boardName);
|
|
46
48
|
|
|
47
49
|
if (!board) {
|
|
48
|
-
throw new Error(
|
|
50
|
+
throw new Error(t('board.notFound', { name: boardName }));
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
const lists = await this.getListsUseCase.execute(board.id);
|
|
52
54
|
const list = lists.find(l => l.name === listName);
|
|
53
55
|
|
|
54
56
|
if (!list) {
|
|
55
|
-
throw new Error(
|
|
56
|
-
`Lista "${listName}" não encontrada no quadro "${boardName}"`,
|
|
57
|
-
);
|
|
57
|
+
throw new Error(t('list.notFound', { listName, boardName }));
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
const cards = await this.getCardsUseCase.execute(list.id);
|
|
61
61
|
|
|
62
|
-
console.log(
|
|
62
|
+
console.log(t('card.listCards', { listName, boardName }));
|
|
63
63
|
if (cards.length === 0) {
|
|
64
|
-
console.log('
|
|
64
|
+
console.log(t('card.emptyList'));
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
67
|
|