import fs from 'fs'; import { Parser } from 'json2csv'; // Load the enriched JSON file const jsonFile = 'enriched-meraki.csv.json'; // Your input JSON path const data = JSON.parse(fs.readFileSync(jsonFile, 'utf8')); // Flatten the nested objects for CSV-friendly structure const flattenedData = data.map(item => { const meraki = item.meraki || {}; // safe access // Handle stickyMacList as comma-separated string (or empty string) const stickyMacListStr = Array.isArray(meraki.stickyMacList) && meraki.stickyMacList.length > 0 ? meraki.stickyMacList.join(', ') : ''; return { device_id: item.device_id || '', device_friendly_name: item.device_friendly_name || '', device_enrollment_user_name: item.device_enrollment_user_name || '', _device_platform: item._device_platform || '', device_os_version: item.device_os_version || '', device_last_seen_utc: item.device_last_seen_utc || '', device_enrollment_status: item.device_enrollment_status || '', device_model_name: item.device_model_name || '', _device_mac_address: item._device_mac_address || '', device_mac_address: item.device_mac_address || '', // Existing Meraki fields meraki_deviceName: meraki.deviceName || '', meraki_switchport: meraki.switchport || '', meraki_vlan: meraki.vlan || '', meraki_status: meraki.status || '', meraki_connection: meraki.connection || '', meraki_lastSeen: meraki.lastSeen || '', meraki_ip: meraki.ip || '', meraki_mac: meraki.mac || '', // New Meraki port / Sticky MAC fields meraki_portType: meraki.portType || 'N/A', meraki_portEnabled: meraki.portEnabled != null ? (typeof meraki.portEnabled === 'boolean' ? (meraki.portEnabled ? 'Enabled' : 'Disabled') : meraki.portEnabled) // handles 'Error' / 'N/A' : 'N/A', meraki_accessPolicyType: meraki.accessPolicyType || 'N/A', meraki_stickyMacEnabled: meraki.stickyMacEnabled === true ? 'true' : 'false', // explicit string for CSV clarity meraki_stickyMacList: stickyMacListStr, meraki_stickyMacAllowListLimit: meraki.stickyMacAllowListLimit != null ? meraki.stickyMacAllowListLimit : '', meraki_stickyMacCount: meraki.stickyMacCount != null ? meraki.stickyMacCount : '', meraki_portError: meraki.portError || '' // only present if fetch failed }; }); // Define all CSV column headers (order matters for output) const fields = [ 'device_id', 'device_friendly_name', 'device_enrollment_user_name', '_device_platform', 'device_os_version', 'device_last_seen_utc', 'device_enrollment_status', 'device_model_name', '_device_mac_address', 'device_mac_address', 'meraki_deviceName', 'meraki_switchport', 'meraki_vlan', 'meraki_status', 'meraki_connection', 'meraki_lastSeen', 'meraki_ip', 'meraki_mac', // New fields 'meraki_portType', 'meraki_accessPolicyType', 'meraki_portEnabled', // ← NEW 'meraki_stickyMacEnabled', 'meraki_stickyMacList', 'meraki_stickyMacAllowListLimit', 'meraki_stickyMacCount', 'meraki_portError' ]; const opts = { fields }; const parser = new Parser(opts); const csv = parser.parse(flattenedData); // Save to output CSV const csvFile = 'enriched-meraki-output.csv'; fs.writeFileSync(csvFile, csv); console.log(`CSV file created: ${csvFile}`); console.log(`Total rows processed: ${flattenedData.length}`);