/ src / utils / flag-parser.js
flag-parser.js
  1  /**
  2   * Flag Parser Utility
  3   * Parses command line flags for stage orchestration
  4   */
  5  
  6  /**
  7   * Parse --skip flags from command line arguments
  8   * @param {string[]} args - Command line arguments (process.argv)
  9   * @returns {Set<string>} Set of stages to skip
 10   *
 11   * @example
 12   * parseSkipFlags(['--skip', 'keywords,serps'])
 13   * // Returns: Set(['keywords', 'serps'])
 14   */
 15  export function parseSkipFlags(args = process.argv) {
 16    const skipIndex = args.findIndex(arg => arg === '--skip');
 17  
 18    if (skipIndex === -1 || skipIndex === args.length - 1) {
 19      return new Set();
 20    }
 21  
 22    const skipValue = args[skipIndex + 1];
 23    const stages = skipValue
 24      .split(',')
 25      .map(s => s.trim())
 26      .filter(Boolean);
 27  
 28    return new Set(stages);
 29  }
 30  
 31  /**
 32   * Parse --limit flag from command line arguments
 33   * @param {string[]} args - Command line arguments (process.argv)
 34   * @returns {number|null} Limit value or null if not specified
 35   *
 36   * @example
 37   * parseLimitFlag(['--limit', '10'])
 38   * // Returns: 10
 39   */
 40  export function parseLimitFlag(args = process.argv) {
 41    const limitIndex = args.findIndex(arg => arg === '--limit');
 42  
 43    if (limitIndex === -1 || limitIndex === args.length - 1) {
 44      return null;
 45    }
 46  
 47    const limitValue = parseInt(args[limitIndex + 1], 10);
 48    return isNaN(limitValue) ? null : limitValue;
 49  }
 50  
 51  /**
 52   * Parse --force flag from command line arguments
 53   * @param {string[]} args - Command line arguments (process.argv)
 54   * @returns {boolean} True if --force flag is present
 55   */
 56  export function parseForceFlag(args = process.argv) {
 57    return args.includes('--force');
 58  }
 59  
 60  /**
 61   * Parse --country flag from command line arguments
 62   * @param {string[]} args - Command line arguments (process.argv)
 63   * @returns {string|null} Country code or null if not specified
 64   *
 65   * @example
 66   * parseCountryFlag(['--country', 'UK'])
 67   * // Returns: 'UK'
 68   */
 69  export function parseCountryFlag(args = process.argv) {
 70    const countryIndex = args.findIndex(arg => arg === '--country');
 71  
 72    if (countryIndex === -1 || countryIndex === args.length - 1) {
 73      return null;
 74    }
 75  
 76    return args[countryIndex + 1];
 77  }
 78  
 79  /**
 80   * Parse --type flag from command line arguments
 81   * @param {string[]} args - Command line arguments (process.argv)
 82   * @returns {string|null} Type value ('businesses' or 'regions') or null if not specified
 83   *
 84   * @example
 85   * parseTypeFlag(['--type', 'businesses'])
 86   * // Returns: 'businesses'
 87   */
 88  export function parseTypeFlag(args = process.argv) {
 89    const typeIndex = args.findIndex(arg => arg === '--type');
 90  
 91    if (typeIndex === -1 || typeIndex === args.length - 1) {
 92      return null;
 93    }
 94  
 95    return args[typeIndex + 1];
 96  }
 97  
 98  /**
 99   * Parse --csv flag from command line arguments
100   * @param {string[]} args - Command line arguments (process.argv)
101   * @returns {string|null} CSV file path or null if not specified
102   *
103   * @example
104   * parseCsvFlag(['--csv', 'data/au/businesses-search-volume.csv'])
105   * // Returns: 'data/au/businesses-search-volume.csv'
106   */
107  export function parseCsvFlag(args = process.argv) {
108    const csvIndex = args.findIndex(arg => arg === '--csv');
109  
110    if (csvIndex === -1 || csvIndex === args.length - 1) {
111      return null;
112    }
113  
114    return args[csvIndex + 1];
115  }
116  
117  /**
118   * Parse --threshold flag from command line arguments
119   * @param {string[]} args - Command line arguments (process.argv)
120   * @returns {number|null} Threshold value or null if not specified
121   *
122   * @example
123   * parseThresholdFlag(['--threshold', '200000'])
124   * // Returns: 200000
125   */
126  export function parseThresholdFlag(args = process.argv) {
127    const thresholdIndex = args.findIndex(arg => arg === '--threshold');
128  
129    if (thresholdIndex === -1 || thresholdIndex === args.length - 1) {
130      return null;
131    }
132  
133    const thresholdValue = parseInt(args[thresholdIndex + 1], 10);
134    return isNaN(thresholdValue) ? null : thresholdValue;
135  }
136  
137  /**
138   * Parse all common flags from command line arguments
139   * @param {string[]} args - Command line arguments (process.argv)
140   * @returns {Object} Object with skip, limit, force, country, type, csv, and threshold flags
141   *
142   * @example
143   * parseFlags(['--skip', 'keywords', '--limit', '10', '--force', '--country', 'UK', '--type', 'businesses', '--threshold', '200000'])
144   * // Returns: { skip: Set(['keywords']), limit: 10, force: true, country: 'UK', type: 'businesses', csv: null, threshold: 200000 }
145   */
146  export function parseFlags(args = process.argv) {
147    return {
148      skip: parseSkipFlags(args),
149      limit: parseLimitFlag(args),
150      force: parseForceFlag(args),
151      country: parseCountryFlag(args),
152      type: parseTypeFlag(args),
153      csv: parseCsvFlag(args),
154      threshold: parseThresholdFlag(args),
155    };
156  }