taskninja 1.1.6 → 1.1.7
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 +83 -254
- package/index.js +108 -0
- package/package.json +3 -3
- package/src/commands/addCommand.js +79 -0
- package/src/commands/deleteCommand.js +51 -0
- package/src/commands/doneCommand.js +36 -0
- package/src/commands/listCommand.js +19 -0
- package/src/commands/searchCommand.js +48 -0
- package/src/commands/sortCommand.js +47 -0
- package/src/commands/undoCommand.js +32 -0
- package/src/commands/updateCommand.js +62 -0
- package/src/helpers/helpers.js +1 -18
- package/src/utils/taskService.js +32 -7
- package/src/index.js +0 -523
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# TaskNinja
|
|
2
2
|
|
|
3
|
-
**Version:** 1.1.
|
|
4
|
-
**Description:** A simple CLI To-Do Application to manage your tasks directly from the terminal. Includes colored tables, search, soft delete, undo, and interactive sort.
|
|
3
|
+
**Version:** 1.1.7
|
|
4
|
+
**Description:** A simple CLI To-Do Application to manage your tasks directly from the terminal. Includes colored tables, search, soft delete with auto-expiration, undo, and interactive sort.
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -10,17 +10,18 @@
|
|
|
10
10
|
* [Installation](#installation)
|
|
11
11
|
* [Running the CLI](#running-the-cli)
|
|
12
12
|
* [Commands](#commands)
|
|
13
|
+
* [Add Task](#1-add-task)
|
|
14
|
+
* [List Tasks](#2-list-tasks)
|
|
15
|
+
* [Update Task](#3-update-task)
|
|
16
|
+
* [Mark as Done](#4-mark-as-done)
|
|
17
|
+
* [Delete Task](#5-delete-task)
|
|
18
|
+
* [Undo Delete Task](#6-undo-delete-task)
|
|
19
|
+
* [Search Tasks](#7-search-tasks)
|
|
20
|
+
* [Sort Tasks](#8-sort-tasks)
|
|
21
|
+
|
|
13
22
|
|
|
14
|
-
* [Add Task](#add-task)
|
|
15
|
-
* [List Tasks](#list-tasks)
|
|
16
|
-
* [Update Task](#update-task)
|
|
17
|
-
* [Delete Task](#delete-task)
|
|
18
|
-
* [Undo Delete Task](#undo-delete-task)
|
|
19
|
-
* [Search Tasks](#search-tasks)
|
|
20
|
-
* [Sort Tasks](#sort-tasks)
|
|
21
23
|
* [Task Fields & Allowed Values](#task-fields--allowed-values)
|
|
22
|
-
* [
|
|
23
|
-
* [Demo](#demo)
|
|
24
|
+
* [New Features in Version 1.1.7](#new-features-in-version-117)
|
|
24
25
|
|
|
25
26
|
---
|
|
26
27
|
|
|
@@ -32,21 +33,18 @@ TaskNinja is published on npm as `taskninja`. Install it globally to use the CLI
|
|
|
32
33
|
|
|
33
34
|
```bash
|
|
34
35
|
npm install -g taskninja
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
or use it instantly with:
|
|
38
36
|
|
|
39
|
-
```bash
|
|
40
|
-
npx taskninja
|
|
41
|
-
npx taskninja <command>
|
|
42
37
|
```
|
|
43
38
|
|
|
39
|
+
### From Source
|
|
40
|
+
|
|
44
41
|
Clone the repository and install dependencies:
|
|
45
42
|
|
|
46
43
|
```bash
|
|
47
44
|
git clone <your-repo-url>
|
|
48
45
|
cd taskninja
|
|
49
46
|
npm install
|
|
47
|
+
|
|
50
48
|
```
|
|
51
49
|
|
|
52
50
|
---
|
|
@@ -56,16 +54,15 @@ npm install
|
|
|
56
54
|
You can run the CLI using either `node` or the bin aliases:
|
|
57
55
|
|
|
58
56
|
```bash
|
|
59
|
-
# Using node
|
|
60
|
-
node app.js <command>
|
|
61
|
-
|
|
62
57
|
# Using bin aliases
|
|
63
|
-
dotask <command>
|
|
64
|
-
taskninja <command>
|
|
65
58
|
tn <command>
|
|
66
|
-
|
|
59
|
+
taskninja <command>
|
|
60
|
+
dotask <command>
|
|
61
|
+
|
|
62
|
+
# Using node
|
|
63
|
+
node index.js <command>
|
|
67
64
|
|
|
68
|
-
|
|
65
|
+
```
|
|
69
66
|
|
|
70
67
|
---
|
|
71
68
|
|
|
@@ -78,32 +75,18 @@ Replace `<command>` with any of the available commands: `add`, `list`, `update`,
|
|
|
78
75
|
|
|
79
76
|
```bash
|
|
80
77
|
tn a
|
|
78
|
+
|
|
81
79
|
```
|
|
82
80
|
|
|
83
81
|
**Prompts:**
|
|
84
82
|
|
|
85
83
|
1. **Task Title:** Enter any text (cannot be empty).
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
* todo
|
|
90
|
-
* in-progress
|
|
91
|
-
* done
|
|
92
|
-
|
|
93
|
-
3. **Task Priority:** Select from allowed values:
|
|
94
|
-
|
|
95
|
-
* low
|
|
96
|
-
* medium
|
|
97
|
-
* high
|
|
98
|
-
|
|
99
|
-
4. **Due Date:** Enter in `YYYY-MM-DD` format. Invalid dates will show a validation error.
|
|
100
|
-
|
|
84
|
+
2. **Task Status:** Select from (todo, in-progress, done).
|
|
85
|
+
3. **Task Priority:** Select from (low, medium, high).
|
|
86
|
+
4. **Due Date:** Enter in `YYYY-MM-DD` (Defaults to today).
|
|
101
87
|
5. **Description:** Optional text.
|
|
102
88
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
* Task is saved in `todos.json`.
|
|
106
|
-
* Confirmation message: `Task added successfully!`
|
|
89
|
+

|
|
107
90
|
|
|
108
91
|
---
|
|
109
92
|
|
|
@@ -115,17 +98,16 @@ tn a
|
|
|
115
98
|
```bash
|
|
116
99
|
tn ls
|
|
117
100
|
tn ls --status todo
|
|
101
|
+
|
|
118
102
|
```
|
|
119
103
|
|
|
120
104
|
**Behavior:**
|
|
121
105
|
|
|
122
|
-
* Displays tasks in a
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
| - | -- | ----- | ------ | -------- | ------- | ----------- |
|
|
106
|
+
* Displays tasks in a colored table.
|
|
107
|
+
* Status colors: `todo` (blue), `in-progress` (yellow), `done` (green).
|
|
108
|
+
* Priority colors: `low` (green), `medium` (yellow), `high` (red).
|
|
126
109
|
|
|
127
|
-
|
|
128
|
-
* Priority colors: `low` → green, `medium` → yellow, `high` → red
|
|
110
|
+

|
|
129
111
|
|
|
130
112
|
---
|
|
131
113
|
|
|
@@ -136,273 +118,120 @@ tn ls --status todo
|
|
|
136
118
|
|
|
137
119
|
```bash
|
|
138
120
|
tn up
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
**Steps:**
|
|
142
|
-
|
|
143
|
-
1. Select task by ID from a list.
|
|
144
|
-
2. Confirm which fields to change (title, status, priority, due date, description).
|
|
145
|
-
3. Enter new values where applicable.
|
|
146
|
-
|
|
147
|
-
**Behavior:**
|
|
148
|
-
|
|
149
|
-
* Only fields selected for change are updated.
|
|
150
|
-
* Confirmation message: `Task updated successfully!`
|
|
151
|
-
* Shows updated **colored task table**.
|
|
152
|
-
|
|
153
|
-
---
|
|
154
|
-
|
|
155
|
-
### 4. Delete Task
|
|
156
121
|
|
|
157
|
-
**Alias:** `del`
|
|
158
|
-
**Description:** Soft delete a task by selecting its ID.
|
|
159
|
-
|
|
160
|
-
```bash
|
|
161
|
-
tn del
|
|
162
122
|
```
|
|
163
123
|
|
|
164
124
|
**Steps:**
|
|
165
125
|
|
|
166
|
-
1. Select task by ID
|
|
167
|
-
2. Confirm
|
|
126
|
+
1. Select task by ID.
|
|
127
|
+
2. Confirm which fields to change.
|
|
128
|
+
3. Enter new values.
|
|
168
129
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
* Task is removed from `todos.json` **but saved in `deleted-todos.json`**.
|
|
172
|
-
* Confirmation: `Task deleted successfully!`
|
|
173
|
-
* You can restore it using the `undo` command.
|
|
130
|
+

|
|
174
131
|
|
|
175
132
|
---
|
|
176
133
|
|
|
177
|
-
###
|
|
134
|
+
### 4. Mark as Done
|
|
178
135
|
|
|
179
|
-
**Alias:** `
|
|
180
|
-
**Description:**
|
|
136
|
+
**Alias:** `done`
|
|
137
|
+
**Description:** Quickly mark a specific task as done.
|
|
181
138
|
|
|
182
139
|
```bash
|
|
183
|
-
tn
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
**Behavior:**
|
|
140
|
+
tn done
|
|
187
141
|
|
|
188
|
-
|
|
189
|
-
* Confirmation: `Last deleted task restored successfully!, (Task name: taskName)`
|
|
142
|
+
```
|
|
190
143
|
|
|
191
|
-
|
|
144
|
+
[Mark Task As Done](src/images/doneTask.png "Mark as Done In one step")
|
|
192
145
|
|
|
193
|
-
|
|
146
|
+

|
|
194
147
|
|
|
195
148
|
---
|
|
196
149
|
|
|
197
|
-
###
|
|
150
|
+
### 5. Delete Task
|
|
198
151
|
|
|
199
|
-
**Alias:** `
|
|
200
|
-
**Description:**
|
|
152
|
+
**Alias:** `del`
|
|
153
|
+
**Description:** Soft delete a task by selecting its ID.
|
|
201
154
|
|
|
202
155
|
```bash
|
|
203
|
-
|
|
204
|
-
tn search
|
|
156
|
+
tn del
|
|
205
157
|
|
|
206
|
-
# Or search directly using --find
|
|
207
|
-
tn search --find "meeting"
|
|
208
158
|
```
|
|
209
159
|
|
|
210
160
|
**Behavior:**
|
|
211
161
|
|
|
212
|
-
*
|
|
213
|
-
|
|
214
|
-
1. Enter the keyword you want to search for.
|
|
215
|
-
2. Choose where to search: in the title, description, or both.
|
|
216
|
-
|
|
217
|
-
* If you use `--find <keyword>` directly, the CLI will return all tasks containing that keyword in the title or description.
|
|
218
|
-
|
|
219
|
-
**Example:**
|
|
162
|
+
* Task is moved to `deleted-todos.json` and kept for 60 seconds.
|
|
220
163
|
|
|
221
|
-
|
|
222
|
-
tn search
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
```
|
|
226
|
-
Enter the keyword you want to search for: meeting
|
|
227
|
-
Where do you want to search? (Use arrow keys)
|
|
228
|
-
1. title
|
|
229
|
-
2. description
|
|
230
|
-
3. both
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
```bash
|
|
234
|
-
tn search --find "meeting"
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
┌─┬────┬────────────┬─────────────┬─────────┬────────────┬───────────────────┐
|
|
238
|
-
│#│ ID │ Title │ Status │ Priority│ DueDate │ Description │
|
|
239
|
-
├─┼────┼────────────┼─────────────┼─────────┼────────────┼───────────────────┤
|
|
240
|
-
│1│ 3 │ Team meeting│ todo │ medium │ 2026-02-01 │ Discuss project │
|
|
241
|
-
└─┴────┴────────────┴─────────────┴─────────┴────────────┴───────────────────┘
|
|
164
|
+

|
|
242
165
|
|
|
243
166
|
---
|
|
244
167
|
|
|
245
|
-
###
|
|
168
|
+
### 6. Undo Delete Task
|
|
246
169
|
|
|
247
|
-
**Alias:** `
|
|
248
|
-
**Description:**
|
|
170
|
+
**Alias:** `un`
|
|
171
|
+
**Description:** Restore the last deleted task (if within 60 seconds).
|
|
249
172
|
|
|
250
173
|
```bash
|
|
251
|
-
tn
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
**Behavior:**
|
|
255
|
-
|
|
256
|
-
* Prompts: `Sort tasks by:` → select from `dueDate`, `priority`, `status`.
|
|
257
|
-
* Displays **sorted colored table**.
|
|
258
|
-
* Can also pass `--by` option: `tn so --by priority`
|
|
259
|
-
|
|
260
|
-
---
|
|
174
|
+
tn un
|
|
261
175
|
|
|
262
|
-
|
|
176
|
+
```
|
|
263
177
|
|
|
264
|
-
|
|
265
|
-
| ----------- | ---------------------------- |
|
|
266
|
-
| title | Any non-empty string |
|
|
267
|
-
| status | todo, in-progress, done |
|
|
268
|
-
| priority | low, medium, high |
|
|
269
|
-
| dueDate | YYYY-MM-DD |
|
|
270
|
-
| description | Optional text |
|
|
178
|
+

|
|
271
179
|
|
|
272
180
|
---
|
|
273
181
|
|
|
274
|
-
|
|
182
|
+
### 7. Search Tasks
|
|
275
183
|
|
|
276
|
-
**
|
|
277
|
-
|
|
278
|
-
```bash
|
|
279
|
-
tn a
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
```
|
|
283
|
-
Task Title: Buy groceries
|
|
284
|
-
Task Status: → todo
|
|
285
|
-
Task Priority: → medium
|
|
286
|
-
Due Date (YYYY-MM-DD): 2026-02-01
|
|
287
|
-
Task Description (optional): Buy fruits and vegetables
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
**Listing Tasks:**
|
|
184
|
+
**Alias:** `sr`
|
|
185
|
+
**Description:** Search tasks by keyword in title or description.
|
|
291
186
|
|
|
292
187
|
```bash
|
|
293
|
-
tn
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
```
|
|
297
|
-
┌─┬────┬────────────────┬─────────────┬─────────┬────────────┬─────────────────────────────┐
|
|
298
|
-
│#│ ID │ Title │ Status │ Priority│ DueDate │ Description │
|
|
299
|
-
├─┼────┼────────────────┼─────────────┼─────────┼────────────┼─────────────────────────────┤
|
|
300
|
-
│1│ 1 │ Buy groceries │ todo │ medium │ 2026-02-01 │ Buy fruits and vegetables │
|
|
301
|
-
└─┴────┴────────────────┴─────────────┴─────────┴────────────┴─────────────────────────────┘
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
**Updating a Task:**
|
|
188
|
+
tn search --find "keyword"
|
|
305
189
|
|
|
306
|
-
```bash
|
|
307
|
-
tn up
|
|
308
190
|
```
|
|
309
191
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
```bash
|
|
313
|
-
tn del
|
|
314
|
-
```
|
|
192
|
+

|
|
315
193
|
|
|
316
|
-
|
|
194
|
+
---
|
|
317
195
|
|
|
318
|
-
|
|
319
|
-
tn un
|
|
320
|
-
```
|
|
196
|
+
### 8. Sort Tasks
|
|
321
197
|
|
|
322
|
-
**
|
|
198
|
+
**Alias:** `so`
|
|
199
|
+
**Description:** Sort tasks by due date, priority, or status.
|
|
323
200
|
|
|
324
201
|
```bash
|
|
325
|
-
tn
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
**Sort Tasks:**
|
|
202
|
+
tn so --by priority
|
|
329
203
|
|
|
330
|
-
```bash
|
|
331
|
-
tn so
|
|
332
204
|
```
|
|
333
205
|
|
|
334
|
-
* Select `dueDate`, `priority`, or `status` interactively
|
|
335
|
-
* Or use `--by` option: `tn so --by priority`
|
|
336
|
-
|
|
337
|
-
---
|
|
338
|
-
|
|
339
|
-
## Notes
|
|
340
|
-
|
|
341
|
-
* All selection prompts use **arrow keys** in terminal.
|
|
342
|
-
* Task table always shows **numbered index (`#`) starting from 1**.
|
|
343
|
-
* Status and priority are displayed in **colors** for better readability.
|
|
344
|
-
|
|
345
|
-
---
|
|
346
|
-
|
|
347
|
-
---
|
|
348
|
-
|
|
349
|
-
## Demo
|
|
350
|
-
|
|
351
|
-
**All Features:**
|
|
352
|
-
|
|
353
|
-

|
|
354
|
-
|
|
355
|
-
**Adding a Task:**
|
|
356
|
-
|
|
357
|
-

|
|
358
|
-
|
|
359
|
-
**Listing Tasks:**
|
|
360
|
-
|
|
361
|
-

|
|
362
|
-
|
|
363
|
-
**Updating a Task:**
|
|
364
|
-
|
|
365
|
-

|
|
366
|
-
|
|
367
|
-
**Deleting a Task:**
|
|
368
|
-
|
|
369
|
-

|
|
370
|
-
|
|
371
|
-
**Restore Last-Deleted Task:**
|
|
372
|
-
|
|
373
|
-

|
|
374
|
-
|
|
375
|
-
**Search / Sort Tasks:**
|
|
376
|
-
|
|
377
|
-

|
|
378
206
|

|
|
379
|
-

|
|
380
|
-
|
|
381
|
-
**Mark as Done:**
|
|
382
207
|
|
|
383
|
-

|
|
208
|
+

|
|
385
209
|
|
|
386
|
-
|
|
210
|
+
---
|
|
387
211
|
|
|
388
|
-
|
|
212
|
+
## Task Fields & Allowed Values
|
|
389
213
|
|
|
214
|
+
| Field | Allowed Values / Description | Requirement |
|
|
215
|
+
| --- | --- | --- |
|
|
216
|
+
| **Title** | Any non-empty string | Required |
|
|
217
|
+
| **Status** | `todo` | `in-progress` | `done` | Required |
|
|
218
|
+
| **Priority** | `low` | `medium` | `high` | Required |
|
|
219
|
+
| **Due Date** | Date in `YYYY-MM-DD` format | Required |
|
|
220
|
+
| **Description** | Any text providing task details | Optional |
|
|
390
221
|
|
|
391
222
|
---
|
|
392
223
|
|
|
393
|
-
## New
|
|
394
|
-
|
|
395
|
-
**ESC Button End Operation:**
|
|
396
|
-
|
|
397
|
-
* If the user presses the `Esc` button, this will end the ongoing process
|
|
398
|
-
* This may benefit the user by terminating the process without having to complete the process until the end
|
|
399
|
-
* default setter for date
|
|
224
|
+
## New Features in Version 1.1.7
|
|
400
225
|
|
|
401
|
-
###
|
|
402
|
-
**Auto Deleted Task:**
|
|
226
|
+
### Smart Cancellation (Ctrl+C)
|
|
403
227
|
|
|
404
|
-
|
|
405
|
-
* This somewhat conserves the user's storage space while calculating that the user may undo deleting a task
|
|
228
|
+
Operations can now be cancelled using the standard `Ctrl+C` shortcut. This provides a clean exit without overlapping text in the terminal, ensuring a professional user experience.
|
|
406
229
|
|
|
230
|
+
### Auto-Delete & Expiration
|
|
407
231
|
|
|
232
|
+
* **Auto-Cleanup:** The CLI automatically deletes `todos.json` or `deleted-todos.json` if they become empty to save space and keep the directory clean.
|
|
233
|
+
* **Timed Expiration:** Deleted tasks are stored in `deleted-todos.json` for exactly **60 seconds**. After this period, they are automatically purged to manage storage efficiently.
|
|
408
234
|
|
|
235
|
+
### Tasks in todos.json
|
|
236
|
+

|
|
237
|
+
---
|
package/index.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* TASKNINJA -
|
|
5
|
+
* Task Manager CLI Application
|
|
6
|
+
* This application allows users to manage their tasks via command line interface.
|
|
7
|
+
* It supports adding, listing, and removing tasks.
|
|
8
|
+
* Dependencies:
|
|
9
|
+
* - commander: For command line argument parsing
|
|
10
|
+
* - inquirer: For interactive prompts
|
|
11
|
+
* - fs: For file system operations
|
|
12
|
+
* Author: Mohamed Bakr
|
|
13
|
+
* Date: January 2026
|
|
14
|
+
* Version: 1.1.5
|
|
15
|
+
* @license MIT
|
|
16
|
+
* Copyright (c) 2026 Mohamed Bakr
|
|
17
|
+
* @MoBMoCaffeine
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
// for using commands in terminal
|
|
21
|
+
import { Command } from "commander";
|
|
22
|
+
|
|
23
|
+
import { addAction } from "./src/commands/addCommand.js";
|
|
24
|
+
import { listAction } from "./src/commands/listCommand.js";
|
|
25
|
+
import { updateAction } from "./src/commands/updateCommand.js";
|
|
26
|
+
import { doneAction } from "./src/commands/doneCommand.js";
|
|
27
|
+
import { deleteAction } from "./src/commands/deleteCommand.js";
|
|
28
|
+
import { undoAction } from "./src/commands/undoCommand.js";
|
|
29
|
+
import { searchAction } from "./src/commands/searchCommand.js";
|
|
30
|
+
import { sortAction } from "./src/commands/sortCommand.js";
|
|
31
|
+
// assigning Commander to a variable
|
|
32
|
+
const program = new Command();
|
|
33
|
+
|
|
34
|
+
// setting up
|
|
35
|
+
program
|
|
36
|
+
.name("taskninja")
|
|
37
|
+
.description("A simple CLI application to manage your tasks")
|
|
38
|
+
.version("1.1.7");
|
|
39
|
+
|
|
40
|
+
// use command 'add' with title + status + priority + dueDate + description and action
|
|
41
|
+
program
|
|
42
|
+
.command('add')
|
|
43
|
+
.alias('a')
|
|
44
|
+
.description('Add a new task')
|
|
45
|
+
.action(addAction);
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
// use command 'list' with optional status filter and action
|
|
49
|
+
program
|
|
50
|
+
.command('list')
|
|
51
|
+
.alias('ls')
|
|
52
|
+
.description('List all tasks')
|
|
53
|
+
.option('-s, --status <status>', 'Filter tasks by status (todo, in-progress, done)')
|
|
54
|
+
.action( listAction );
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
// use command 'search' to find tasks by keyword in title or description
|
|
59
|
+
program
|
|
60
|
+
.command('search [keyword]')
|
|
61
|
+
.alias('sr')
|
|
62
|
+
.option('-f, --find <keyword>', 'Keyword to search in title or description')
|
|
63
|
+
.description('Search tasks by keyword in title or description')
|
|
64
|
+
.action( searchAction );
|
|
65
|
+
|
|
66
|
+
// use command 'sort' to sort tasks by due date, priority, or status
|
|
67
|
+
program
|
|
68
|
+
.command('sort')
|
|
69
|
+
.alias('so')
|
|
70
|
+
.option('--by <criteria>', 'Sort tasks by criteria (dueDate, priority, status)')
|
|
71
|
+
.description('Sort tasks by due date, priority, or status')
|
|
72
|
+
.action( sortAction );
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
// use command 'update' with task ID and action
|
|
76
|
+
program
|
|
77
|
+
.command('update')
|
|
78
|
+
.alias('up')
|
|
79
|
+
.description('Update a task by ==> ID <==')
|
|
80
|
+
.action( updateAction );
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
// use command 'done' with task ID instead of 'update' + confirm to mark task as done
|
|
84
|
+
program
|
|
85
|
+
.command('done')
|
|
86
|
+
.description('Mark a task as done by ==> ID <==')
|
|
87
|
+
.action( doneAction );
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
// use command 'delete' with task ID and action
|
|
92
|
+
program
|
|
93
|
+
.command('delete')
|
|
94
|
+
.alias('del')
|
|
95
|
+
.description('delete a task by ==> ID <==')
|
|
96
|
+
.action( deleteAction );
|
|
97
|
+
|
|
98
|
+
// use command 'undo' to restore last deleted task
|
|
99
|
+
program
|
|
100
|
+
.command('undo')
|
|
101
|
+
.alias('un')
|
|
102
|
+
.description('Undo the last deleted task')
|
|
103
|
+
.action( undoAction );
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
// parse command line arguments
|
|
108
|
+
program.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "taskninja",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.7",
|
|
4
4
|
"description": "a simple CLI application with JS as a (To-Do Application)",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"dev": "node src/index.js"
|
|
11
11
|
},
|
|
12
12
|
"bin": {
|
|
13
|
-
"dotask": "./
|
|
14
|
-
"taskninja": "./
|
|
13
|
+
"dotask": "./index.js",
|
|
14
|
+
"taskninja": "./index.js",
|
|
15
15
|
"tn": "./src/index.js"
|
|
16
16
|
},
|
|
17
17
|
"repository": {
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import inquirer from "inquirer";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { loadTasks, saveTasks, getNextId } from "../utils/taskService.js";
|
|
4
|
+
import { validateDueDate, ALLOWED_PRIORITIES, ALLOWED_STATUSES } from "../utils/validators.js";
|
|
5
|
+
import { cleanupAndExit } from '../helpers/helpers.js';
|
|
6
|
+
|
|
7
|
+
export const addAction = async () => {
|
|
8
|
+
try {
|
|
9
|
+
const answers = await inquirer.prompt([
|
|
10
|
+
{
|
|
11
|
+
type: 'input',
|
|
12
|
+
name: 'title',
|
|
13
|
+
message: 'Task Title:',
|
|
14
|
+
validate: input => input ? true : 'Title cannot be empty!'
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
type: 'rawlist',
|
|
18
|
+
name: 'status',
|
|
19
|
+
message: 'Task Status:',
|
|
20
|
+
choices: ALLOWED_STATUSES,
|
|
21
|
+
default: 'todo'
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
type: 'rawlist',
|
|
25
|
+
name: 'priority',
|
|
26
|
+
message: 'Task Priority:',
|
|
27
|
+
choices: ALLOWED_PRIORITIES,
|
|
28
|
+
default: 'medium'
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
type: 'input',
|
|
32
|
+
name: 'dueDate',
|
|
33
|
+
message: 'Due Date (YYYY-MM-DD):',
|
|
34
|
+
default: () => {
|
|
35
|
+
const today = new Date();
|
|
36
|
+
return today.toISOString().split('T')[0];
|
|
37
|
+
},
|
|
38
|
+
filter: (input) => {
|
|
39
|
+
const trimmed = input.trim();
|
|
40
|
+
if (!trimmed) {
|
|
41
|
+
return new Date().toISOString().split('T')[0];
|
|
42
|
+
}
|
|
43
|
+
return trimmed;
|
|
44
|
+
},
|
|
45
|
+
validate: input => {
|
|
46
|
+
try {
|
|
47
|
+
validateDueDate(input);
|
|
48
|
+
return true;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
return error.message;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
type: 'input',
|
|
56
|
+
name: 'description',
|
|
57
|
+
message: 'Task Description (optional):'
|
|
58
|
+
},
|
|
59
|
+
]);
|
|
60
|
+
|
|
61
|
+
const tasks = await loadTasks();
|
|
62
|
+
const newTask = {
|
|
63
|
+
id: getNextId(tasks),
|
|
64
|
+
title: answers.title,
|
|
65
|
+
status: answers.status,
|
|
66
|
+
priority: answers.priority,
|
|
67
|
+
dueDate: answers.dueDate,
|
|
68
|
+
description: answers.description || ''
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
tasks.push(newTask);
|
|
72
|
+
await saveTasks(tasks);
|
|
73
|
+
console.log(chalk.green('Task added successfully!'));
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.log(chalk.yellow('\nOperation Cancelled!'));
|
|
76
|
+
} finally {
|
|
77
|
+
cleanupAndExit(0);
|
|
78
|
+
}
|
|
79
|
+
};
|