Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/commands/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ export default class ConfigCommand extends Command {
'api-key': Flags.string({
description: 'Set OpenAI API key',
}),
'base-url': Flags.string({
description: 'Set OpenAI Base URL',
}),
show: Flags.boolean({
description: 'Show current configuration',
}),
Expand All @@ -27,6 +30,10 @@ export default class ConfigCommand extends Command {
await this.setApiKey(flags['api-key']);
}

if (flags['base-url']) {
await this.setBaseUrl(flags['base-url']);
}

if (flags.show) {
await this.showConfig();
}
Expand All @@ -49,6 +56,19 @@ export default class ConfigCommand extends Command {
this.log(chalk.dim('Built with ❤️ by \u001b]8;;https://codewithbeto.dev\u001b\\codewithbeto.dev\u001b]8;;\u001b\\ - Ship faster, contribute more, lead with confidence'));
}


private async setBaseUrl(baseUrl: string): Promise<void> {
const error = ValidationService.validateBaseUrl(baseUrl);
if (error) {
this.error(chalk.red(error));
}

await ConfigService.set('openai_base_url', baseUrl);
this.log(chalk.green('✅ OpenAI Base URL configured successfully!'));
this.log('');
this.log(chalk.dim('Built with ❤️ by \u001b]8;;https://codewithbeto.dev\u001b\\codewithbeto.dev\u001b]8;;\u001b\\ - Ship faster, contribute more, lead with confidence'));
}

private async showConfig(): Promise<void> {
const config = await ConfigService.getConfig();

Expand All @@ -62,6 +82,10 @@ export default class ConfigCommand extends Command {
this.log(`🔑 OpenAI API Key: ${chalk.red('Not configured')}`);
this.log(chalk.gray(' Set with: snapai config --api-key YOUR_KEY'));
}

if (config.openai_base_url) {
this.log(`🔗 OpenAI Base URL: ${chalk.blue(config.openai_base_url)}`);
}

if (config.default_output_path) {
this.log(`📁 Default Output: ${chalk.blue(config.default_output_path)}`);
Expand Down
2 changes: 2 additions & 0 deletions src/services/openai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { IconGenerationOptions, OpenAIResponse } from "../types.js";
export class OpenAIService {
private static async getClient(): Promise<OpenAI> {
const apiKey = await ConfigService.get("openai_api_key");
const baseUrl = await ConfigService.get("openai_base_url");

if (!apiKey) {
throw new Error(
Expand All @@ -14,6 +15,7 @@ export class OpenAIService {

return new OpenAI({
apiKey: apiKey,
baseURL: baseUrl
});
}

Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export interface ConfigData {
openai_api_key?: string;
openai_base_url?: string;
default_output_path?: string;
}

Expand Down
8 changes: 8 additions & 0 deletions src/utils/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ export class ValidationService {
return null;
}

static validateBaseUrl(baseUrl: string): string | null {
if (!baseUrl || !baseUrl.startsWith('https://')) {
return 'Invalid OpenAI URL format';
}

return null;
}

static validateOutputPath(outputPath: string): string | null {
if (!outputPath || outputPath.trim().length === 0) {
return 'Output path cannot be empty';
Expand Down