@fromsvenwithlove/devops-issues-cli
Version:
AI-powered CLI tool and library for Azure DevOps work item management with Claude agents
56 lines (48 loc) • 2.08 kB
JavaScript
import chalk from 'chalk';
export class ConfigError extends Error {
constructor(message) {
super(message);
this.name = 'ConfigError';
}
}
export function getConfig() {
const config = {
orgUrl: process.env.AZ_DEVOPS_ORG,
project: process.env.AZ_DEVOPS_PROJECT,
pat: process.env.AZ_DEVOPS_PAT,
user: process.env.AZ_DEVOPS_USER,
rootIssueId: process.env.AZ_DEVOPS_ROOT_ISSUE_ID ? parseInt(process.env.AZ_DEVOPS_ROOT_ISSUE_ID) : null, // Optional Root Issue ID filter
batchSize: process.env.AZ_DEVOPS_BATCH_SIZE ? parseInt(process.env.AZ_DEVOPS_BATCH_SIZE) : 200 // API batch size limit (default: 200)
};
const missing = [];
if (!config.orgUrl) missing.push('AZ_DEVOPS_ORG');
if (!config.project) missing.push('AZ_DEVOPS_PROJECT');
if (!config.pat) missing.push('AZ_DEVOPS_PAT');
if (!config.user) missing.push('AZ_DEVOPS_USER');
if (missing.length > 0) {
const errorMessage = `Missing required environment variables: ${missing.join(', ')}\n\n` +
`Please set the following environment variables:\n` +
` ${chalk.yellow('AZ_DEVOPS_ORG')} - Your Azure DevOps organization URL\n` +
` ${chalk.yellow('AZ_DEVOPS_PROJECT')} - Your project name\n` +
` ${chalk.yellow('AZ_DEVOPS_PAT')} - Your Personal Access Token\n` +
` ${chalk.yellow('AZ_DEVOPS_USER')} - Your user email or display name\n\n` +
`Optional:\n` +
` ${chalk.yellow('AZ_DEVOPS_ROOT_ISSUE_ID')} - Filter by Root Issue ID (e.g., "30408")\n` +
` ${chalk.yellow('AZ_DEVOPS_BATCH_SIZE')} - API batch size for large requests (default: 200)\n\n` +
`You can set these in a .env file in your project root.`;
throw new ConfigError(errorMessage);
}
return config;
}
export function validateOrgUrl(url) {
try {
const parsedUrl = new URL(url);
if (!parsedUrl.hostname.includes('dev.azure.com') &&
!parsedUrl.hostname.includes('visualstudio.com')) {
throw new Error('Invalid Azure DevOps organization URL');
}
return true;
} catch (error) {
return false;
}
}