code icon Code

JSON to CSV

Convert JSON array to CSV format

Source Code

import fs from "fs";
import path from "path";

const [inputPath, fieldsArg, outputPath] = process.argv.slice(2);

if (!inputPath || !fieldsArg || !outputPath) {
  console.error("Usage: inputPath fields outputPath");
  process.exit(1);
}

/**
 * Get nested field value using dot notation
 */
function getField(obj, fieldPath) {
  const parts = fieldPath.split(".");
  let value = obj;
  for (const part of parts) {
    if (value == null) return undefined;
    value = value[part];
  }
  return value;
}

/**
 * Escape CSV field value
 */
function escapeCSV(value) {
  if (value == null) return "";

  let str;
  if (typeof value === "object") {
    str = JSON.stringify(value);
  } else {
    str = String(value);
  }

  // If contains comma, quote, or newline, wrap in quotes and escape inner quotes
  if (str.includes(",") || str.includes('"') || str.includes("\n")) {
    return '"' + str.replace(/"/g, '""') + '"';
  }

  return str;
}

try {
  console.log(`Reading ${inputPath}...`);
  const raw = fs.readFileSync(inputPath, "utf-8");
  const data = JSON.parse(raw);

  const items = Array.isArray(data)
    ? data
    : data.items || data.results || data.messages || [];

  if (!Array.isArray(items)) {
    console.error("Input must be a JSON array or object with array property");
    process.exit(1);
  }

  // Determine fields
  let fields;
  if (fieldsArg === "all" && items.length > 0) {
    // Get all unique keys from all items
    const allKeys = new Set();
    for (const item of items) {
      for (const key of Object.keys(item)) {
        allKeys.add(key);
      }
    }
    fields = Array.from(allKeys);
  } else {
    fields = fieldsArg.split(",").map((f) => f.trim());
  }

  console.log(`Converting ${items.length} items to CSV with fields: ${fields.join(", ")}`);

  const lines = [];

  // Header row
  lines.push(fields.map(escapeCSV).join(","));

  // Data rows
  for (const item of items) {
    const row = fields.map((f) => escapeCSV(getField(item, f)));
    lines.push(row.join(","));
  }

  const csv = lines.join("\n");

  // Ensure output directory exists
  const dir = path.dirname(outputPath);
  if (dir && dir !== ".") {
    fs.mkdirSync(dir, { recursive: true });
  }

  fs.writeFileSync(outputPath, csv);

  console.log(`\nāœ“ Converted ${items.length} items to CSV`);
  console.log(`  Fields: ${fields.join(", ")}`);
  console.log(`  Rows: ${items.length + 1} (including header)`);
  console.log(`  Written to: ${outputPath}`);

  console.log(
    JSON.stringify({
      success: true,
      outputPath,
      count: items.length,
      fields,
    })
  );
} catch (error) {
  console.error("Error:", error.message);
  process.exit(1);
}