@qodalis/cli-todo 0.0.1
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 +34 -0
- package/esm2022/lib/cli-todo.module.mjs +19 -0
- package/esm2022/lib/processors/cli-todo-command-processor.mjs +160 -0
- package/esm2022/lib/version.mjs +3 -0
- package/esm2022/public-api.mjs +6 -0
- package/esm2022/qodalis-cli-todo.mjs +5 -0
- package/fesm2022/qodalis-cli-todo.mjs +189 -0
- package/fesm2022/qodalis-cli-todo.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/cli-todo.module.d.ts +6 -0
- package/lib/processors/cli-todo-command-processor.d.ts +22 -0
- package/lib/version.d.ts +1 -0
- package/package.json +44 -0
- package/public-api.d.ts +2 -0
- package/umd/index.js +199 -0
package/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Cli extension
|
|
2
|
+
|
|
3
|
+
The `@qodalis/cli-todo` package is a powerful CLI extension designed to help you manage your tasks efficiently. With a simple and intuitive command structure, you can add, list, complete, and remove TODO items directly from your command line.
|
|
4
|
+
|
|
5
|
+
# Features
|
|
6
|
+
|
|
7
|
+
Add tasks with a single command.
|
|
8
|
+
View all your TODO items in a clear, organized list.
|
|
9
|
+
Mark tasks as complete to keep track of your progress.
|
|
10
|
+
Remove tasks when they are no longer needed.
|
|
11
|
+
Persistent storage for your tasks across CLI sessions.
|
|
12
|
+
|
|
13
|
+
# Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
packages add @qodalis/cli-todo
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
This command downloads and registers the extension for use within the CLI environment.
|
|
20
|
+
|
|
21
|
+
# Usage
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
todo ls
|
|
25
|
+
todo add <task description>
|
|
26
|
+
todo add Buy groceries
|
|
27
|
+
todo add Finish the project report
|
|
28
|
+
todo complete <task ID>
|
|
29
|
+
todo complete 1
|
|
30
|
+
todo rm <task ID>
|
|
31
|
+
|
|
32
|
+
todo ls
|
|
33
|
+
[ ] #2 - Finish the project report
|
|
34
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { resolveCommandProcessorProvider } from '@qodalis/angular-cli';
|
|
3
|
+
import { CliTodoCommandProcessor } from './processors/cli-todo-command-processor';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export class CliTodoModule {
|
|
6
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliTodoModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
7
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: CliTodoModule }); }
|
|
8
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliTodoModule, providers: [resolveCommandProcessorProvider(CliTodoCommandProcessor)] }); }
|
|
9
|
+
}
|
|
10
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliTodoModule, decorators: [{
|
|
11
|
+
type: NgModule,
|
|
12
|
+
args: [{
|
|
13
|
+
declarations: [],
|
|
14
|
+
imports: [],
|
|
15
|
+
exports: [],
|
|
16
|
+
providers: [resolveCommandProcessorProvider(CliTodoCommandProcessor)],
|
|
17
|
+
}]
|
|
18
|
+
}] });
|
|
19
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLXRvZG8ubW9kdWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvdG9kby9zcmMvbGliL2NsaS10b2RvLm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3ZFLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHlDQUF5QyxDQUFDOztBQVFsRixNQUFNLE9BQU8sYUFBYTsrR0FBYixhQUFhO2dIQUFiLGFBQWE7Z0hBQWIsYUFBYSxhQUZYLENBQUMsK0JBQStCLENBQUMsdUJBQXVCLENBQUMsQ0FBQzs7NEZBRTVELGFBQWE7a0JBTnpCLFFBQVE7bUJBQUM7b0JBQ04sWUFBWSxFQUFFLEVBQUU7b0JBQ2hCLE9BQU8sRUFBRSxFQUFFO29CQUNYLE9BQU8sRUFBRSxFQUFFO29CQUNYLFNBQVMsRUFBRSxDQUFDLCtCQUErQixDQUFDLHVCQUF1QixDQUFDLENBQUM7aUJBQ3hFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHJlc29sdmVDb21tYW5kUHJvY2Vzc29yUHJvdmlkZXIgfSBmcm9tICdAcW9kYWxpcy9hbmd1bGFyLWNsaSc7XG5pbXBvcnQgeyBDbGlUb2RvQ29tbWFuZFByb2Nlc3NvciB9IGZyb20gJy4vcHJvY2Vzc29ycy9jbGktdG9kby1jb21tYW5kLXByb2Nlc3Nvcic7XG5cbkBOZ01vZHVsZSh7XG4gICAgZGVjbGFyYXRpb25zOiBbXSxcbiAgICBpbXBvcnRzOiBbXSxcbiAgICBleHBvcnRzOiBbXSxcbiAgICBwcm92aWRlcnM6IFtyZXNvbHZlQ29tbWFuZFByb2Nlc3NvclByb3ZpZGVyKENsaVRvZG9Db21tYW5kUHJvY2Vzc29yKV0sXG59KVxuZXhwb3J0IGNsYXNzIENsaVRvZG9Nb2R1bGUge31cbiJdfQ==
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { CliForegroundColor, CliIcon, DefaultLibraryAuthor, } from '@qodalis/cli-core';
|
|
3
|
+
import { LIBRARY_VERSION } from '../version';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export class CliTodoCommandProcessor {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.command = 'todo';
|
|
8
|
+
this.description = 'A command-line tool for managing your tasks efficiently. Add, list, complete, and remove TODO items with simple commands.';
|
|
9
|
+
this.author = DefaultLibraryAuthor;
|
|
10
|
+
this.version = LIBRARY_VERSION;
|
|
11
|
+
this.processors = [];
|
|
12
|
+
this.todos = [];
|
|
13
|
+
this.nextId = 1;
|
|
14
|
+
this.storageKey = 'todo-items';
|
|
15
|
+
this.registerSubProcessors();
|
|
16
|
+
}
|
|
17
|
+
async processCommand(command, context) {
|
|
18
|
+
context.executor.showHelp(command, context);
|
|
19
|
+
}
|
|
20
|
+
writeDescription(context) {
|
|
21
|
+
context.writer.writeln(this.description);
|
|
22
|
+
context.writer.writeln('');
|
|
23
|
+
context.writer.writeln('Usage:');
|
|
24
|
+
context.writer.writeln(' todo <command> [options]');
|
|
25
|
+
context.writer.writeln('');
|
|
26
|
+
context.writer.writeln('Commands:');
|
|
27
|
+
context.writer.writeln(' ls List all TODO items');
|
|
28
|
+
context.writer.writeln(' add <text> Add a new TODO item with the given text');
|
|
29
|
+
context.writer.writeln(' rm <id> Remove a TODO item by its ID');
|
|
30
|
+
context.writer.writeln(' complete <id> Mark a TODO item as completed by its ID');
|
|
31
|
+
context.writer.writeln('');
|
|
32
|
+
context.writer.writeln('Examples:');
|
|
33
|
+
context.writer.writeln(' todo add Buy milk');
|
|
34
|
+
context.writer.writeln(' todo ls');
|
|
35
|
+
context.writer.writeln(' todo complete 1');
|
|
36
|
+
context.writer.writeln(' todo rm 2');
|
|
37
|
+
context.writer.writeln('');
|
|
38
|
+
}
|
|
39
|
+
async initialize(context) {
|
|
40
|
+
this.todos = this.loadFromStorage();
|
|
41
|
+
this.nextId =
|
|
42
|
+
this.todos.length > 0
|
|
43
|
+
? Math.max(...this.todos.map((t) => t.id)) + 1
|
|
44
|
+
: 1;
|
|
45
|
+
}
|
|
46
|
+
lineThroughText(text) {
|
|
47
|
+
return text
|
|
48
|
+
.split('')
|
|
49
|
+
.map((char) => char + '\u0336')
|
|
50
|
+
.join('');
|
|
51
|
+
}
|
|
52
|
+
registerSubProcessors() {
|
|
53
|
+
this.processors = [
|
|
54
|
+
{
|
|
55
|
+
command: 'ls',
|
|
56
|
+
description: 'List all TODO items',
|
|
57
|
+
processCommand: async (_, context) => {
|
|
58
|
+
if (this.todos.length === 0) {
|
|
59
|
+
context.writer.writeWarning('No TODO items found.');
|
|
60
|
+
context.writer.writeln('Use "todo add <text>" to add a new TODO item.');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
this.todos.forEach((todo) => {
|
|
64
|
+
context.writer.writeln(`[${todo.completed ? context.writer.wrapInColor(CliIcon.CheckIcon, CliForegroundColor.Green) : ' '}] #${todo.id} - ${todo.completed ? this.lineThroughText(todo.text) : todo.text}`);
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
command: 'add',
|
|
70
|
+
description: 'Add a new TODO item',
|
|
71
|
+
allowUnlistedCommands: true,
|
|
72
|
+
valueRequired: true,
|
|
73
|
+
processCommand: async (command, context) => {
|
|
74
|
+
const text = command.value;
|
|
75
|
+
if (!text) {
|
|
76
|
+
context.writer.writeError('Please provide a TODO description.');
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
this.todos.push({
|
|
80
|
+
id: this.nextId++,
|
|
81
|
+
text,
|
|
82
|
+
completed: false,
|
|
83
|
+
});
|
|
84
|
+
this.saveToStorage();
|
|
85
|
+
context.writer.writeSuccess(`Added TODO: "${text}"`);
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
command: 'rm',
|
|
90
|
+
description: 'Remove a TODO item by ID',
|
|
91
|
+
allowUnlistedCommands: true,
|
|
92
|
+
parameters: [
|
|
93
|
+
{
|
|
94
|
+
name: 'all',
|
|
95
|
+
description: 'Remove all TODO items',
|
|
96
|
+
type: 'boolean',
|
|
97
|
+
defaultValue: false,
|
|
98
|
+
aliases: ['a'],
|
|
99
|
+
required: false,
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
processCommand: async (command, context) => {
|
|
103
|
+
if (command.args['all'] || command.args['a']) {
|
|
104
|
+
this.todos = [];
|
|
105
|
+
this.saveToStorage();
|
|
106
|
+
context.writer.writeSuccess('Removed all TODO items.');
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const id = parseInt(command.value, 10);
|
|
110
|
+
if (isNaN(id)) {
|
|
111
|
+
context.writer.writeError('Please provide a valid TODO ID.');
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const index = this.todos.findIndex((todo) => todo.id === id);
|
|
115
|
+
if (index === -1) {
|
|
116
|
+
context.writer.writeInfo(`TODO item with ID ${id} not found.`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
this.todos.splice(index, 1);
|
|
120
|
+
this.saveToStorage();
|
|
121
|
+
context.writer.writeSuccess(`Removed TODO item with ID ${id}.`);
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
command: 'complete',
|
|
126
|
+
description: 'Mark a TODO item as completed by ID',
|
|
127
|
+
allowUnlistedCommands: true,
|
|
128
|
+
valueRequired: true,
|
|
129
|
+
processCommand: async (command, context) => {
|
|
130
|
+
const id = parseInt(command.value || '', 10);
|
|
131
|
+
if (isNaN(id)) {
|
|
132
|
+
context.writer.writeln('Please provide a valid TODO ID.');
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const todo = this.todos.find((todo) => todo.id === id);
|
|
136
|
+
if (!todo) {
|
|
137
|
+
context.writer.writeError(`TODO item with ID ${id} not found.`);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
todo.completed = true;
|
|
141
|
+
this.saveToStorage();
|
|
142
|
+
context.writer.writeSuccess(`Marked TODO item with ID ${id} as completed.`);
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
];
|
|
146
|
+
}
|
|
147
|
+
loadFromStorage() {
|
|
148
|
+
const data = localStorage.getItem(this.storageKey);
|
|
149
|
+
return data ? JSON.parse(data) : [];
|
|
150
|
+
}
|
|
151
|
+
saveToStorage() {
|
|
152
|
+
localStorage.setItem(this.storageKey, JSON.stringify(this.todos));
|
|
153
|
+
}
|
|
154
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliTodoCommandProcessor, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
155
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliTodoCommandProcessor }); }
|
|
156
|
+
}
|
|
157
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliTodoCommandProcessor, decorators: [{
|
|
158
|
+
type: Injectable
|
|
159
|
+
}], ctorParameters: function () { return []; } });
|
|
160
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLXRvZG8tY29tbWFuZC1wcm9jZXNzb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90b2RvL3NyYy9saWIvcHJvY2Vzc29ycy9jbGktdG9kby1jb21tYW5kLXByb2Nlc3Nvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFDSCxrQkFBa0IsRUFDbEIsT0FBTyxFQUVQLG9CQUFvQixHQUd2QixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxZQUFZLENBQUM7O0FBRzdDLE1BQU0sT0FBTyx1QkFBdUI7SUFrQmhDO1FBakJBLFlBQU8sR0FBRyxNQUFNLENBQUM7UUFFakIsZ0JBQVcsR0FDUCwySEFBMkgsQ0FBQztRQUVoSSxXQUFNLEdBQUcsb0JBQW9CLENBQUM7UUFFOUIsWUFBTyxHQUFHLGVBQWUsQ0FBQztRQUUxQixlQUFVLEdBQXdDLEVBQUUsQ0FBQztRQUU3QyxVQUFLLEdBQXVELEVBQUUsQ0FBQztRQUUvRCxXQUFNLEdBQUcsQ0FBQyxDQUFDO1FBRVgsZUFBVSxHQUFHLFlBQVksQ0FBQztRQUc5QixJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBRUQsS0FBSyxDQUFDLGNBQWMsQ0FDaEIsT0FBMEIsRUFDMUIsT0FBNkI7UUFFN0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxPQUE2QjtRQUMxQyxPQUFPLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBWSxDQUFDLENBQUM7UUFDMUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDM0IsT0FBTyxDQUFDLE1BQU0sQ0FBQyxP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WUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDdEUsQ0FBQzsrR0F4TVEsdUJBQXVCO21IQUF2Qix1QkFBdUI7OzRGQUF2Qix1QkFBdUI7a0JBRG5DLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICAgIENsaUZvcmVncm91bmRDb2xvcixcbiAgICBDbGlJY29uLFxuICAgIENsaVByb2Nlc3NDb21tYW5kLFxuICAgIERlZmF1bHRMaWJyYXJ5QXV0aG9yLFxuICAgIElDbGlDb21tYW5kUHJvY2Vzc29yLFxuICAgIElDbGlFeGVjdXRpb25Db250ZXh0LFxufSBmcm9tICdAcW9kYWxpcy9jbGktY29yZSc7XG5pbXBvcnQgeyBMSUJSQVJZX1ZFUlNJT04gfSBmcm9tICcuLi92ZXJzaW9uJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIENsaVRvZG9Db21tYW5kUHJvY2Vzc29yIGltcGxlbWVudHMgSUNsaUNvbW1hbmRQcm9jZXNzb3Ige1xuICAgIGNvbW1hbmQgPSAndG9kbyc7XG5cbiAgICBkZXNjcmlwdGlvbiA9XG4gICAgICAgICdBIGNvbW1hbmQtbGluZSB0b29sIGZvciBtYW5hZ2luZyB5b3VyIHRhc2tzIGVmZmljaWVudGx5LiBBZGQsIGxpc3QsIGNvbXBsZXRlLCBhbmQgcmVtb3ZlIFRPRE8gaXRlbXMgd2l0aCBzaW1wbGUgY29tbWFuZHMuJztcblxuICAgIGF1dGhvciA9IERlZmF1bHRMaWJyYXJ5QXV0aG9yO1xuXG4gICAgdmVyc2lvbiA9IExJQlJBUllfVkVSU0lPTjtcblxuICAgIHByb2Nlc3NvcnM/OiBJQ2xpQ29tbWFuZFByb2Nlc3NvcltdIHwgdW5kZWZpbmVkID0gW107XG5cbiAgICBwcml2YXRlIHRvZG9zOiB7IGlkOiBudW1iZXI7IHRleHQ6IHN0cmluZzsgY29tcGxldGVkOiBib29sZWFuIH1bXSA9IFtdO1xuXG4gICAgcHJpdmF0ZSBuZXh0SWQgPSAxO1xuXG4gICAgcHJpdmF0ZSBzdG9yYWdlS2V5ID0gJ3RvZG8taXRlbXMnO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJTdWJQcm9jZXNzb3JzKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgcHJvY2Vzc0NvbW1hbmQoXG4gICAgICAgIGNvbW1hbmQ6IENsaVByb2Nlc3NDb21tYW5kLFxuICAgICAgICBjb250ZXh0OiBJQ2xpRXhlY3V0aW9uQ29udGV4dCxcbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29udGV4dC5leGVjdXRvci5zaG93SGVscChjb21tYW5kLCBjb250ZXh0KTtcbiAgICB9XG5cbiAgICB3cml0ZURlc2NyaXB0aW9uKGNvbnRleHQ6IElDbGlFeGVjdXRpb25Db250ZXh0KTogdm9pZCB7XG4gICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlbG4odGhpcy5kZXNjcmlwdGlvbiEpO1xuICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZWxuKCcnKTtcbiAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVsbignVXNhZ2U6Jyk7XG4gICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlbG4oJyAgdG9kbyA8Y29tbWFuZD4gW29wdGlvbnNdJyk7XG4gICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlbG4oJycpO1xuICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZWxuKCdDb21tYW5kczonKTtcbiAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVsbignICBscyAgICAgICAgICAgICAgIExpc3QgYWxsIFRPRE8gaXRlbXMnKTtcbiAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVsbihcbiAgICAgICAgICAgICcgIGFkZCA8dGV4dD4gICAgICAgQWRkIGEgbmV3IFRPRE8gaXRlbSB3aXRoIHRoZSBnaXZlbiB0ZXh0JyxcbiAgICAgICAgKTtcbiAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVsbihcbiAgICAgICAgICAgICcgIHJtIDxpZD4gICAgICAgICAgUmVtb3ZlIGEgVE9ETyBpdGVtIGJ5IGl0cyBJRCcsXG4gICAgICAgICk7XG4gICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlbG4oXG4gICAgICAgICAgICAnICBjb21wbGV0ZSA8aWQ+ICAgIE1hcmsgYSBUT0RPIGl0ZW0gYXMgY29tcGxldGVkIGJ5IGl0cyBJRCcsXG4gICAgICAgICk7XG4gICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlbG4oJycpO1xuICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZWxuKCdFeGFtcGxlczonKTtcbiAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVsbignICB0b2RvIGFkZCBCdXkgbWlsaycpO1xuICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZWxuKCcgIHRvZG8gbHMnKTtcbiAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVsbignICB0b2RvIGNvbXBsZXRlIDEnKTtcbiAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVsbignICB0b2RvIHJtIDInKTtcbiAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVsbignJyk7XG4gICAgfVxuXG4gICAgYXN5bmMgaW5pdGlhbGl6ZShjb250ZXh0OiBJQ2xpRXhlY3V0aW9uQ29udGV4dCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLnRvZG9zID0gdGhpcy5sb2FkRnJvbVN0b3JhZ2UoKTtcbiAgICAgICAgdGhpcy5uZXh0SWQgPVxuICAgICAgICAgICAgdGhpcy50b2Rvcy5sZW5ndGggPiAwXG4gICAgICAgICAgICAgICAgPyBNYXRoLm1heCguLi50aGlzLnRvZG9zLm1hcCgodCkgPT4gdC5pZCkpICsgMVxuICAgICAgICAgICAgICAgIDogMTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGxpbmVUaHJvdWdoVGV4dCh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGV4dFxuICAgICAgICAgICAgLnNwbGl0KCcnKVxuICAgICAgICAgICAgLm1hcCgoY2hhcikgPT4gY2hhciArICdcXHUwMzM2JylcbiAgICAgICAgICAgIC5qb2luKCcnKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlZ2lzdGVyU3ViUHJvY2Vzc29ycygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5wcm9jZXNzb3JzID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNvbW1hbmQ6ICdscycsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdMaXN0IGFsbCBUT0RPIGl0ZW1zJyxcbiAgICAgICAgICAgICAgICBwcm9jZXNzQ29tbWFuZDogYXN5bmMgKF8sIGNvbnRleHQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudG9kb3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZVdhcm5pbmcoJ05vIFRPRE8gaXRlbXMgZm91bmQuJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZWxuKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdVc2UgXCJ0b2RvIGFkZCA8dGV4dD5cIiB0byBhZGQgYSBuZXcgVE9ETyBpdGVtLicsXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudG9kb3MuZm9yRWFjaCgodG9kbykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVsbihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBgWyR7dG9kby5jb21wbGV0ZWQgPyBjb250ZXh0LndyaXRlci53cmFwSW5Db2xvcihDbGlJY29uLkNoZWNrSWNvbiwgQ2xpRm9yZWdyb3VuZENvbG9yLkdyZWVuKSA6ICcgJ31dICMke3RvZG8uaWR9IC0gJHt0b2RvLmNvbXBsZXRlZCA/IHRoaXMubGluZVRocm91Z2hUZXh0KHRvZG8udGV4dCkgOiB0b2RvLnRleHR9YCxcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNvbW1hbmQ6ICdhZGQnLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnQWRkIGEgbmV3IFRPRE8gaXRlbScsXG4gICAgICAgICAgICAgICAgYWxsb3dVbmxpc3RlZENvbW1hbmRzOiB0cnVlLFxuICAgICAgICAgICAgICAgIHZhbHVlUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgcHJvY2Vzc0NvbW1hbmQ6IGFzeW5jIChjb21tYW5kLCBjb250ZXh0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRleHQgPSBjb21tYW5kLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1BsZWFzZSBwcm92aWRlIGEgVE9ETyBkZXNjcmlwdGlvbi4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRvZG9zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IHRoaXMubmV4dElkKyssXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0LFxuICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGVkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zYXZlVG9TdG9yYWdlKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVTdWNjZXNzKGBBZGRlZCBUT0RPOiBcIiR7dGV4dH1cImApO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNvbW1hbmQ6ICdybScsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdSZW1vdmUgYSBUT0RPIGl0ZW0gYnkgSUQnLFxuICAgICAgICAgICAgICAgIGFsbG93VW5saXN0ZWRDb21tYW5kczogdHJ1ZSxcbiAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzOiBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdhbGwnLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdSZW1vdmUgYWxsIFRPRE8gaXRlbXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsaWFzZXM6IFsnYSddLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgcHJvY2Vzc0NvbW1hbmQ6IGFzeW5jIChjb21tYW5kLCBjb250ZXh0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb21tYW5kLmFyZ3NbJ2FsbCddIHx8IGNvbW1hbmQuYXJnc1snYSddKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRvZG9zID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNhdmVUb1N0b3JhZ2UoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlU3VjY2VzcygnUmVtb3ZlZCBhbGwgVE9ETyBpdGVtcy4nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gcGFyc2VJbnQoY29tbWFuZC52YWx1ZSEsIDEwKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzTmFOKGlkKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUGxlYXNlIHByb3ZpZGUgYSB2YWxpZCBUT0RPIElELicsXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy50b2Rvcy5maW5kSW5kZXgoXG4gICAgICAgICAgICAgICAgICAgICAgICAodG9kbykgPT4gdG9kby5pZCA9PT0gaWQsXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlSW5mbyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBgVE9ETyBpdGVtIHdpdGggSUQgJHtpZH0gbm90IGZvdW5kLmAsXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudG9kb3Muc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zYXZlVG9TdG9yYWdlKCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlU3VjY2VzcyhcbiAgICAgICAgICAgICAgICAgICAgICAgIGBSZW1vdmVkIFRPRE8gaXRlbSB3aXRoIElEICR7aWR9LmAsXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY29tbWFuZDogJ2NvbXBsZXRlJyxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ01hcmsgYSBUT0RPIGl0ZW0gYXMgY29tcGxldGVkIGJ5IElEJyxcbiAgICAgICAgICAgICAgICBhbGxvd1VubGlzdGVkQ29tbWFuZHM6IHRydWUsXG4gICAgICAgICAgICAgICAgdmFsdWVSZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBwcm9jZXNzQ29tbWFuZDogYXN5bmMgKGNvbW1hbmQsIGNvbnRleHQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaWQgPSBwYXJzZUludChjb21tYW5kLnZhbHVlIHx8ICcnLCAxMCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc05hTihpZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlbG4oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1BsZWFzZSBwcm92aWRlIGEgdmFsaWQgVE9ETyBJRC4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0b2RvID0gdGhpcy50b2Rvcy5maW5kKCh0b2RvKSA9PiB0b2RvLmlkID09PSBpZCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghdG9kbykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBgVE9ETyBpdGVtIHdpdGggSUQgJHtpZH0gbm90IGZvdW5kLmAsXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRvZG8uY29tcGxldGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zYXZlVG9TdG9yYWdlKCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlU3VjY2VzcyhcbiAgICAgICAgICAgICAgICAgICAgICAgIGBNYXJrZWQgVE9ETyBpdGVtIHdpdGggSUQgJHtpZH0gYXMgY29tcGxldGVkLmAsXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIF07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBsb2FkRnJvbVN0b3JhZ2UoKToge1xuICAgICAgICBpZDogbnVtYmVyO1xuICAgICAgICB0ZXh0OiBzdHJpbmc7XG4gICAgICAgIGNvbXBsZXRlZDogYm9vbGVhbjtcbiAgICB9W10ge1xuICAgICAgICBjb25zdCBkYXRhID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5zdG9yYWdlS2V5KTtcbiAgICAgICAgcmV0dXJuIGRhdGEgPyBKU09OLnBhcnNlKGRhdGEpIDogW107XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzYXZlVG9TdG9yYWdlKCk6IHZvaWQge1xuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSh0aGlzLnN0b3JhZ2VLZXksIEpTT04uc3RyaW5naWZ5KHRoaXMudG9kb3MpKTtcbiAgICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Automatically generated during build
|
|
2
|
+
export const LIBRARY_VERSION = '0.0.1';
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RvZG8vc3JjL2xpYi92ZXJzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNFLHVDQUF1QztBQUN2QyxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiXG4gIC8vIEF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGR1cmluZyBidWlsZFxuICBleHBvcnQgY29uc3QgTElCUkFSWV9WRVJTSU9OID0gJzAuMC4xJztcbiAgIl19
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Public API Surface of string
|
|
3
|
+
*/
|
|
4
|
+
export * from './lib/cli-todo.module';
|
|
5
|
+
export * from './lib/processors/cli-todo-command-processor';
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL3RvZG8vc3JjL3B1YmxpYy1hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLHVCQUF1QixDQUFDO0FBRXRDLGNBQWMsNkNBQTZDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogUHVibGljIEFQSSBTdXJmYWNlIG9mIHN0cmluZ1xuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vbGliL2NsaS10b2RvLm1vZHVsZSc7XG5cbmV4cG9ydCAqIGZyb20gJy4vbGliL3Byb2Nlc3NvcnMvY2xpLXRvZG8tY29tbWFuZC1wcm9jZXNzb3InO1xuIl19
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated bundle index. Do not edit.
|
|
3
|
+
*/
|
|
4
|
+
export * from './public-api';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicW9kYWxpcy1jbGktdG9kby5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL3RvZG8vc3JjL3FvZGFsaXMtY2xpLXRvZG8udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9wdWJsaWMtYXBpJztcbiJdfQ==
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Injectable, NgModule } from '@angular/core';
|
|
3
|
+
import { resolveCommandProcessorProvider } from '@qodalis/angular-cli';
|
|
4
|
+
import { DefaultLibraryAuthor, CliIcon, CliForegroundColor } from '@qodalis/cli-core';
|
|
5
|
+
|
|
6
|
+
// Automatically generated during build
|
|
7
|
+
const LIBRARY_VERSION = '0.0.1';
|
|
8
|
+
|
|
9
|
+
class CliTodoCommandProcessor {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.command = 'todo';
|
|
12
|
+
this.description = 'A command-line tool for managing your tasks efficiently. Add, list, complete, and remove TODO items with simple commands.';
|
|
13
|
+
this.author = DefaultLibraryAuthor;
|
|
14
|
+
this.version = LIBRARY_VERSION;
|
|
15
|
+
this.processors = [];
|
|
16
|
+
this.todos = [];
|
|
17
|
+
this.nextId = 1;
|
|
18
|
+
this.storageKey = 'todo-items';
|
|
19
|
+
this.registerSubProcessors();
|
|
20
|
+
}
|
|
21
|
+
async processCommand(command, context) {
|
|
22
|
+
context.executor.showHelp(command, context);
|
|
23
|
+
}
|
|
24
|
+
writeDescription(context) {
|
|
25
|
+
context.writer.writeln(this.description);
|
|
26
|
+
context.writer.writeln('');
|
|
27
|
+
context.writer.writeln('Usage:');
|
|
28
|
+
context.writer.writeln(' todo <command> [options]');
|
|
29
|
+
context.writer.writeln('');
|
|
30
|
+
context.writer.writeln('Commands:');
|
|
31
|
+
context.writer.writeln(' ls List all TODO items');
|
|
32
|
+
context.writer.writeln(' add <text> Add a new TODO item with the given text');
|
|
33
|
+
context.writer.writeln(' rm <id> Remove a TODO item by its ID');
|
|
34
|
+
context.writer.writeln(' complete <id> Mark a TODO item as completed by its ID');
|
|
35
|
+
context.writer.writeln('');
|
|
36
|
+
context.writer.writeln('Examples:');
|
|
37
|
+
context.writer.writeln(' todo add Buy milk');
|
|
38
|
+
context.writer.writeln(' todo ls');
|
|
39
|
+
context.writer.writeln(' todo complete 1');
|
|
40
|
+
context.writer.writeln(' todo rm 2');
|
|
41
|
+
context.writer.writeln('');
|
|
42
|
+
}
|
|
43
|
+
async initialize(context) {
|
|
44
|
+
this.todos = this.loadFromStorage();
|
|
45
|
+
this.nextId =
|
|
46
|
+
this.todos.length > 0
|
|
47
|
+
? Math.max(...this.todos.map((t) => t.id)) + 1
|
|
48
|
+
: 1;
|
|
49
|
+
}
|
|
50
|
+
lineThroughText(text) {
|
|
51
|
+
return text
|
|
52
|
+
.split('')
|
|
53
|
+
.map((char) => char + '\u0336')
|
|
54
|
+
.join('');
|
|
55
|
+
}
|
|
56
|
+
registerSubProcessors() {
|
|
57
|
+
this.processors = [
|
|
58
|
+
{
|
|
59
|
+
command: 'ls',
|
|
60
|
+
description: 'List all TODO items',
|
|
61
|
+
processCommand: async (_, context) => {
|
|
62
|
+
if (this.todos.length === 0) {
|
|
63
|
+
context.writer.writeWarning('No TODO items found.');
|
|
64
|
+
context.writer.writeln('Use "todo add <text>" to add a new TODO item.');
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
this.todos.forEach((todo) => {
|
|
68
|
+
context.writer.writeln(`[${todo.completed ? context.writer.wrapInColor(CliIcon.CheckIcon, CliForegroundColor.Green) : ' '}] #${todo.id} - ${todo.completed ? this.lineThroughText(todo.text) : todo.text}`);
|
|
69
|
+
});
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
command: 'add',
|
|
74
|
+
description: 'Add a new TODO item',
|
|
75
|
+
allowUnlistedCommands: true,
|
|
76
|
+
valueRequired: true,
|
|
77
|
+
processCommand: async (command, context) => {
|
|
78
|
+
const text = command.value;
|
|
79
|
+
if (!text) {
|
|
80
|
+
context.writer.writeError('Please provide a TODO description.');
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
this.todos.push({
|
|
84
|
+
id: this.nextId++,
|
|
85
|
+
text,
|
|
86
|
+
completed: false,
|
|
87
|
+
});
|
|
88
|
+
this.saveToStorage();
|
|
89
|
+
context.writer.writeSuccess(`Added TODO: "${text}"`);
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
command: 'rm',
|
|
94
|
+
description: 'Remove a TODO item by ID',
|
|
95
|
+
allowUnlistedCommands: true,
|
|
96
|
+
parameters: [
|
|
97
|
+
{
|
|
98
|
+
name: 'all',
|
|
99
|
+
description: 'Remove all TODO items',
|
|
100
|
+
type: 'boolean',
|
|
101
|
+
defaultValue: false,
|
|
102
|
+
aliases: ['a'],
|
|
103
|
+
required: false,
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
processCommand: async (command, context) => {
|
|
107
|
+
if (command.args['all'] || command.args['a']) {
|
|
108
|
+
this.todos = [];
|
|
109
|
+
this.saveToStorage();
|
|
110
|
+
context.writer.writeSuccess('Removed all TODO items.');
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const id = parseInt(command.value, 10);
|
|
114
|
+
if (isNaN(id)) {
|
|
115
|
+
context.writer.writeError('Please provide a valid TODO ID.');
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const index = this.todos.findIndex((todo) => todo.id === id);
|
|
119
|
+
if (index === -1) {
|
|
120
|
+
context.writer.writeInfo(`TODO item with ID ${id} not found.`);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
this.todos.splice(index, 1);
|
|
124
|
+
this.saveToStorage();
|
|
125
|
+
context.writer.writeSuccess(`Removed TODO item with ID ${id}.`);
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
command: 'complete',
|
|
130
|
+
description: 'Mark a TODO item as completed by ID',
|
|
131
|
+
allowUnlistedCommands: true,
|
|
132
|
+
valueRequired: true,
|
|
133
|
+
processCommand: async (command, context) => {
|
|
134
|
+
const id = parseInt(command.value || '', 10);
|
|
135
|
+
if (isNaN(id)) {
|
|
136
|
+
context.writer.writeln('Please provide a valid TODO ID.');
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const todo = this.todos.find((todo) => todo.id === id);
|
|
140
|
+
if (!todo) {
|
|
141
|
+
context.writer.writeError(`TODO item with ID ${id} not found.`);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
todo.completed = true;
|
|
145
|
+
this.saveToStorage();
|
|
146
|
+
context.writer.writeSuccess(`Marked TODO item with ID ${id} as completed.`);
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
];
|
|
150
|
+
}
|
|
151
|
+
loadFromStorage() {
|
|
152
|
+
const data = localStorage.getItem(this.storageKey);
|
|
153
|
+
return data ? JSON.parse(data) : [];
|
|
154
|
+
}
|
|
155
|
+
saveToStorage() {
|
|
156
|
+
localStorage.setItem(this.storageKey, JSON.stringify(this.todos));
|
|
157
|
+
}
|
|
158
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliTodoCommandProcessor, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
159
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliTodoCommandProcessor }); }
|
|
160
|
+
}
|
|
161
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliTodoCommandProcessor, decorators: [{
|
|
162
|
+
type: Injectable
|
|
163
|
+
}], ctorParameters: function () { return []; } });
|
|
164
|
+
|
|
165
|
+
class CliTodoModule {
|
|
166
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliTodoModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
167
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: CliTodoModule }); }
|
|
168
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliTodoModule, providers: [resolveCommandProcessorProvider(CliTodoCommandProcessor)] }); }
|
|
169
|
+
}
|
|
170
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliTodoModule, decorators: [{
|
|
171
|
+
type: NgModule,
|
|
172
|
+
args: [{
|
|
173
|
+
declarations: [],
|
|
174
|
+
imports: [],
|
|
175
|
+
exports: [],
|
|
176
|
+
providers: [resolveCommandProcessorProvider(CliTodoCommandProcessor)],
|
|
177
|
+
}]
|
|
178
|
+
}] });
|
|
179
|
+
|
|
180
|
+
/*
|
|
181
|
+
* Public API Surface of string
|
|
182
|
+
*/
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Generated bundle index. Do not edit.
|
|
186
|
+
*/
|
|
187
|
+
|
|
188
|
+
export { CliTodoCommandProcessor, CliTodoModule };
|
|
189
|
+
//# sourceMappingURL=qodalis-cli-todo.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qodalis-cli-todo.mjs","sources":["../../../projects/todo/src/lib/version.ts","../../../projects/todo/src/lib/processors/cli-todo-command-processor.ts","../../../projects/todo/src/lib/cli-todo.module.ts","../../../projects/todo/src/public-api.ts","../../../projects/todo/src/qodalis-cli-todo.ts"],"sourcesContent":["\n // Automatically generated during build\n export const LIBRARY_VERSION = '0.0.1';\n ","import { Injectable } from '@angular/core';\nimport {\n CliForegroundColor,\n CliIcon,\n CliProcessCommand,\n DefaultLibraryAuthor,\n ICliCommandProcessor,\n ICliExecutionContext,\n} from '@qodalis/cli-core';\nimport { LIBRARY_VERSION } from '../version';\n\n@Injectable()\nexport class CliTodoCommandProcessor implements ICliCommandProcessor {\n command = 'todo';\n\n description =\n 'A command-line tool for managing your tasks efficiently. Add, list, complete, and remove TODO items with simple commands.';\n\n author = DefaultLibraryAuthor;\n\n version = LIBRARY_VERSION;\n\n processors?: ICliCommandProcessor[] | undefined = [];\n\n private todos: { id: number; text: string; completed: boolean }[] = [];\n\n private nextId = 1;\n\n private storageKey = 'todo-items';\n\n constructor() {\n this.registerSubProcessors();\n }\n\n async processCommand(\n command: CliProcessCommand,\n context: ICliExecutionContext,\n ): Promise<void> {\n context.executor.showHelp(command, context);\n }\n\n writeDescription(context: ICliExecutionContext): void {\n context.writer.writeln(this.description!);\n context.writer.writeln('');\n context.writer.writeln('Usage:');\n context.writer.writeln(' todo <command> [options]');\n context.writer.writeln('');\n context.writer.writeln('Commands:');\n context.writer.writeln(' ls List all TODO items');\n context.writer.writeln(\n ' add <text> Add a new TODO item with the given text',\n );\n context.writer.writeln(\n ' rm <id> Remove a TODO item by its ID',\n );\n context.writer.writeln(\n ' complete <id> Mark a TODO item as completed by its ID',\n );\n context.writer.writeln('');\n context.writer.writeln('Examples:');\n context.writer.writeln(' todo add Buy milk');\n context.writer.writeln(' todo ls');\n context.writer.writeln(' todo complete 1');\n context.writer.writeln(' todo rm 2');\n context.writer.writeln('');\n }\n\n async initialize(context: ICliExecutionContext): Promise<void> {\n this.todos = this.loadFromStorage();\n this.nextId =\n this.todos.length > 0\n ? Math.max(...this.todos.map((t) => t.id)) + 1\n : 1;\n }\n\n private lineThroughText(text: string): string {\n return text\n .split('')\n .map((char) => char + '\\u0336')\n .join('');\n }\n\n private registerSubProcessors(): void {\n this.processors = [\n {\n command: 'ls',\n description: 'List all TODO items',\n processCommand: async (_, context) => {\n if (this.todos.length === 0) {\n context.writer.writeWarning('No TODO items found.');\n context.writer.writeln(\n 'Use \"todo add <text>\" to add a new TODO item.',\n );\n return;\n }\n this.todos.forEach((todo) => {\n context.writer.writeln(\n `[${todo.completed ? context.writer.wrapInColor(CliIcon.CheckIcon, CliForegroundColor.Green) : ' '}] #${todo.id} - ${todo.completed ? this.lineThroughText(todo.text) : todo.text}`,\n );\n });\n },\n },\n {\n command: 'add',\n description: 'Add a new TODO item',\n allowUnlistedCommands: true,\n valueRequired: true,\n processCommand: async (command, context) => {\n const text = command.value;\n if (!text) {\n context.writer.writeError(\n 'Please provide a TODO description.',\n );\n return;\n }\n this.todos.push({\n id: this.nextId++,\n text,\n completed: false,\n });\n\n this.saveToStorage();\n\n context.writer.writeSuccess(`Added TODO: \"${text}\"`);\n },\n },\n {\n command: 'rm',\n description: 'Remove a TODO item by ID',\n allowUnlistedCommands: true,\n parameters: [\n {\n name: 'all',\n description: 'Remove all TODO items',\n type: 'boolean',\n defaultValue: false,\n aliases: ['a'],\n required: false,\n },\n ],\n processCommand: async (command, context) => {\n if (command.args['all'] || command.args['a']) {\n this.todos = [];\n this.saveToStorage();\n context.writer.writeSuccess('Removed all TODO items.');\n return;\n }\n\n const id = parseInt(command.value!, 10);\n if (isNaN(id)) {\n context.writer.writeError(\n 'Please provide a valid TODO ID.',\n );\n return;\n }\n const index = this.todos.findIndex(\n (todo) => todo.id === id,\n );\n if (index === -1) {\n context.writer.writeInfo(\n `TODO item with ID ${id} not found.`,\n );\n return;\n }\n this.todos.splice(index, 1);\n this.saveToStorage();\n context.writer.writeSuccess(\n `Removed TODO item with ID ${id}.`,\n );\n },\n },\n {\n command: 'complete',\n description: 'Mark a TODO item as completed by ID',\n allowUnlistedCommands: true,\n valueRequired: true,\n processCommand: async (command, context) => {\n const id = parseInt(command.value || '', 10);\n if (isNaN(id)) {\n context.writer.writeln(\n 'Please provide a valid TODO ID.',\n );\n return;\n }\n const todo = this.todos.find((todo) => todo.id === id);\n if (!todo) {\n context.writer.writeError(\n `TODO item with ID ${id} not found.`,\n );\n return;\n }\n todo.completed = true;\n this.saveToStorage();\n context.writer.writeSuccess(\n `Marked TODO item with ID ${id} as completed.`,\n );\n },\n },\n ];\n }\n\n private loadFromStorage(): {\n id: number;\n text: string;\n completed: boolean;\n }[] {\n const data = localStorage.getItem(this.storageKey);\n return data ? JSON.parse(data) : [];\n }\n\n private saveToStorage(): void {\n localStorage.setItem(this.storageKey, JSON.stringify(this.todos));\n }\n}\n","import { NgModule } from '@angular/core';\nimport { resolveCommandProcessorProvider } from '@qodalis/angular-cli';\nimport { CliTodoCommandProcessor } from './processors/cli-todo-command-processor';\n\n@NgModule({\n declarations: [],\n imports: [],\n exports: [],\n providers: [resolveCommandProcessorProvider(CliTodoCommandProcessor)],\n})\nexport class CliTodoModule {}\n","/*\n * Public API Surface of string\n */\n\nexport * from './lib/cli-todo.module';\n\nexport * from './lib/processors/cli-todo-command-processor';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
export declare class CliTodoModule {
|
|
3
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<CliTodoModule, never>;
|
|
4
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<CliTodoModule, never, never, never>;
|
|
5
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<CliTodoModule>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CliProcessCommand, ICliCommandProcessor, ICliExecutionContext } from '@qodalis/cli-core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export declare class CliTodoCommandProcessor implements ICliCommandProcessor {
|
|
4
|
+
command: string;
|
|
5
|
+
description: string;
|
|
6
|
+
author: import("@qodalis/cli-core").ICliCommandAuthor;
|
|
7
|
+
version: string;
|
|
8
|
+
processors?: ICliCommandProcessor[] | undefined;
|
|
9
|
+
private todos;
|
|
10
|
+
private nextId;
|
|
11
|
+
private storageKey;
|
|
12
|
+
constructor();
|
|
13
|
+
processCommand(command: CliProcessCommand, context: ICliExecutionContext): Promise<void>;
|
|
14
|
+
writeDescription(context: ICliExecutionContext): void;
|
|
15
|
+
initialize(context: ICliExecutionContext): Promise<void>;
|
|
16
|
+
private lineThroughText;
|
|
17
|
+
private registerSubProcessors;
|
|
18
|
+
private loadFromStorage;
|
|
19
|
+
private saveToStorage;
|
|
20
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<CliTodoCommandProcessor, never>;
|
|
21
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<CliTodoCommandProcessor>;
|
|
22
|
+
}
|
package/lib/version.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const LIBRARY_VERSION = "0.0.1";
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@qodalis/cli-todo",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "A command-line tool for managing your tasks efficiently. Add, list, complete, and remove TODO items with simple commands.",
|
|
5
|
+
"author": "Nicolae Lupei, Qodalis Solutions",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/qodalis-solutions/angular-web-cli"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://qodalis.com",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"angular",
|
|
14
|
+
"cli",
|
|
15
|
+
"qodalis",
|
|
16
|
+
"terminal",
|
|
17
|
+
"todo"
|
|
18
|
+
],
|
|
19
|
+
"umd": "./umd/index.js",
|
|
20
|
+
"unpkg": "./umd/index.js",
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"@angular/common": "^16.2.0",
|
|
23
|
+
"@angular/core": "^16.2.0"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"tslib": "^2.3.0",
|
|
27
|
+
"@qodalis/cli-core": "^0.0.7",
|
|
28
|
+
"@qodalis/angular-cli": "^1.0.22"
|
|
29
|
+
},
|
|
30
|
+
"sideEffects": false,
|
|
31
|
+
"module": "fesm2022/qodalis-cli-todo.mjs",
|
|
32
|
+
"typings": "index.d.ts",
|
|
33
|
+
"exports": {
|
|
34
|
+
"./package.json": {
|
|
35
|
+
"default": "./package.json"
|
|
36
|
+
},
|
|
37
|
+
".": {
|
|
38
|
+
"types": "./index.d.ts",
|
|
39
|
+
"esm2022": "./esm2022/qodalis-cli-todo.mjs",
|
|
40
|
+
"esm": "./esm2022/qodalis-cli-todo.mjs",
|
|
41
|
+
"default": "./fesm2022/qodalis-cli-todo.mjs"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
package/public-api.d.ts
ADDED
package/umd/index.js
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
(function (global, factory) {
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('@qodalis/cli-core'), require('@angular/core')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['@qodalis/cli-core', '@angular/core'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.cliCore, global.ngCore));
|
|
5
|
+
})(this, (function (cliCore, core) { 'use strict';
|
|
6
|
+
|
|
7
|
+
/******************************************************************************
|
|
8
|
+
Copyright (c) Microsoft Corporation.
|
|
9
|
+
|
|
10
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
11
|
+
purpose with or without fee is hereby granted.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
14
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
15
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
16
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
17
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
18
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
19
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
20
|
+
***************************************************************************** */
|
|
21
|
+
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
function __decorate(decorators, target, key, desc) {
|
|
25
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
26
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
27
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
28
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
32
|
+
var e = new Error(message);
|
|
33
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// Automatically generated during build
|
|
37
|
+
const LIBRARY_VERSION = '0.0.1';
|
|
38
|
+
|
|
39
|
+
let CliTodoCommandProcessor = class CliTodoCommandProcessor {
|
|
40
|
+
constructor() {
|
|
41
|
+
this.command = 'todo';
|
|
42
|
+
this.description = 'A command-line tool for managing your tasks efficiently. Add, list, complete, and remove TODO items with simple commands.';
|
|
43
|
+
this.author = cliCore.DefaultLibraryAuthor;
|
|
44
|
+
this.version = LIBRARY_VERSION;
|
|
45
|
+
this.processors = [];
|
|
46
|
+
this.todos = [];
|
|
47
|
+
this.nextId = 1;
|
|
48
|
+
this.storageKey = 'todo-items';
|
|
49
|
+
this.registerSubProcessors();
|
|
50
|
+
}
|
|
51
|
+
async processCommand(command, context) {
|
|
52
|
+
context.executor.showHelp(command, context);
|
|
53
|
+
}
|
|
54
|
+
writeDescription(context) {
|
|
55
|
+
context.writer.writeln(this.description);
|
|
56
|
+
context.writer.writeln('');
|
|
57
|
+
context.writer.writeln('Usage:');
|
|
58
|
+
context.writer.writeln(' todo <command> [options]');
|
|
59
|
+
context.writer.writeln('');
|
|
60
|
+
context.writer.writeln('Commands:');
|
|
61
|
+
context.writer.writeln(' ls List all TODO items');
|
|
62
|
+
context.writer.writeln(' add <text> Add a new TODO item with the given text');
|
|
63
|
+
context.writer.writeln(' rm <id> Remove a TODO item by its ID');
|
|
64
|
+
context.writer.writeln(' complete <id> Mark a TODO item as completed by its ID');
|
|
65
|
+
context.writer.writeln('');
|
|
66
|
+
context.writer.writeln('Examples:');
|
|
67
|
+
context.writer.writeln(' todo add Buy milk');
|
|
68
|
+
context.writer.writeln(' todo ls');
|
|
69
|
+
context.writer.writeln(' todo complete 1');
|
|
70
|
+
context.writer.writeln(' todo rm 2');
|
|
71
|
+
context.writer.writeln('');
|
|
72
|
+
}
|
|
73
|
+
async initialize(context) {
|
|
74
|
+
this.todos = this.loadFromStorage();
|
|
75
|
+
this.nextId =
|
|
76
|
+
this.todos.length > 0
|
|
77
|
+
? Math.max(...this.todos.map((t) => t.id)) + 1
|
|
78
|
+
: 1;
|
|
79
|
+
}
|
|
80
|
+
lineThroughText(text) {
|
|
81
|
+
return text
|
|
82
|
+
.split('')
|
|
83
|
+
.map((char) => char + '\u0336')
|
|
84
|
+
.join('');
|
|
85
|
+
}
|
|
86
|
+
registerSubProcessors() {
|
|
87
|
+
this.processors = [
|
|
88
|
+
{
|
|
89
|
+
command: 'ls',
|
|
90
|
+
description: 'List all TODO items',
|
|
91
|
+
processCommand: async (_, context) => {
|
|
92
|
+
if (this.todos.length === 0) {
|
|
93
|
+
context.writer.writeWarning('No TODO items found.');
|
|
94
|
+
context.writer.writeln('Use "todo add <text>" to add a new TODO item.');
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
this.todos.forEach((todo) => {
|
|
98
|
+
context.writer.writeln(`[${todo.completed ? context.writer.wrapInColor(cliCore.CliIcon.CheckIcon, cliCore.CliForegroundColor.Green) : ' '}] #${todo.id} - ${todo.completed ? this.lineThroughText(todo.text) : todo.text}`);
|
|
99
|
+
});
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
command: 'add',
|
|
104
|
+
description: 'Add a new TODO item',
|
|
105
|
+
allowUnlistedCommands: true,
|
|
106
|
+
valueRequired: true,
|
|
107
|
+
processCommand: async (command, context) => {
|
|
108
|
+
const text = command.value;
|
|
109
|
+
if (!text) {
|
|
110
|
+
context.writer.writeError('Please provide a TODO description.');
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
this.todos.push({
|
|
114
|
+
id: this.nextId++,
|
|
115
|
+
text,
|
|
116
|
+
completed: false,
|
|
117
|
+
});
|
|
118
|
+
this.saveToStorage();
|
|
119
|
+
context.writer.writeSuccess(`Added TODO: "${text}"`);
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
command: 'rm',
|
|
124
|
+
description: 'Remove a TODO item by ID',
|
|
125
|
+
allowUnlistedCommands: true,
|
|
126
|
+
parameters: [
|
|
127
|
+
{
|
|
128
|
+
name: 'all',
|
|
129
|
+
description: 'Remove all TODO items',
|
|
130
|
+
type: 'boolean',
|
|
131
|
+
defaultValue: false,
|
|
132
|
+
aliases: ['a'],
|
|
133
|
+
required: false,
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
processCommand: async (command, context) => {
|
|
137
|
+
if (command.args['all'] || command.args['a']) {
|
|
138
|
+
this.todos = [];
|
|
139
|
+
this.saveToStorage();
|
|
140
|
+
context.writer.writeSuccess('Removed all TODO items.');
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const id = parseInt(command.value, 10);
|
|
144
|
+
if (isNaN(id)) {
|
|
145
|
+
context.writer.writeError('Please provide a valid TODO ID.');
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const index = this.todos.findIndex((todo) => todo.id === id);
|
|
149
|
+
if (index === -1) {
|
|
150
|
+
context.writer.writeInfo(`TODO item with ID ${id} not found.`);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
this.todos.splice(index, 1);
|
|
154
|
+
this.saveToStorage();
|
|
155
|
+
context.writer.writeSuccess(`Removed TODO item with ID ${id}.`);
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
command: 'complete',
|
|
160
|
+
description: 'Mark a TODO item as completed by ID',
|
|
161
|
+
allowUnlistedCommands: true,
|
|
162
|
+
valueRequired: true,
|
|
163
|
+
processCommand: async (command, context) => {
|
|
164
|
+
const id = parseInt(command.value || '', 10);
|
|
165
|
+
if (isNaN(id)) {
|
|
166
|
+
context.writer.writeln('Please provide a valid TODO ID.');
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const todo = this.todos.find((todo) => todo.id === id);
|
|
170
|
+
if (!todo) {
|
|
171
|
+
context.writer.writeError(`TODO item with ID ${id} not found.`);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
todo.completed = true;
|
|
175
|
+
this.saveToStorage();
|
|
176
|
+
context.writer.writeSuccess(`Marked TODO item with ID ${id} as completed.`);
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
];
|
|
180
|
+
}
|
|
181
|
+
loadFromStorage() {
|
|
182
|
+
const data = localStorage.getItem(this.storageKey);
|
|
183
|
+
return data ? JSON.parse(data) : [];
|
|
184
|
+
}
|
|
185
|
+
saveToStorage() {
|
|
186
|
+
localStorage.setItem(this.storageKey, JSON.stringify(this.todos));
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
CliTodoCommandProcessor = __decorate([
|
|
190
|
+
core.Injectable()
|
|
191
|
+
], CliTodoCommandProcessor);
|
|
192
|
+
|
|
193
|
+
const module = {
|
|
194
|
+
name: '@qodalis/cli-todo',
|
|
195
|
+
processors: [new CliTodoCommandProcessor()],
|
|
196
|
+
};
|
|
197
|
+
cliCore.bootUmdModule(module);
|
|
198
|
+
|
|
199
|
+
}));
|