trello-cli-unofficial 0.14.0 → 0.15.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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [0.15.0](https://github.com/JaegerCaiser/trello-cli-unofficial/compare/v0.14.0...v0.15.0) (2026-04-05)
2
+
3
+
4
+ ### Features
5
+
6
+ * inclui comandos faltantes de checklist ([5479ea0](https://github.com/JaegerCaiser/trello-cli-unofficial/commit/5479ea09d7349a76df5826414b9ba12a5ec3c40f))
7
+
1
8
  # [0.14.0](https://github.com/JaegerCaiser/trello-cli-unofficial/compare/v0.13.14...v0.14.0) (2026-04-04)
2
9
 
3
10
 
package/dist/main.js CHANGED
@@ -2973,12 +2973,20 @@ var require_en = __commonJS((exports, module) => {
2973
2973
  created: '\u2705 Checklist "{{name}}" created successfully!',
2974
2974
  checklistId: "\uD83C\uDD94 ID: {{id}}",
2975
2975
  checklistCard: "\uD83D\uDCCB Card ID: {{idCard}}",
2976
+ deleted: "\u2705 Checklist deleted successfully!",
2977
+ renamed: '\u2705 Checklist renamed to "{{name}}" successfully!',
2976
2978
  itemAdded: '\u2705 Item "{{name}}" added to checklist successfully!',
2979
+ itemDeleted: "\u2705 Checklist item deleted successfully!",
2980
+ itemRenamed: '\u2705 Item renamed to "{{name}}" successfully!',
2981
+ itemChecked: '\u2705 Item "{{name}}" marked as complete!',
2982
+ itemUnchecked: '\u2705 Item "{{name}}" marked as incomplete!',
2977
2983
  itemId: "\uD83C\uDD94 ID: {{id}}",
2978
2984
  itemState: "\uD83D\uDCCC State: {{state}}",
2985
+ forceRequired: "\u26A0\uFE0F This operation is destructive. Add --force to confirm.",
2979
2986
  validation: {
2980
2987
  requiredName: "Checklist name is required",
2981
- requiredItemName: "Item name is required"
2988
+ requiredItemName: "Item name is required",
2989
+ requiredItemId: "Item ID is required"
2982
2990
  }
2983
2991
  },
2984
2992
  errors: {
@@ -3134,11 +3142,37 @@ var require_en = __commonJS((exports, module) => {
3134
3142
  description: "Create a checklist on a card",
3135
3143
  nameOption: "Checklist name"
3136
3144
  },
3145
+ delete: {
3146
+ description: "Delete a checklist",
3147
+ forceOption: "Skip confirmation"
3148
+ },
3149
+ rename: {
3150
+ description: "Rename a checklist",
3151
+ nameOption: "New checklist name"
3152
+ },
3137
3153
  item: {
3138
3154
  description: "Manage checklist items",
3139
3155
  add: {
3140
3156
  description: "Add an item to a checklist",
3141
3157
  nameOption: "Item name"
3158
+ },
3159
+ delete: {
3160
+ description: "Delete an item from a checklist",
3161
+ itemOption: "Item ID to delete",
3162
+ forceOption: "Skip confirmation"
3163
+ },
3164
+ rename: {
3165
+ description: "Rename an item of a checklist",
3166
+ itemOption: "Item ID to rename",
3167
+ nameOption: "New item name"
3168
+ },
3169
+ check: {
3170
+ description: "Mark a checklist item as complete",
3171
+ itemOption: "Item ID to check"
3172
+ },
3173
+ uncheck: {
3174
+ description: "Mark a checklist item as incomplete",
3175
+ itemOption: "Item ID to uncheck"
3142
3176
  }
3143
3177
  }
3144
3178
  }
@@ -3298,12 +3332,20 @@ var require_pt_BR = __commonJS((exports, module) => {
3298
3332
  created: '\u2705 Checklist "{{name}}" criado com sucesso!',
3299
3333
  checklistId: "\uD83C\uDD94 ID: {{id}}",
3300
3334
  checklistCard: "\uD83D\uDCCB ID do Card: {{idCard}}",
3335
+ deleted: "\u2705 Checklist deletado com sucesso!",
3336
+ renamed: '\u2705 Checklist renomeado para "{{name}}" com sucesso!',
3301
3337
  itemAdded: '\u2705 Item "{{name}}" adicionado ao checklist com sucesso!',
3338
+ itemDeleted: "\u2705 Item do checklist deletado com sucesso!",
3339
+ itemRenamed: '\u2705 Item renomeado para "{{name}}" com sucesso!',
3340
+ itemChecked: '\u2705 Item "{{name}}" marcado como conclu\xEDdo!',
3341
+ itemUnchecked: '\u2705 Item "{{name}}" marcado como incompleto!',
3302
3342
  itemId: "\uD83C\uDD94 ID: {{id}}",
3303
3343
  itemState: "\uD83D\uDCCC Estado: {{state}}",
3344
+ forceRequired: "\u26A0\uFE0F Esta opera\xE7\xE3o \xE9 destrutiva. Adicione --force para confirmar.",
3304
3345
  validation: {
3305
3346
  requiredName: "Nome do checklist \xE9 obrigat\xF3rio",
3306
- requiredItemName: "Nome do item \xE9 obrigat\xF3rio"
3347
+ requiredItemName: "Nome do item \xE9 obrigat\xF3rio",
3348
+ requiredItemId: "ID do item \xE9 obrigat\xF3rio"
3307
3349
  }
3308
3350
  },
3309
3351
  errors: {
@@ -3459,11 +3501,37 @@ var require_pt_BR = __commonJS((exports, module) => {
3459
3501
  description: "Cria um checklist em um card",
3460
3502
  nameOption: "Nome do checklist"
3461
3503
  },
3504
+ delete: {
3505
+ description: "Deleta um checklist",
3506
+ forceOption: "Pular confirma\xE7\xE3o"
3507
+ },
3508
+ rename: {
3509
+ description: "Renomeia um checklist",
3510
+ nameOption: "Novo nome do checklist"
3511
+ },
3462
3512
  item: {
3463
3513
  description: "Gerencia itens de checklist",
3464
3514
  add: {
3465
3515
  description: "Adiciona um item a um checklist",
3466
3516
  nameOption: "Nome do item"
3517
+ },
3518
+ delete: {
3519
+ description: "Deleta um item de um checklist",
3520
+ itemOption: "ID do item a deletar",
3521
+ forceOption: "Pular confirma\xE7\xE3o"
3522
+ },
3523
+ rename: {
3524
+ description: "Renomeia um item de um checklist",
3525
+ itemOption: "ID do item a renomear",
3526
+ nameOption: "Novo nome do item"
3527
+ },
3528
+ check: {
3529
+ description: "Marca um item do checklist como conclu\xEDdo",
3530
+ itemOption: "ID do item a marcar"
3531
+ },
3532
+ uncheck: {
3533
+ description: "Marca um item do checklist como incompleto",
3534
+ itemOption: "ID do item a desmarcar"
3467
3535
  }
3468
3536
  }
3469
3537
  }
@@ -3722,6 +3790,28 @@ class DeleteCardUseCase {
3722
3790
  }
3723
3791
  }
3724
3792
 
3793
+ // src/application/use-cases/DeleteChecklistItemUseCase.ts
3794
+ class DeleteChecklistItemUseCase {
3795
+ trelloRepository;
3796
+ constructor(trelloRepository) {
3797
+ this.trelloRepository = trelloRepository;
3798
+ }
3799
+ async execute(checklistId, itemId) {
3800
+ await this.trelloRepository.deleteChecklistItem(checklistId, itemId);
3801
+ }
3802
+ }
3803
+
3804
+ // src/application/use-cases/DeleteChecklistUseCase.ts
3805
+ class DeleteChecklistUseCase {
3806
+ trelloRepository;
3807
+ constructor(trelloRepository) {
3808
+ this.trelloRepository = trelloRepository;
3809
+ }
3810
+ async execute(checklistId) {
3811
+ await this.trelloRepository.deleteChecklist(checklistId);
3812
+ }
3813
+ }
3814
+
3725
3815
  // src/application/use-cases/GetBoardDetailsUseCase.ts
3726
3816
  class GetBoardDetailsUseCase {
3727
3817
  trelloRepository;
@@ -3811,6 +3901,40 @@ class MoveCardUseCase {
3811
3901
  }
3812
3902
  }
3813
3903
 
3904
+ // src/application/use-cases/RenameChecklistItemUseCase.ts
3905
+ class RenameChecklistItemUseCase {
3906
+ trelloRepository;
3907
+ constructor(trelloRepository) {
3908
+ this.trelloRepository = trelloRepository;
3909
+ }
3910
+ async execute(cardId, itemId, name) {
3911
+ if (!name.trim()) {
3912
+ throw new Error(t2("checklist.validation.requiredItemName"));
3913
+ }
3914
+ return await this.trelloRepository.renameChecklistItem(cardId, itemId, name);
3915
+ }
3916
+ }
3917
+ var init_RenameChecklistItemUseCase = __esm(() => {
3918
+ init_i18n();
3919
+ });
3920
+
3921
+ // src/application/use-cases/RenameChecklistUseCase.ts
3922
+ class RenameChecklistUseCase {
3923
+ trelloRepository;
3924
+ constructor(trelloRepository) {
3925
+ this.trelloRepository = trelloRepository;
3926
+ }
3927
+ async execute(checklistId, name) {
3928
+ if (!name.trim()) {
3929
+ throw new Error(t2("checklist.validation.requiredName"));
3930
+ }
3931
+ return await this.trelloRepository.renameChecklist(checklistId, name);
3932
+ }
3933
+ }
3934
+ var init_RenameChecklistUseCase = __esm(() => {
3935
+ init_i18n();
3936
+ });
3937
+
3814
3938
  // src/application/use-cases/UpdateCardUseCase.ts
3815
3939
  class UpdateCardUseCase {
3816
3940
  trelloRepository;
@@ -3828,6 +3952,17 @@ var init_UpdateCardUseCase = __esm(() => {
3828
3952
  init_i18n();
3829
3953
  });
3830
3954
 
3955
+ // src/application/use-cases/UpdateChecklistItemStateUseCase.ts
3956
+ class UpdateChecklistItemStateUseCase {
3957
+ trelloRepository;
3958
+ constructor(trelloRepository) {
3959
+ this.trelloRepository = trelloRepository;
3960
+ }
3961
+ async execute(cardId, itemId, state) {
3962
+ return await this.trelloRepository.updateChecklistItemState(cardId, itemId, state);
3963
+ }
3964
+ }
3965
+
3831
3966
  // src/application/use-cases/index.ts
3832
3967
  var init_use_cases = __esm(() => {
3833
3968
  init_AddChecklistItemUseCase();
@@ -3837,6 +3972,8 @@ var init_use_cases = __esm(() => {
3837
3972
  init_CreateChecklistUseCase();
3838
3973
  init_CreateListUseCase();
3839
3974
  init_GetBoardDetailsUseCase();
3975
+ init_RenameChecklistItemUseCase();
3976
+ init_RenameChecklistUseCase();
3840
3977
  init_UpdateCardUseCase();
3841
3978
  });
3842
3979
 
@@ -26119,11 +26256,21 @@ var init_CardController = __esm(() => {
26119
26256
  class ChecklistController {
26120
26257
  outputFormatter;
26121
26258
  createChecklistUseCase;
26259
+ deleteChecklistUseCase;
26260
+ renameChecklistUseCase;
26122
26261
  addChecklistItemUseCase;
26262
+ deleteChecklistItemUseCase;
26263
+ renameChecklistItemUseCase;
26264
+ updateChecklistItemStateUseCase;
26123
26265
  constructor(trelloRepository, outputFormatter) {
26124
26266
  this.outputFormatter = outputFormatter;
26125
26267
  this.createChecklistUseCase = new CreateChecklistUseCase(trelloRepository);
26268
+ this.deleteChecklistUseCase = new DeleteChecklistUseCase(trelloRepository);
26269
+ this.renameChecklistUseCase = new RenameChecklistUseCase(trelloRepository);
26126
26270
  this.addChecklistItemUseCase = new AddChecklistItemUseCase(trelloRepository);
26271
+ this.deleteChecklistItemUseCase = new DeleteChecklistItemUseCase(trelloRepository);
26272
+ this.renameChecklistItemUseCase = new RenameChecklistItemUseCase(trelloRepository);
26273
+ this.updateChecklistItemStateUseCase = new UpdateChecklistItemStateUseCase(trelloRepository);
26127
26274
  }
26128
26275
  async createChecklist(cardId, name) {
26129
26276
  const checklist = await this.createChecklistUseCase.execute(cardId, name);
@@ -26135,6 +26282,23 @@ class ChecklistController {
26135
26282
  fields: ["id", "name", "idCard", "checkItems"]
26136
26283
  });
26137
26284
  }
26285
+ async deleteChecklist(checklistId, force) {
26286
+ if (!force) {
26287
+ this.outputFormatter.warning(t2("checklist.forceRequired"));
26288
+ return;
26289
+ }
26290
+ await this.deleteChecklistUseCase.execute(checklistId);
26291
+ this.outputFormatter.success(t2("checklist.deleted"));
26292
+ }
26293
+ async renameChecklist(checklistId, name) {
26294
+ const checklist = await this.renameChecklistUseCase.execute(checklistId, name);
26295
+ this.outputFormatter.success(t2("checklist.renamed", { name: checklist.name }));
26296
+ console.log(t2("checklist.checklistId", { id: checklist.id }));
26297
+ this.outputFormatter.output([checklist], {
26298
+ headers: ["ID", "Name", "Card ID"],
26299
+ fields: ["id", "name", "idCard"]
26300
+ });
26301
+ }
26138
26302
  async addChecklistItem(checklistId, name) {
26139
26303
  const item = await this.addChecklistItemUseCase.execute(checklistId, name);
26140
26304
  console.log(t2("checklist.itemAdded", { name: item.name }));
@@ -26145,6 +26309,44 @@ class ChecklistController {
26145
26309
  fields: ["id", "name", "state", "idChecklist"]
26146
26310
  });
26147
26311
  }
26312
+ async deleteChecklistItem(checklistId, itemId, force) {
26313
+ if (!force) {
26314
+ this.outputFormatter.warning(t2("checklist.forceRequired"));
26315
+ return;
26316
+ }
26317
+ await this.deleteChecklistItemUseCase.execute(checklistId, itemId);
26318
+ this.outputFormatter.success(t2("checklist.itemDeleted"));
26319
+ }
26320
+ async renameChecklistItem(cardId, itemId, name) {
26321
+ const item = await this.renameChecklistItemUseCase.execute(cardId, itemId, name);
26322
+ this.outputFormatter.success(t2("checklist.itemRenamed", { name: item.name }));
26323
+ console.log(t2("checklist.itemId", { id: item.id }));
26324
+ console.log(t2("checklist.itemState", { state: item.state }));
26325
+ this.outputFormatter.output([item], {
26326
+ headers: ["ID", "Name", "State", "Checklist ID"],
26327
+ fields: ["id", "name", "state", "idChecklist"]
26328
+ });
26329
+ }
26330
+ async checkItem(cardId, itemId) {
26331
+ const item = await this.updateChecklistItemStateUseCase.execute(cardId, itemId, "complete");
26332
+ this.outputFormatter.success(t2("checklist.itemChecked", { name: item.name }));
26333
+ console.log(t2("checklist.itemId", { id: item.id }));
26334
+ console.log(t2("checklist.itemState", { state: item.state }));
26335
+ this.outputFormatter.output([item], {
26336
+ headers: ["ID", "Name", "State", "Checklist ID"],
26337
+ fields: ["id", "name", "state", "idChecklist"]
26338
+ });
26339
+ }
26340
+ async uncheckItem(cardId, itemId) {
26341
+ const item = await this.updateChecklistItemStateUseCase.execute(cardId, itemId, "incomplete");
26342
+ this.outputFormatter.success(t2("checklist.itemUnchecked", { name: item.name }));
26343
+ console.log(t2("checklist.itemId", { id: item.id }));
26344
+ console.log(t2("checklist.itemState", { state: item.state }));
26345
+ this.outputFormatter.output([item], {
26346
+ headers: ["ID", "Name", "State", "Checklist ID"],
26347
+ fields: ["id", "name", "state", "idChecklist"]
26348
+ });
26349
+ }
26148
26350
  }
26149
26351
  var init_ChecklistController = __esm(() => {
26150
26352
  init_use_cases();
@@ -28626,6 +28828,61 @@ ${errorText}`);
28626
28828
  });
28627
28829
  return ChecklistItemEntity.fromApiResponse(data);
28628
28830
  }
28831
+ async deleteChecklist(checklistId) {
28832
+ await this.request(`/checklists/${checklistId}`, {
28833
+ method: "DELETE"
28834
+ });
28835
+ }
28836
+ async renameChecklist(checklistId, name) {
28837
+ const body = new URLSearchParams({
28838
+ name,
28839
+ key: this.apiKey,
28840
+ token: this.token
28841
+ });
28842
+ const data = await this.request(`/checklists/${checklistId}`, {
28843
+ method: "PUT",
28844
+ headers: {
28845
+ "Content-Type": "application/x-www-form-urlencoded"
28846
+ },
28847
+ body: body.toString()
28848
+ });
28849
+ return ChecklistEntity.fromApiResponse(data);
28850
+ }
28851
+ async deleteChecklistItem(checklistId, itemId) {
28852
+ await this.request(`/checklists/${checklistId}/checkItems/${itemId}`, {
28853
+ method: "DELETE"
28854
+ });
28855
+ }
28856
+ async renameChecklistItem(cardId, itemId, name) {
28857
+ const body = new URLSearchParams({
28858
+ name,
28859
+ key: this.apiKey,
28860
+ token: this.token
28861
+ });
28862
+ const data = await this.request(`/cards/${cardId}/checklistItem/${itemId}`, {
28863
+ method: "PUT",
28864
+ headers: {
28865
+ "Content-Type": "application/x-www-form-urlencoded"
28866
+ },
28867
+ body: body.toString()
28868
+ });
28869
+ return ChecklistItemEntity.fromApiResponse(data);
28870
+ }
28871
+ async updateChecklistItemState(cardId, itemId, state) {
28872
+ const body = new URLSearchParams({
28873
+ state,
28874
+ key: this.apiKey,
28875
+ token: this.token
28876
+ });
28877
+ const data = await this.request(`/cards/${cardId}/checklistItem/${itemId}`, {
28878
+ method: "PUT",
28879
+ headers: {
28880
+ "Content-Type": "application/x-www-form-urlencoded"
28881
+ },
28882
+ body: body.toString()
28883
+ });
28884
+ return ChecklistItemEntity.fromApiResponse(data);
28885
+ }
28629
28886
  }
28630
28887
  var init_TrelloApiRepository = __esm(() => {
28631
28888
  init_entities();
@@ -31310,6 +31567,21 @@ class CommandController {
31310
31567
  await this.checklistController.createChecklist(cardId, options.name);
31311
31568
  }, "checklists create");
31312
31569
  });
31570
+ checklistsCmd.command("delete <checklistId>").description(t2("commands.checklists.delete.description")).option("--force", t2("commands.checklists.delete.forceOption")).action(async (checklistId, options) => {
31571
+ await ErrorHandler.withErrorHandling(async () => {
31572
+ await this.initializeTrelloControllers();
31573
+ await this.checklistController.deleteChecklist(checklistId, options.force ?? false);
31574
+ }, "checklists delete");
31575
+ });
31576
+ checklistsCmd.command("rename <checklistId>").description(t2("commands.checklists.rename.description")).requiredOption("-n, --name <name>", t2("commands.checklists.rename.nameOption")).option("-f, --format <format>", t2("commands.formatOption"), "table").action(async (checklistId, options) => {
31577
+ await ErrorHandler.withErrorHandling(async () => {
31578
+ await this.initializeTrelloControllers();
31579
+ if (options.format) {
31580
+ this.outputFormatter.setFormat(options.format);
31581
+ }
31582
+ await this.checklistController.renameChecklist(checklistId, options.name);
31583
+ }, "checklists rename");
31584
+ });
31313
31585
  const checklistItemCmd = checklistsCmd.command("item").description(t2("commands.checklists.item.description"));
31314
31586
  checklistItemCmd.command("add <checklistId>").description(t2("commands.checklists.item.add.description")).requiredOption("-n, --name <name>", t2("commands.checklists.item.add.nameOption")).option("-f, --format <format>", t2("commands.formatOption"), "table").action(async (checklistId, options) => {
31315
31587
  await ErrorHandler.withErrorHandling(async () => {
@@ -31320,6 +31592,39 @@ class CommandController {
31320
31592
  await this.checklistController.addChecklistItem(checklistId, options.name);
31321
31593
  }, "checklists-item-add");
31322
31594
  });
31595
+ checklistItemCmd.command("delete <checklistId>").description(t2("commands.checklists.item.delete.description")).requiredOption("--item <itemId>", t2("commands.checklists.item.delete.itemOption")).option("--force", t2("commands.checklists.item.delete.forceOption")).action(async (checklistId, options) => {
31596
+ await ErrorHandler.withErrorHandling(async () => {
31597
+ await this.initializeTrelloControllers();
31598
+ await this.checklistController.deleteChecklistItem(checklistId, options.item, options.force ?? false);
31599
+ }, "checklists-item-delete");
31600
+ });
31601
+ checklistItemCmd.command("rename <cardId>").description(t2("commands.checklists.item.rename.description")).requiredOption("--item <itemId>", t2("commands.checklists.item.rename.itemOption")).requiredOption("-n, --name <name>", t2("commands.checklists.item.rename.nameOption")).option("-f, --format <format>", t2("commands.formatOption"), "table").action(async (cardId, options) => {
31602
+ await ErrorHandler.withErrorHandling(async () => {
31603
+ await this.initializeTrelloControllers();
31604
+ if (options.format) {
31605
+ this.outputFormatter.setFormat(options.format);
31606
+ }
31607
+ await this.checklistController.renameChecklistItem(cardId, options.item, options.name);
31608
+ }, "checklists-item-rename");
31609
+ });
31610
+ checklistItemCmd.command("check <cardId>").description(t2("commands.checklists.item.check.description")).requiredOption("--item <itemId>", t2("commands.checklists.item.check.itemOption")).option("-f, --format <format>", t2("commands.formatOption"), "table").action(async (cardId, options) => {
31611
+ await ErrorHandler.withErrorHandling(async () => {
31612
+ await this.initializeTrelloControllers();
31613
+ if (options.format) {
31614
+ this.outputFormatter.setFormat(options.format);
31615
+ }
31616
+ await this.checklistController.checkItem(cardId, options.item);
31617
+ }, "checklists-item-check");
31618
+ });
31619
+ checklistItemCmd.command("uncheck <cardId>").description(t2("commands.checklists.item.uncheck.description")).requiredOption("--item <itemId>", t2("commands.checklists.item.uncheck.itemOption")).option("-f, --format <format>", t2("commands.formatOption"), "table").action(async (cardId, options) => {
31620
+ await ErrorHandler.withErrorHandling(async () => {
31621
+ await this.initializeTrelloControllers();
31622
+ if (options.format) {
31623
+ this.outputFormatter.setFormat(options.format);
31624
+ }
31625
+ await this.checklistController.uncheckItem(cardId, options.item);
31626
+ }, "checklists-item-uncheck");
31627
+ });
31323
31628
  }
31324
31629
  async run() {
31325
31630
  if (!this.program) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "trello-cli-unofficial",
3
3
  "type": "module",
4
- "version": "0.14.0",
4
+ "version": "0.15.0",
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/)",
@@ -0,0 +1,9 @@
1
+ import type { TrelloRepository } from '@domain/repositories';
2
+
3
+ export class DeleteChecklistItemUseCase {
4
+ constructor(private trelloRepository: TrelloRepository) {}
5
+
6
+ async execute(checklistId: string, itemId: string): Promise<void> {
7
+ await this.trelloRepository.deleteChecklistItem(checklistId, itemId);
8
+ }
9
+ }
@@ -0,0 +1,9 @@
1
+ import type { TrelloRepository } from '@domain/repositories';
2
+
3
+ export class DeleteChecklistUseCase {
4
+ constructor(private trelloRepository: TrelloRepository) {}
5
+
6
+ async execute(checklistId: string): Promise<void> {
7
+ await this.trelloRepository.deleteChecklist(checklistId);
8
+ }
9
+ }
@@ -0,0 +1,15 @@
1
+ import type { ChecklistItemEntity } from '@domain/entities';
2
+ import type { TrelloRepository } from '@domain/repositories';
3
+ import { t } from '@/i18n';
4
+
5
+ export class RenameChecklistItemUseCase {
6
+ constructor(private trelloRepository: TrelloRepository) {}
7
+
8
+ async execute(cardId: string, itemId: string, name: string): Promise<ChecklistItemEntity> {
9
+ if (!name.trim()) {
10
+ throw new Error(t('checklist.validation.requiredItemName'));
11
+ }
12
+
13
+ return await this.trelloRepository.renameChecklistItem(cardId, itemId, name);
14
+ }
15
+ }
@@ -0,0 +1,15 @@
1
+ import type { ChecklistEntity } from '@domain/entities';
2
+ import type { TrelloRepository } from '@domain/repositories';
3
+ import { t } from '@/i18n';
4
+
5
+ export class RenameChecklistUseCase {
6
+ constructor(private trelloRepository: TrelloRepository) {}
7
+
8
+ async execute(checklistId: string, name: string): Promise<ChecklistEntity> {
9
+ if (!name.trim()) {
10
+ throw new Error(t('checklist.validation.requiredName'));
11
+ }
12
+
13
+ return await this.trelloRepository.renameChecklist(checklistId, name);
14
+ }
15
+ }
@@ -0,0 +1,14 @@
1
+ import type { ChecklistItemEntity } from '@domain/entities';
2
+ import type { TrelloRepository } from '@domain/repositories';
3
+
4
+ export class UpdateChecklistItemStateUseCase {
5
+ constructor(private trelloRepository: TrelloRepository) {}
6
+
7
+ async execute(
8
+ cardId: string,
9
+ itemId: string,
10
+ state: 'complete' | 'incomplete',
11
+ ): Promise<ChecklistItemEntity> {
12
+ return await this.trelloRepository.updateChecklistItemState(cardId, itemId, state);
13
+ }
14
+ }
@@ -5,10 +5,15 @@ export * from './CreateCardUseCase';
5
5
  export * from './CreateChecklistUseCase';
6
6
  export * from './CreateListUseCase';
7
7
  export * from './DeleteCardUseCase';
8
+ export * from './DeleteChecklistItemUseCase';
9
+ export * from './DeleteChecklistUseCase';
8
10
  export * from './GetBoardDetailsUseCase';
9
11
  export * from './GetBoardsUseCase';
10
12
  export * from './GetCardsUseCase';
11
13
  export * from './GetCardUseCase';
12
14
  export * from './GetListsUseCase';
13
15
  export * from './MoveCardUseCase';
16
+ export * from './RenameChecklistItemUseCase';
17
+ export * from './RenameChecklistUseCase';
14
18
  export * from './UpdateCardUseCase';
19
+ export * from './UpdateChecklistItemStateUseCase';
@@ -37,5 +37,10 @@ export interface TrelloRepository {
37
37
  deleteCard: (cardId: string) => Promise<void>;
38
38
  moveCard: (cardId: string, targetListId: string) => Promise<CardEntity>;
39
39
  createChecklist: (cardId: string, name: string) => Promise<ChecklistEntity>;
40
+ deleteChecklist: (checklistId: string) => Promise<void>;
41
+ renameChecklist: (checklistId: string, name: string) => Promise<ChecklistEntity>;
40
42
  addChecklistItem: (checklistId: string, name: string) => Promise<ChecklistItemEntity>;
43
+ deleteChecklistItem: (checklistId: string, itemId: string) => Promise<void>;
44
+ renameChecklistItem: (cardId: string, itemId: string, name: string) => Promise<ChecklistItemEntity>;
45
+ updateChecklistItemState: (cardId: string, itemId: string, state: 'complete' | 'incomplete') => Promise<ChecklistItemEntity>;
41
46
  }
@@ -148,12 +148,20 @@
148
148
  "created": "✅ Checklist \"{{name}}\" created successfully!",
149
149
  "checklistId": "🆔 ID: {{id}}",
150
150
  "checklistCard": "📋 Card ID: {{idCard}}",
151
+ "deleted": "✅ Checklist deleted successfully!",
152
+ "renamed": "✅ Checklist renamed to \"{{name}}\" successfully!",
151
153
  "itemAdded": "✅ Item \"{{name}}\" added to checklist successfully!",
154
+ "itemDeleted": "✅ Checklist item deleted successfully!",
155
+ "itemRenamed": "✅ Item renamed to \"{{name}}\" successfully!",
156
+ "itemChecked": "✅ Item \"{{name}}\" marked as complete!",
157
+ "itemUnchecked": "✅ Item \"{{name}}\" marked as incomplete!",
152
158
  "itemId": "🆔 ID: {{id}}",
153
159
  "itemState": "📌 State: {{state}}",
160
+ "forceRequired": "⚠️ This operation is destructive. Add --force to confirm.",
154
161
  "validation": {
155
162
  "requiredName": "Checklist name is required",
156
- "requiredItemName": "Item name is required"
163
+ "requiredItemName": "Item name is required",
164
+ "requiredItemId": "Item ID is required"
157
165
  }
158
166
  },
159
167
  "errors": {
@@ -309,11 +317,37 @@
309
317
  "description": "Create a checklist on a card",
310
318
  "nameOption": "Checklist name"
311
319
  },
320
+ "delete": {
321
+ "description": "Delete a checklist",
322
+ "forceOption": "Skip confirmation"
323
+ },
324
+ "rename": {
325
+ "description": "Rename a checklist",
326
+ "nameOption": "New checklist name"
327
+ },
312
328
  "item": {
313
329
  "description": "Manage checklist items",
314
330
  "add": {
315
331
  "description": "Add an item to a checklist",
316
332
  "nameOption": "Item name"
333
+ },
334
+ "delete": {
335
+ "description": "Delete an item from a checklist",
336
+ "itemOption": "Item ID to delete",
337
+ "forceOption": "Skip confirmation"
338
+ },
339
+ "rename": {
340
+ "description": "Rename an item of a checklist",
341
+ "itemOption": "Item ID to rename",
342
+ "nameOption": "New item name"
343
+ },
344
+ "check": {
345
+ "description": "Mark a checklist item as complete",
346
+ "itemOption": "Item ID to check"
347
+ },
348
+ "uncheck": {
349
+ "description": "Mark a checklist item as incomplete",
350
+ "itemOption": "Item ID to uncheck"
317
351
  }
318
352
  }
319
353
  }
@@ -148,12 +148,20 @@
148
148
  "created": "✅ Checklist \"{{name}}\" criado com sucesso!",
149
149
  "checklistId": "🆔 ID: {{id}}",
150
150
  "checklistCard": "📋 ID do Card: {{idCard}}",
151
+ "deleted": "✅ Checklist deletado com sucesso!",
152
+ "renamed": "✅ Checklist renomeado para \"{{name}}\" com sucesso!",
151
153
  "itemAdded": "✅ Item \"{{name}}\" adicionado ao checklist com sucesso!",
154
+ "itemDeleted": "✅ Item do checklist deletado com sucesso!",
155
+ "itemRenamed": "✅ Item renomeado para \"{{name}}\" com sucesso!",
156
+ "itemChecked": "✅ Item \"{{name}}\" marcado como concluído!",
157
+ "itemUnchecked": "✅ Item \"{{name}}\" marcado como incompleto!",
152
158
  "itemId": "🆔 ID: {{id}}",
153
159
  "itemState": "📌 Estado: {{state}}",
160
+ "forceRequired": "⚠️ Esta operação é destrutiva. Adicione --force para confirmar.",
154
161
  "validation": {
155
162
  "requiredName": "Nome do checklist é obrigatório",
156
- "requiredItemName": "Nome do item é obrigatório"
163
+ "requiredItemName": "Nome do item é obrigatório",
164
+ "requiredItemId": "ID do item é obrigatório"
157
165
  }
158
166
  },
159
167
  "errors": {
@@ -309,11 +317,37 @@
309
317
  "description": "Cria um checklist em um card",
310
318
  "nameOption": "Nome do checklist"
311
319
  },
320
+ "delete": {
321
+ "description": "Deleta um checklist",
322
+ "forceOption": "Pular confirmação"
323
+ },
324
+ "rename": {
325
+ "description": "Renomeia um checklist",
326
+ "nameOption": "Novo nome do checklist"
327
+ },
312
328
  "item": {
313
329
  "description": "Gerencia itens de checklist",
314
330
  "add": {
315
331
  "description": "Adiciona um item a um checklist",
316
332
  "nameOption": "Nome do item"
333
+ },
334
+ "delete": {
335
+ "description": "Deleta um item de um checklist",
336
+ "itemOption": "ID do item a deletar",
337
+ "forceOption": "Pular confirmação"
338
+ },
339
+ "rename": {
340
+ "description": "Renomeia um item de um checklist",
341
+ "itemOption": "ID do item a renomear",
342
+ "nameOption": "Novo nome do item"
343
+ },
344
+ "check": {
345
+ "description": "Marca um item do checklist como concluído",
346
+ "itemOption": "ID do item a marcar"
347
+ },
348
+ "uncheck": {
349
+ "description": "Marca um item do checklist como incompleto",
350
+ "itemOption": "ID do item a desmarcar"
317
351
  }
318
352
  }
319
353
  }
@@ -330,4 +330,74 @@ export class TrelloApiRepository implements TrelloRepository {
330
330
 
331
331
  return ChecklistItemEntity.fromApiResponse(data as TrelloChecklistItemResponse);
332
332
  }
333
+
334
+ async deleteChecklist(checklistId: string): Promise<void> {
335
+ await this.request(`/checklists/${checklistId}`, {
336
+ method: 'DELETE',
337
+ });
338
+ }
339
+
340
+ async renameChecklist(checklistId: string, name: string): Promise<ChecklistEntity> {
341
+ const body = new URLSearchParams({
342
+ name,
343
+ key: this.apiKey,
344
+ token: this.token,
345
+ });
346
+
347
+ const data = await this.request(`/checklists/${checklistId}`, {
348
+ method: 'PUT',
349
+ headers: {
350
+ 'Content-Type': 'application/x-www-form-urlencoded',
351
+ },
352
+ body: body.toString(),
353
+ });
354
+
355
+ return ChecklistEntity.fromApiResponse(data as TrelloChecklistResponse);
356
+ }
357
+
358
+ async deleteChecklistItem(checklistId: string, itemId: string): Promise<void> {
359
+ await this.request(`/checklists/${checklistId}/checkItems/${itemId}`, {
360
+ method: 'DELETE',
361
+ });
362
+ }
363
+
364
+ async renameChecklistItem(cardId: string, itemId: string, name: string): Promise<ChecklistItemEntity> {
365
+ const body = new URLSearchParams({
366
+ name,
367
+ key: this.apiKey,
368
+ token: this.token,
369
+ });
370
+
371
+ const data = await this.request(`/cards/${cardId}/checklistItem/${itemId}`, {
372
+ method: 'PUT',
373
+ headers: {
374
+ 'Content-Type': 'application/x-www-form-urlencoded',
375
+ },
376
+ body: body.toString(),
377
+ });
378
+
379
+ return ChecklistItemEntity.fromApiResponse(data as TrelloChecklistItemResponse);
380
+ }
381
+
382
+ async updateChecklistItemState(
383
+ cardId: string,
384
+ itemId: string,
385
+ state: 'complete' | 'incomplete',
386
+ ): Promise<ChecklistItemEntity> {
387
+ const body = new URLSearchParams({
388
+ state,
389
+ key: this.apiKey,
390
+ token: this.token,
391
+ });
392
+
393
+ const data = await this.request(`/cards/${cardId}/checklistItem/${itemId}`, {
394
+ method: 'PUT',
395
+ headers: {
396
+ 'Content-Type': 'application/x-www-form-urlencoded',
397
+ },
398
+ body: body.toString(),
399
+ });
400
+
401
+ return ChecklistItemEntity.fromApiResponse(data as TrelloChecklistItemResponse);
402
+ }
333
403
  }
@@ -4,20 +4,35 @@ import type { OutputFormatter } from '@/shared';
4
4
  import {
5
5
  AddChecklistItemUseCase,
6
6
  CreateChecklistUseCase,
7
+ DeleteChecklistItemUseCase,
8
+ DeleteChecklistUseCase,
9
+ RenameChecklistItemUseCase,
10
+ RenameChecklistUseCase,
11
+ UpdateChecklistItemStateUseCase,
7
12
  } from '@application/use-cases';
8
13
 
9
14
  import { t } from '@/i18n';
10
15
 
11
16
  export class ChecklistController {
12
17
  private createChecklistUseCase: CreateChecklistUseCase;
18
+ private deleteChecklistUseCase: DeleteChecklistUseCase;
19
+ private renameChecklistUseCase: RenameChecklistUseCase;
13
20
  private addChecklistItemUseCase: AddChecklistItemUseCase;
21
+ private deleteChecklistItemUseCase: DeleteChecklistItemUseCase;
22
+ private renameChecklistItemUseCase: RenameChecklistItemUseCase;
23
+ private updateChecklistItemStateUseCase: UpdateChecklistItemStateUseCase;
14
24
 
15
25
  constructor(
16
26
  trelloRepository: TrelloRepository,
17
27
  private outputFormatter: OutputFormatter,
18
28
  ) {
19
29
  this.createChecklistUseCase = new CreateChecklistUseCase(trelloRepository);
30
+ this.deleteChecklistUseCase = new DeleteChecklistUseCase(trelloRepository);
31
+ this.renameChecklistUseCase = new RenameChecklistUseCase(trelloRepository);
20
32
  this.addChecklistItemUseCase = new AddChecklistItemUseCase(trelloRepository);
33
+ this.deleteChecklistItemUseCase = new DeleteChecklistItemUseCase(trelloRepository);
34
+ this.renameChecklistItemUseCase = new RenameChecklistItemUseCase(trelloRepository);
35
+ this.updateChecklistItemStateUseCase = new UpdateChecklistItemStateUseCase(trelloRepository);
21
36
  }
22
37
 
23
38
  async createChecklist(cardId: string, name: string): Promise<void> {
@@ -33,6 +48,28 @@ export class ChecklistController {
33
48
  });
34
49
  }
35
50
 
51
+ async deleteChecklist(checklistId: string, force: boolean): Promise<void> {
52
+ if (!force) {
53
+ this.outputFormatter.warning(t('checklist.forceRequired'));
54
+ return;
55
+ }
56
+
57
+ await this.deleteChecklistUseCase.execute(checklistId);
58
+ this.outputFormatter.success(t('checklist.deleted'));
59
+ }
60
+
61
+ async renameChecklist(checklistId: string, name: string): Promise<void> {
62
+ const checklist = await this.renameChecklistUseCase.execute(checklistId, name);
63
+
64
+ this.outputFormatter.success(t('checklist.renamed', { name: checklist.name }));
65
+ console.log(t('checklist.checklistId', { id: checklist.id }));
66
+
67
+ this.outputFormatter.output([checklist], {
68
+ headers: ['ID', 'Name', 'Card ID'],
69
+ fields: ['id', 'name', 'idCard'],
70
+ });
71
+ }
72
+
36
73
  async addChecklistItem(checklistId: string, name: string): Promise<void> {
37
74
  const item = await this.addChecklistItemUseCase.execute(checklistId, name);
38
75
 
@@ -45,4 +82,53 @@ export class ChecklistController {
45
82
  fields: ['id', 'name', 'state', 'idChecklist'],
46
83
  });
47
84
  }
85
+
86
+ async deleteChecklistItem(checklistId: string, itemId: string, force: boolean): Promise<void> {
87
+ if (!force) {
88
+ this.outputFormatter.warning(t('checklist.forceRequired'));
89
+ return;
90
+ }
91
+
92
+ await this.deleteChecklistItemUseCase.execute(checklistId, itemId);
93
+ this.outputFormatter.success(t('checklist.itemDeleted'));
94
+ }
95
+
96
+ async renameChecklistItem(cardId: string, itemId: string, name: string): Promise<void> {
97
+ const item = await this.renameChecklistItemUseCase.execute(cardId, itemId, name);
98
+
99
+ this.outputFormatter.success(t('checklist.itemRenamed', { name: item.name }));
100
+ console.log(t('checklist.itemId', { id: item.id }));
101
+ console.log(t('checklist.itemState', { state: item.state }));
102
+
103
+ this.outputFormatter.output([item], {
104
+ headers: ['ID', 'Name', 'State', 'Checklist ID'],
105
+ fields: ['id', 'name', 'state', 'idChecklist'],
106
+ });
107
+ }
108
+
109
+ async checkItem(cardId: string, itemId: string): Promise<void> {
110
+ const item = await this.updateChecklistItemStateUseCase.execute(cardId, itemId, 'complete');
111
+
112
+ this.outputFormatter.success(t('checklist.itemChecked', { name: item.name }));
113
+ console.log(t('checklist.itemId', { id: item.id }));
114
+ console.log(t('checklist.itemState', { state: item.state }));
115
+
116
+ this.outputFormatter.output([item], {
117
+ headers: ['ID', 'Name', 'State', 'Checklist ID'],
118
+ fields: ['id', 'name', 'state', 'idChecklist'],
119
+ });
120
+ }
121
+
122
+ async uncheckItem(cardId: string, itemId: string): Promise<void> {
123
+ const item = await this.updateChecklistItemStateUseCase.execute(cardId, itemId, 'incomplete');
124
+
125
+ this.outputFormatter.success(t('checklist.itemUnchecked', { name: item.name }));
126
+ console.log(t('checklist.itemId', { id: item.id }));
127
+ console.log(t('checklist.itemState', { state: item.state }));
128
+
129
+ this.outputFormatter.output([item], {
130
+ headers: ['ID', 'Name', 'State', 'Checklist ID'],
131
+ fields: ['id', 'name', 'state', 'idChecklist'],
132
+ });
133
+ }
48
134
  }
@@ -477,6 +477,32 @@ export class CommandController {
477
477
  }, 'checklists create');
478
478
  });
479
479
 
480
+ checklistsCmd
481
+ .command('delete <checklistId>')
482
+ .description(t('commands.checklists.delete.description'))
483
+ .option('--force', t('commands.checklists.delete.forceOption'))
484
+ .action(async (checklistId: string, options: { force?: boolean }) => {
485
+ await ErrorHandler.withErrorHandling(async () => {
486
+ await this.initializeTrelloControllers();
487
+ await this.checklistController.deleteChecklist(checklistId, options.force ?? false);
488
+ }, 'checklists delete');
489
+ });
490
+
491
+ checklistsCmd
492
+ .command('rename <checklistId>')
493
+ .description(t('commands.checklists.rename.description'))
494
+ .requiredOption('-n, --name <name>', t('commands.checklists.rename.nameOption'))
495
+ .option('-f, --format <format>', t('commands.formatOption'), 'table')
496
+ .action(async (checklistId: string, options: { name: string; format?: string }) => {
497
+ await ErrorHandler.withErrorHandling(async () => {
498
+ await this.initializeTrelloControllers();
499
+ if (options.format) {
500
+ this.outputFormatter.setFormat(options.format as import('@/shared').OutputFormat);
501
+ }
502
+ await this.checklistController.renameChecklist(checklistId, options.name);
503
+ }, 'checklists rename');
504
+ });
505
+
480
506
  const checklistItemCmd = checklistsCmd
481
507
  .command('item')
482
508
  .description(t('commands.checklists.item.description'));
@@ -495,6 +521,64 @@ export class CommandController {
495
521
  await this.checklistController.addChecklistItem(checklistId, options.name);
496
522
  }, 'checklists-item-add');
497
523
  });
524
+
525
+ checklistItemCmd
526
+ .command('delete <checklistId>')
527
+ .description(t('commands.checklists.item.delete.description'))
528
+ .requiredOption('--item <itemId>', t('commands.checklists.item.delete.itemOption'))
529
+ .option('--force', t('commands.checklists.item.delete.forceOption'))
530
+ .action(async (checklistId: string, options: { item: string; force?: boolean }) => {
531
+ await ErrorHandler.withErrorHandling(async () => {
532
+ await this.initializeTrelloControllers();
533
+ await this.checklistController.deleteChecklistItem(checklistId, options.item, options.force ?? false);
534
+ }, 'checklists-item-delete');
535
+ });
536
+
537
+ checklistItemCmd
538
+ .command('rename <cardId>')
539
+ .description(t('commands.checklists.item.rename.description'))
540
+ .requiredOption('--item <itemId>', t('commands.checklists.item.rename.itemOption'))
541
+ .requiredOption('-n, --name <name>', t('commands.checklists.item.rename.nameOption'))
542
+ .option('-f, --format <format>', t('commands.formatOption'), 'table')
543
+ .action(async (cardId: string, options: { item: string; name: string; format?: string }) => {
544
+ await ErrorHandler.withErrorHandling(async () => {
545
+ await this.initializeTrelloControllers();
546
+ if (options.format) {
547
+ this.outputFormatter.setFormat(options.format as import('@/shared').OutputFormat);
548
+ }
549
+ await this.checklistController.renameChecklistItem(cardId, options.item, options.name);
550
+ }, 'checklists-item-rename');
551
+ });
552
+
553
+ checklistItemCmd
554
+ .command('check <cardId>')
555
+ .description(t('commands.checklists.item.check.description'))
556
+ .requiredOption('--item <itemId>', t('commands.checklists.item.check.itemOption'))
557
+ .option('-f, --format <format>', t('commands.formatOption'), 'table')
558
+ .action(async (cardId: string, options: { item: string; format?: string }) => {
559
+ await ErrorHandler.withErrorHandling(async () => {
560
+ await this.initializeTrelloControllers();
561
+ if (options.format) {
562
+ this.outputFormatter.setFormat(options.format as import('@/shared').OutputFormat);
563
+ }
564
+ await this.checklistController.checkItem(cardId, options.item);
565
+ }, 'checklists-item-check');
566
+ });
567
+
568
+ checklistItemCmd
569
+ .command('uncheck <cardId>')
570
+ .description(t('commands.checklists.item.uncheck.description'))
571
+ .requiredOption('--item <itemId>', t('commands.checklists.item.uncheck.itemOption'))
572
+ .option('-f, --format <format>', t('commands.formatOption'), 'table')
573
+ .action(async (cardId: string, options: { item: string; format?: string }) => {
574
+ await ErrorHandler.withErrorHandling(async () => {
575
+ await this.initializeTrelloControllers();
576
+ if (options.format) {
577
+ this.outputFormatter.setFormat(options.format as import('@/shared').OutputFormat);
578
+ }
579
+ await this.checklistController.uncheckItem(cardId, options.item);
580
+ }, 'checklists-item-uncheck');
581
+ });
498
582
  }
499
583
 
500
584
  async run(): Promise<void> {