UNPKG

linear-cmd

Version:

A GitHub CLI-like tool for Linear - manage issues, accounts, and more

143 lines (142 loc) 4.7 kB
import * as fs from 'fs'; import { CONFIG_PATHS } from '../constants.js'; import { linearConfigSchema, userMetadataSchema } from '../types/local.js'; import { readJson5, writeJson5 } from '../utils/json-utils.js'; export class ConfigManager { userMetadata = null; config = null; constructor() { this.ensureConfigDirectory(); this.initializeUserMetadata(); } ensureConfigDirectory() { if (!fs.existsSync(CONFIG_PATHS.configDir)) { fs.mkdirSync(CONFIG_PATHS.configDir, { recursive: true }); } } initializeUserMetadata() { if (!fs.existsSync(CONFIG_PATHS.userMetadataFile)) { this.createDefaultUserMetadata(); } this.loadUserMetadata(); } createDefaultUserMetadata() { const defaultMetadata = { config_path: CONFIG_PATHS.defaultConfigFile }; writeJson5(CONFIG_PATHS.userMetadataFile, defaultMetadata); } loadUserMetadata() { try { const data = readJson5(CONFIG_PATHS.userMetadataFile); const validated = userMetadataSchema.parse(data); this.userMetadata = validated; } catch (error) { throw new Error(`Failed to load user metadata: ${error instanceof Error ? error.message : 'Unknown error'}`); } } getConfigPath() { if (!this.userMetadata) { throw new Error('User metadata not loaded'); } return this.userMetadata.config_path; } loadConfig() { if (this.config) { return this.config; } const configPath = this.getConfigPath(); if (!fs.existsSync(configPath)) { this.createDefaultConfig(); } try { const data = readJson5(configPath); const validated = linearConfigSchema.parse(data); this.config = validated; return this.config; } catch (error) { throw new Error(`Failed to load config: ${error instanceof Error ? error.message : 'Unknown error'}`); } } createDefaultConfig() { const defaultConfig = { accounts: {}, settings: { max_results: 50, date_format: 'relative', auto_update_accounts: true } }; const configPath = this.getConfigPath(); writeJson5(configPath, defaultConfig); } saveConfig() { if (!this.config) { throw new Error('No config to save'); } const configPath = this.getConfigPath(); writeJson5(configPath, this.config); } // Public API Methods async addAccount(name, apiKey, teamId) { const config = this.loadConfig(); if (config.accounts[name]) { throw new Error(`Account '${name}' already exists`); } const account = { name, api_key: apiKey, team_id: teamId }; config.accounts[name] = account; // No longer set as active automatically this.saveConfig(); } async removeAccount(name) { const config = this.loadConfig(); if (!config.accounts[name]) { throw new Error(`Account '${name}' not found`); } delete config.accounts[name]; // No longer manage active account this.saveConfig(); } // Active account methods removed - accounts must be specified explicitly getAllAccounts() { const config = this.loadConfig(); return Object.values(config.accounts); } getAccount(name) { const config = this.loadConfig(); return config.accounts[name] || null; } listAccounts() { const config = this.loadConfig(); return Object.entries(config.accounts).map(([name, account]) => ({ name, teamId: account.team_id })); } updateAccountApiKey(name, apiKey) { const config = this.loadConfig(); if (!config.accounts[name]) { throw new Error(`Account '${name}' not found`); } config.accounts[name].api_key = apiKey; this.saveConfig(); } findAccountByWorkspace(workspace) { const accounts = this.getAllAccounts(); return accounts.find((a) => a.workspaces?.includes(workspace)) || null; } async updateAccountWorkspaces(accountId, workspaces) { const config = this.loadConfig(); if (!config.accounts[accountId]) { throw new Error(`Account '${accountId}' not found`); } config.accounts[accountId].workspaces = workspaces; this.saveConfig(); } }