UNPKG

nylas

Version:

A NodeJS wrapper for the Nylas REST API for email, contacts, and calendar.

118 lines (117 loc) 4.11 kB
import { camelCase, snakeCase } from 'change-case'; import * as fs from 'fs'; import * as path from 'path'; import * as mime from 'mime-types'; import { Readable } from 'stream'; export function createFileRequestBuilder(filePath) { const stats = fs.statSync(filePath); const filename = path.basename(filePath); const contentType = mime.lookup(filePath) || 'application/octet-stream'; const content = fs.createReadStream(filePath); return { filename, contentType, content, size: stats.size, }; } /** * Converts a ReadableStream to a base64 encoded string. * @param stream The ReadableStream containing the binary data. * @returns The stream base64 encoded to a string. */ function streamToBase64(stream) { return new Promise((resolve, reject) => { const chunks = []; stream.on('data', (chunk) => { chunks.push(chunk); }); stream.on('end', () => { const base64 = Buffer.concat(chunks).toString('base64'); resolve(base64); }); stream.on('error', err => { reject(err); }); }); } /** * Encodes the content of each attachment stream to base64. * @param attachments The attachments to encode. * @returns The attachments with their content encoded to base64. */ export async function encodeAttachmentStreams(attachments) { return await Promise.all(attachments.map(async (attachment) => { const base64EncodedContent = attachment.content instanceof Readable ? await streamToBase64(attachment.content) : attachment.content; return { ...attachment, content: base64EncodedContent }; // Replace the stream with its base64 string })); } /** * Applies the casing function and ensures numeric parts are preceded by underscores in snake_case. * @param casingFunction The original casing function. * @param input The string to convert. * @returns The converted string. */ function applyCasing(casingFunction, input) { const transformed = casingFunction(input); if (casingFunction === snakeCase) { return transformed.replace(/(\d+)/g, '_$1'); } else { return transformed.replace(/_+(\d+)/g, (match, p1) => p1); } } /** * A utility function that recursively converts all keys in an object to a given case. * @param obj The object to convert * @param casingFunction The function to use to convert the keys * @param excludeKeys An array of keys to exclude from conversion * @returns The converted object * @ignore Not for public use. */ function convertCase(obj, casingFunction, excludeKeys) { const newObj = {}; for (const key in obj) { if (excludeKeys?.includes(key)) { newObj[key] = obj[key]; } else if (Array.isArray(obj[key])) { newObj[applyCasing(casingFunction, key)] = obj[key].map(item => { if (typeof item === 'object') { return convertCase(item, casingFunction); } else { return item; } }); } else if (typeof obj[key] === 'object' && obj[key] !== null) { newObj[applyCasing(casingFunction, key)] = convertCase(obj[key], casingFunction); } else { newObj[applyCasing(casingFunction, key)] = obj[key]; } } return newObj; } /** * A utility function that recursively converts all keys in an object to camelCase. * @param obj The object to convert * @param exclude An array of keys to exclude from conversion * @returns The converted object * @ignore Not for public use. */ export function objKeysToCamelCase(obj, exclude) { return convertCase(obj, camelCase, exclude); } /** * A utility function that recursively converts all keys in an object to snake_case. * @param obj The object to convert * @param exclude An array of keys to exclude from conversion * @returns The converted object */ export function objKeysToSnakeCase(obj, exclude) { return convertCase(obj, snakeCase, exclude); }