1
1
/**
2
- * Base Command Class for Event-Driven Architecture
2
+ * @fileoverview Base Command Class for Event-Driven Architecture
3
+ *
4
+ * Provides a common foundation for all CLI commands with event emission,
5
+ * logging, production safety checks, and user interaction capabilities.
6
+ * All commands in the D.A.T.A. system extend from this base class.
7
+ *
8
+ * @module Command
9
+ * @requires EventEmitter
10
+ * @requires pino
11
+ * @since 1.0.0
3
12
*/
4
13
5
14
import { EventEmitter } from 'events' ;
@@ -16,9 +25,32 @@ import {
16
25
} from './events/CommandEvents.cjs' ;
17
26
18
27
/**
19
- * Base command class that all commands extend from
28
+ * Base command class that all commands extend from.
29
+ *
30
+ * Provides event-driven architecture with production safety features,
31
+ * logging capabilities, and standardized user interaction patterns.
32
+ *
33
+ * @class
34
+ * @extends EventEmitter
35
+ * @example
36
+ * class MyCommand extends Command {
37
+ * async performExecute(options) {
38
+ * this.progress('Starting operation...');
39
+ * // Do work here
40
+ * this.success('Operation completed!');
41
+ * return result;
42
+ * }
43
+ * }
20
44
*/
21
45
class Command extends EventEmitter {
46
+ /**
47
+ * Creates a new Command instance.
48
+ *
49
+ * @param {Object|null } legacyConfig - Legacy configuration object (Config class instance)
50
+ * @param {Object|null } logger - Pino logger instance (optional, will create default if null)
51
+ * @param {boolean } isProd - Whether running in production mode (affects confirmation behavior)
52
+ * @param {Object|null } outputConfig - Output configuration for paths (OutputConfig class instance)
53
+ */
22
54
constructor (
23
55
legacyConfig = null , // Config class instance is OK - it's a typed class
24
56
logger = null ,
@@ -41,7 +73,10 @@ class Command extends EventEmitter {
41
73
}
42
74
43
75
/**
44
- * Create a default pino logger
76
+ * Creates a default pino logger with development-friendly configuration.
77
+ *
78
+ * @returns {Object } Configured pino logger instance
79
+ * @private
45
80
*/
46
81
createLogger ( ) {
47
82
const isDev = process . env . NODE_ENV !== 'production' ;
@@ -60,7 +95,22 @@ class Command extends EventEmitter {
60
95
}
61
96
62
97
/**
63
- * Execute the command with production safety check
98
+ * Executes the command with production safety checks and event emission.
99
+ *
100
+ * This is the main entry point for command execution. It handles:
101
+ * - Start event emission
102
+ * - Production confirmation (if required)
103
+ * - Delegation to performExecute()
104
+ * - Completion event emission
105
+ * - Error handling and cleanup
106
+ *
107
+ * @param {...* } args - Arguments to pass to performExecute()
108
+ * @returns {Promise<*> } Result from performExecute() or undefined if cancelled
109
+ * @throws {Error } Any error thrown by performExecute()
110
+ * @emits start - When command execution begins
111
+ * @emits complete - When command execution succeeds
112
+ * @emits cancelled - When command is cancelled by user
113
+ * @emits error - When command execution fails
64
114
*/
65
115
async execute ( ...args ) {
66
116
// Emit start event
@@ -111,15 +161,29 @@ class Command extends EventEmitter {
111
161
}
112
162
113
163
/**
114
- * The actual execution logic - must be overridden by subclasses
164
+ * The actual execution logic that must be implemented by subclasses.
165
+ *
166
+ * This abstract method contains the core command logic. Subclasses must
167
+ * override this method to provide their specific functionality.
168
+ *
169
+ * @abstract
170
+ * @param {...* } args - Command-specific arguments
171
+ * @returns {Promise<*> } Command execution result
172
+ * @throws {Error } Must be implemented by subclass
115
173
*/
116
174
// eslint-disable-next-line require-await
117
175
async performExecute ( ..._args ) {
118
176
throw new Error ( 'Command.performExecute() must be implemented by subclass' ) ;
119
177
}
120
178
121
179
/**
122
- * Confirm production operation
180
+ * Prompts user to confirm production operation with safety warnings.
181
+ *
182
+ * Displays warning about production environment and requests explicit
183
+ * user confirmation before proceeding with potentially dangerous operations.
184
+ *
185
+ * @returns {Promise<boolean> } True if user confirms, false otherwise
186
+ * @private
123
187
*/
124
188
async confirmProduction ( ) {
125
189
this . warn ( 'Production operation requested!' , {
@@ -133,7 +197,14 @@ class Command extends EventEmitter {
133
197
}
134
198
135
199
/**
136
- * Emit a progress event
200
+ * Emits a progress event with optional data payload.
201
+ *
202
+ * Used to communicate ongoing operation status to event listeners,
203
+ * typically for progress bars or status updates in CLI interfaces.
204
+ *
205
+ * @param {string } message - Progress description
206
+ * @param {Object } [data={}] - Additional progress data
207
+ * @emits progress - Progress event with message and data
137
208
*/
138
209
progress ( message , data = { } ) {
139
210
const event = new ProgressEvent ( message , null , data ) ; // null percentage for indeterminate progress
@@ -149,7 +220,14 @@ class Command extends EventEmitter {
149
220
}
150
221
151
222
/**
152
- * Emit a warning event
223
+ * Emits a warning event for non-fatal issues.
224
+ *
225
+ * Used to communicate potential problems or important information
226
+ * that doesn't prevent command execution from continuing.
227
+ *
228
+ * @param {string } message - Warning message
229
+ * @param {Object } [data={}] - Additional warning context
230
+ * @emits warning - Warning event with message and data
153
231
*/
154
232
warn ( message , data = { } ) {
155
233
const event = new WarningEvent ( message , data ) ;
@@ -164,7 +242,15 @@ class Command extends EventEmitter {
164
242
}
165
243
166
244
/**
167
- * Emit an error event
245
+ * Emits an error event for command failures.
246
+ *
247
+ * Used to communicate command execution errors with full context
248
+ * including error objects and additional debugging information.
249
+ *
250
+ * @param {string } message - Error description
251
+ * @param {Error|null } [error=null] - Error object with stack trace
252
+ * @param {Object } [data={}] - Additional error context
253
+ * @emits error - Error event with message, error object, and data
168
254
*/
169
255
error ( message , error = null , data = { } ) {
170
256
// Extract code from data if provided
@@ -182,7 +268,14 @@ class Command extends EventEmitter {
182
268
}
183
269
184
270
/**
185
- * Emit a success event
271
+ * Emits a success event for completed operations.
272
+ *
273
+ * Used to communicate successful command execution with result data
274
+ * for display in CLI interfaces or logging.
275
+ *
276
+ * @param {string } message - Success message
277
+ * @param {Object } [data={}] - Additional success data
278
+ * @emits success - Success event with message and data
186
279
*/
187
280
success ( message , data = { } ) {
188
281
const event = new SuccessEvent ( message , data ) ;
@@ -197,7 +290,15 @@ class Command extends EventEmitter {
197
290
}
198
291
199
292
/**
200
- * Emit a prompt event and wait for response
293
+ * Emits a prompt event and waits for user response.
294
+ *
295
+ * Creates an interactive prompt that waits for user input through
296
+ * the event system. Used by CLI interfaces for user interaction.
297
+ *
298
+ * @param {string } type - Type of prompt (confirm, input, select, etc.)
299
+ * @param {Object } options - Prompt configuration options
300
+ * @returns {Promise<*> } User response value
301
+ * @emits prompt - Prompt event with type, options, and resolve callback
201
302
*/
202
303
prompt ( type , options ) {
203
304
return new Promise ( ( resolve ) => {
@@ -206,24 +307,49 @@ class Command extends EventEmitter {
206
307
}
207
308
208
309
/**
209
- * Emit a confirmation event and wait for response
310
+ * Prompts user for yes/no confirmation.
311
+ *
312
+ * Convenience method for boolean confirmation prompts with
313
+ * optional default value handling.
314
+ *
315
+ * @param {string } message - Confirmation question
316
+ * @param {boolean } [defaultValue=false] - Default response if user presses enter
317
+ * @returns {Promise<boolean> } True if confirmed, false otherwise
210
318
*/
211
319
async confirm ( message , defaultValue = false ) {
212
320
return await this . prompt ( 'confirm' , { message, default : defaultValue } ) ;
213
321
}
214
322
215
323
/**
216
- * Emit an input event and wait for response
324
+ * Prompts user for text input.
325
+ *
326
+ * Convenience method for text input prompts with optional
327
+ * validation and default value handling.
328
+ *
329
+ * @param {string } message - Input prompt message
330
+ * @param {Object } [options={}] - Input options (default, validation, etc.)
331
+ * @returns {Promise<string> } User input string
217
332
*/
218
333
async input ( message , options = { } ) {
219
334
return await this . prompt ( 'input' , { message, ...options } ) ;
220
335
}
221
336
222
337
/**
223
- * Validate an event against expected class type
338
+ * Validates an event object against expected class type using instanceof checks.
339
+ *
340
+ * Provides runtime type validation for event objects to ensure they conform
341
+ * to expected event class structures and contain required properties.
342
+ *
224
343
* @param {Object } event - The event object to validate
225
- * @param {Function } expectedClass - Expected event class constructor
226
- * @returns {Object } Validation result with success/error properties
344
+ * @param {Function|null } [expectedClass=null] - Expected event class constructor for instanceof validation
345
+ * @returns {Object } Validation result object
346
+ * @returns {boolean } returns.success - True if validation passes
347
+ * @returns {string|null } returns.error - Error message if validation fails, null if success
348
+ * @example
349
+ * const result = command.validateEvent(progressEvent, ProgressEvent);
350
+ * if (!result.success) {
351
+ * console.error('Invalid event:', result.error);
352
+ * }
227
353
*/
228
354
validateEvent ( event , expectedClass = null ) {
229
355
if ( ! expectedClass ) {
@@ -243,10 +369,19 @@ class Command extends EventEmitter {
243
369
}
244
370
245
371
/**
246
- * Emit a typed event with validation
247
- * @param {string } eventName - The event name
248
- * @param {Object } eventData - The event data or event instance
249
- * @param {Function } expectedClass - Optional expected event class for validation
372
+ * Emits a typed event with optional validation and automatic format conversion.
373
+ *
374
+ * Provides event emission with runtime validation against expected class types
375
+ * and automatic conversion of CommandEvent instances to the standard event format
376
+ * required by the CLI interface for backward compatibility.
377
+ *
378
+ * @param {string } eventName - The event name to emit
379
+ * @param {Object } eventData - The event data or CommandEvent instance
380
+ * @param {Function|null } [expectedClass=null] - Optional expected event class for instanceof validation
381
+ * @emits eventName - The specified event with standardized format
382
+ * @example
383
+ * const progressEvent = new ProgressEvent('Processing...', 50);
384
+ * command.emitTypedEvent('progress', progressEvent, ProgressEvent);
250
385
*/
251
386
emitTypedEvent ( eventName , eventData , expectedClass = null ) {
252
387
const validation = this . validateEvent ( eventData , expectedClass ) ;
0 commit comments