Skip to content
Draft
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
21 changes: 5 additions & 16 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
import { Command } from 'commander';
Expand All @@ -10,6 +10,7 @@ import {
saveConfig,
isSetupComplete,
getMercuryHome,
appendToMercuryEnv,
ensureCreatorField,
clearTelegramAccess,
isProviderConfigured,
Expand Down Expand Up @@ -539,18 +540,6 @@ async function promptValidatedValue(
}
}

function appendToEnv(key: string, value: string): void {
const envPath = join(getMercuryHome(), '.env');
let envContent = '';
if (existsSync(envPath)) {
envContent = readFileSync(envPath, 'utf-8');
}
const lines = envContent.split('\n').filter((l: string) => !l.startsWith(`${key}=`) && l.trim() !== '');
lines.push(`${key}=${value}`);
writeFileSync(envPath, lines.join('\n') + '\n', 'utf-8');
process.env[key] = value;
}

function parseGithubRepo(input: string): { owner: string; repo: string } | null {
const trimmed = input.trim().replace(/\/+$/, '');
const urlMatch = trimmed.match(/github\.com\/([^/]+)\/([^/]+)/);
Expand Down Expand Up @@ -1078,7 +1067,7 @@ async function configure(existingConfig?: MercuryConfig): Promise<void> {
const ghTokenCurrent = process.env.GITHUB_TOKEN ? ` [${maskKey(process.env.GITHUB_TOKEN)}]` : '';
const ghToken = await ask(chalk.white(` 2. GitHub PAT${ghTokenCurrent}: `));
if (ghToken) {
appendToEnv('GITHUB_TOKEN', ghToken);
appendToMercuryEnv('GITHUB_TOKEN', ghToken);
}

if (config.github.username || process.env.GITHUB_TOKEN) {
Expand Down Expand Up @@ -1122,14 +1111,14 @@ async function configure(existingConfig?: MercuryConfig): Promise<void> {
const spotifyClientId = await ask(chalk.white(` 1. Spotify Client ID${spotifyIdCurrent}: `));
if (spotifyClientId) {
config.spotify.clientId = spotifyClientId;
appendToEnv('SPOTIFY_CLIENT_ID', spotifyClientId);
appendToMercuryEnv('SPOTIFY_CLIENT_ID', spotifyClientId);
}

const spotifySecretCurrent = isReconfig && config.spotify.clientSecret ? ` [${maskKey(config.spotify.clientSecret)}]` : '';
const spotifyClientSecret = await ask(chalk.white(` 2. Spotify Client Secret${spotifySecretCurrent}: `));
if (spotifyClientSecret) {
config.spotify.clientSecret = spotifyClientSecret;
appendToEnv('SPOTIFY_CLIENT_SECRET', spotifyClientSecret);
appendToMercuryEnv('SPOTIFY_CLIENT_SECRET', spotifyClientSecret);
}

if (spotifyClientId || spotifyClientSecret) {
Expand Down
47 changes: 47 additions & 0 deletions src/utils/config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
import { afterEach, describe, expect, it, vi } from 'vitest';

let mercuryHome = '';

async function loadConfigModule() {
vi.resetModules();
vi.stubEnv('MERCURY_HOME', mercuryHome);
return import('./config.js');
}

describe('appendToMercuryEnv', () => {
afterEach(() => {
vi.unstubAllEnvs();
if (mercuryHome) {
rmSync(mercuryHome, { recursive: true, force: true });
mercuryHome = '';
}
});

it('creates the Mercury home directory and env file on first write', async () => {
mercuryHome = join(mkdtempSync(join(tmpdir(), 'mercury-config-test-')), 'nested-home');
const { appendToMercuryEnv } = await loadConfigModule();

appendToMercuryEnv('GITHUB_TOKEN', 'ghp_test_token');

const envPath = join(mercuryHome, '.env');
expect(existsSync(envPath)).toBe(true);
expect(readFileSync(envPath, 'utf-8')).toBe('GITHUB_TOKEN=ghp_test_token\n');
expect(process.env.GITHUB_TOKEN).toBe('ghp_test_token');
});

it('replaces an existing key without duplicating unrelated env entries', async () => {
mercuryHome = mkdtempSync(join(tmpdir(), 'mercury-config-test-'));
const { appendToMercuryEnv } = await loadConfigModule();

appendToMercuryEnv('GITHUB_TOKEN', 'ghp_old_token');
appendToMercuryEnv('SPOTIFY_CLIENT_ID', 'spotify-client');
appendToMercuryEnv('GITHUB_TOKEN', 'ghp_new_token');

expect(readFileSync(join(mercuryHome, '.env'), 'utf-8')).toBe(
'SPOTIFY_CLIENT_ID=spotify-client\nGITHUB_TOKEN=ghp_new_token\n',
);
});
});
21 changes: 21 additions & 0 deletions src/utils/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,27 @@ export function getMercuryHome(): string {
return process.env.MERCURY_HOME || MERCURY_HOME;
}

export function appendToMercuryEnv(key: string, value: string): void {
const dir = getMercuryHome();
if (!existsSync(dir)) {
mkdirSync(dir, { recursive: true });
}

const envPath = join(dir, '.env');
let envContent = '';
if (existsSync(envPath)) {
envContent = readFileSync(envPath, 'utf-8');
}

const lines = envContent
.split('\n')
.filter((line) => !line.startsWith(`${key}=`) && line.trim() !== '');

lines.push(`${key}=${value}`);
process.env[key] = value;
writeFileSync(envPath, lines.join('\n') + '\n', 'utf-8');
}

export function getMemoryDir(): string {
return join(getMercuryHome(), 'memory');
}
Expand Down