UNPKG

@kitapp-developers/mongo-import-export

Version:

A modern CLI tool to import/export MongoDB collections to and from JSON or CSV — great for backups, migrations, and local development.

135 lines (134 loc) 4.38 kB
import { ObjectId } from 'mongodb'; import { logger } from '../utils/logger.js'; import { isValidObjectId, isValidDate } from '../utils/validate.js'; export function convertExtendedJSON(doc) { if (Array.isArray(doc)) { return doc.map(convertExtendedJSON); } if (doc !== null && typeof doc === 'object') { if (doc['$oid']) { logger.debug(`Converting $oid: ${doc['$oid']} to ObjectId`); return new ObjectId(doc['$oid']); } if (doc['$date'] && typeof doc['$date'] === 'object' && doc['$date']['$numberLong']) { logger.debug(`Converting $date.$numberLong: ${doc['$date']['$numberLong']} to Date`); return new Date(Number(doc['$date']['$numberLong'])); } if (doc['$date'] && typeof doc['$date'] === 'string') { logger.debug(`Converting $date: ${doc['$date']} to Date`); return new Date(doc['$date']); } if (doc['$numberInt']) { logger.debug(`Converting $numberInt: ${doc['$numberInt']} to Number`); return Number(doc['$numberInt']); } const result = {}; for (const [key, value] of Object.entries(doc)) { if (typeof value === 'string') { if (key === '_id' && isValidObjectId(value)) { result[key] = new ObjectId(value); } else if (isValidDate(value)) { result[key] = new Date(value); } else { result[key] = value; } } else { result[key] = convertExtendedJSON(value); } } return result; } return doc; } export function convertCSVRow(row) { const result = {}; for (let [key, value] of Object.entries(row)) { if (value === null || value === '') { result[key] = value; continue; } const stringValue = String(value); if (key === '_id' && isValidObjectId(stringValue)) { result[key] = new ObjectId(stringValue); continue; } if ((key.endsWith('At') || key.endsWith('Dt')) && isValidDate(stringValue)) { result[key] = new Date(stringValue); continue; } if (isValidObjectId(stringValue)) { result[key] = new ObjectId(stringValue); } else if (isValidDate(stringValue)) { result[key] = new Date(stringValue); } else if (!isNaN(Number(stringValue)) && stringValue.trim() !== '') { result[key] = Number(stringValue); } else if (stringValue.toLowerCase() === 'true' || stringValue.toLowerCase() === 'false') { result[key] = (stringValue.toLowerCase() === 'true'); } else { try { const parsed = JSON.parse(stringValue); result[key] = convertExtendedJSON(parsed); } catch (e) { result[key] = stringValue; } } } return result; } /** * @param documents * @returns */ export function prepareForCSVExport(documents) { return documents.map(doc => { const newDoc = {}; for (const key in doc) { const value = doc[key]; if (value instanceof ObjectId) { newDoc[key] = value.toHexString(); } else if (value instanceof Date) { newDoc[key] = value.toISOString(); } else if (typeof value === 'object' && value !== null) { newDoc[key] = JSON.stringify(value); } else { newDoc[key] = value; } } return newDoc; }); } /** * * @param doc * @returns */ export function prepareForJSONExport(doc) { if (Array.isArray(doc)) { return doc.map(prepareForJSONExport); } if (doc instanceof ObjectId) { return { $oid: doc.toHexString() }; } if (doc instanceof Date) { return { $date: doc.toISOString() }; } if (doc !== null && typeof doc === 'object') { const result = {}; for (const [key, value] of Object.entries(doc)) { result[key] = prepareForJSONExport(value); } return result; } return doc; }