Problem
The Firebase adapter team has FirebaseConfig extends Config, but createCLI doesn't support config generics. This forces type casting in the extendFlags callback, making it inconvenient and error-prone.
Current code (Firebase adapter):
interface FirebaseConfig extends Config {
databaseUrl: string;
applicationCredentials: string;
connectionTimeout?: number;
}
const program = createCLI({
addCustomOptions: (program) => {
program.option('--database-url <url>', 'Firebase Database URL');
},
extendFlags: (config, flags) => {
// ❌ config is typed as Config, not FirebaseConfig
// Must cast to access FirebaseConfig properties
(config as FirebaseConfig).databaseUrl = flags.databaseUrl;
(config as FirebaseConfig).applicationCredentials = flags.credentials;
},
createExecutor: async (config) => {
// ❌ config is typed as Config, not FirebaseConfig
return FirebaseAdapter.getInstance({ config: config as FirebaseConfig });
}
});
Proposed Solution
Add TConfig generic parameter to createCLI (same pattern as THandler in #138 and TConfig in #144).
After fix:
const program = createCLI<IFirebaseDB, FirebaseAdapter, FirebaseConfig>({
addCustomOptions: (program) => {
program.option('--database-url <url>', 'Firebase Database URL');
},
extendFlags: (config, flags) => {
// ✅ config is typed as FirebaseConfig - full IntelliSense!
config.databaseUrl = flags.databaseUrl;
config.applicationCredentials = flags.credentials;
config.connectionTimeout = flags.timeout ? parseInt(flags.timeout, 10) : undefined;
},
createExecutor: async (config) => {
// ✅ config is typed as FirebaseConfig
return FirebaseAdapter.getInstance({ config });
}
});
Implementation
1. Update CLIOptions interface (createCLI.ts)
export interface CLIOptions<
DB extends IDB,
TExecutor extends MigrationScriptExecutor<DB> = MigrationScriptExecutor<DB>,
TConfig extends Config = Config // NEW: Add TConfig generic
> {
createExecutor: (config: TConfig) => TExecutor | Promise<TExecutor>;
config?: Partial<TConfig>; // Update type
configLoader?: IConfigLoader<TConfig>; // Already exists from #144
extendFlags?: (config: TConfig, flags: CLIFlags) => void; // Update type
// ... other fields unchanged
}
2. Update createCLI function signature
export function createCLI<
DB extends IDB,
TExecutor extends MigrationScriptExecutor<DB> = MigrationScriptExecutor<DB>,
TConfig extends Config = Config // NEW: Add TConfig generic
>(
options: CLIOptions<DB, TExecutor, TConfig>
): Command {
// Implementation stays mostly the same
// TypeScript will infer TConfig throughout
}
3. Update internal usage
The createExecutorWithFlags factory function already uses options.configLoader which is typed as IConfigLoader<TConfig> from #144, so it should work seamlessly.
Benefits
Testing
Add tests to test/unit/cli/createCLI.test.ts:
- Test with custom config type (e.g.,
FirebaseConfig)
- Verify
extendFlags receives typed config
- Verify
createExecutor receives typed config
- Ensure backward compatibility (no generic =
Config)
Related Issues
This completes the type safety story started in v0.8.0-v0.8.3.
Acceptance Criteria
Problem
The Firebase adapter team has
FirebaseConfig extends Config, butcreateCLIdoesn't support config generics. This forces type casting in theextendFlagscallback, making it inconvenient and error-prone.Current code (Firebase adapter):
Proposed Solution
Add
TConfiggeneric parameter tocreateCLI(same pattern asTHandlerin #138 andTConfigin #144).After fix:
Implementation
1. Update
CLIOptionsinterface (createCLI.ts)2. Update
createCLIfunction signature3. Update internal usage
The
createExecutorWithFlagsfactory function already usesoptions.configLoaderwhich is typed asIConfigLoader<TConfig>from #144, so it should work seamlessly.Benefits
extendFlagsandcreateExecutorTHandler(Add handler generic type parameter to MigrationScriptExecutor #138) and executorTConfig(Feature Request: Generic Config Type in IExecutorOptions #144)TConfig = Configmaintains existing behaviorFirebaseConfigwithout castsTesting
Add tests to
test/unit/cli/createCLI.test.ts:FirebaseConfig)extendFlagsreceives typed configcreateExecutorreceives typed configConfig)Related Issues
THandlergeneric for type-safe handler accessTConfiggeneric to executor interfacesaddCustomOptionsandextendFlagscallbacks (v0.8.3)This completes the type safety story started in v0.8.0-v0.8.3.
Acceptance Criteria
CLIOptionshasTConfiggeneric parameter withConfigdefaultcreateCLIhasTConfiggeneric parameter withConfigdefaultextendFlagscallback receivesTConfig(notConfig)createExecutorcallback receivesTConfig(notConfig)options.configtyped asPartial<TConfig>