Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | import fs from 'fs/promises';
import { basename, resolve } from 'path';
import { json2csv, csv2json, Json2CsvOptions } from 'json-2-csv';
import yaml from 'yaml';
import { SupportedFileFormat } from '../types.js';
/**
* Gets the full output path for a file
* @param filename Name of the file
* @param outputDir Directory to write the file to
* @returns Full path to the file
*/
export function getOutputPath(filename: string, outputDir: string = process.cwd()): string {
return resolve(outputDir, filename);
}
/**
* Reads a file and returns its contents as a string
* @param path Path to the file
* @returns Promise resolving to the file contents
*/
export async function readFile(path: string): Promise<string> {
try {
return await fs.readFile(path, 'utf8');
} catch (error) {
throw new Error(`Failed to read file at ${path}: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Writes data to a file
* @param filename Name of the file to write
* @param data Data to write
* @param outputDir Directory to write the file to
* @returns Promise resolving when write is complete
*/
export async function writeFile(filename: string, data: string, outputDir: string = process.cwd()): Promise<void> {
try {
const path = getOutputPath(filename, outputDir);
await fs.writeFile(path, data, 'utf8');
} catch (error) {
throw new Error(`Failed to write file: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Reads a JSON file and parses its contents
* @param path Path to the JSON file
* @returns Promise resolving to the parsed JSON data
*/
export async function readJSON<T>(path: string): Promise<T> {
try {
const content = await readFile(path);
return JSON.parse(content) as T;
} catch (error) {
throw new Error(`Failed to parse JSON file at ${path}: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Writes data as JSON to a file
* @param filename Name of the file to write
* @param data Data to write as JSON
* @param outputDir Directory to write the file to
* @param pretty Whether to format the JSON with indentation
* @returns Promise resolving when write is complete
*/
export async function writeJSON(filename: string, data: any, outputDir: string = process.cwd(), pretty: boolean = true): Promise<void> {
try {
filename = `${filename}.json`;
const content = JSON.stringify(data, null, pretty ? 2 : undefined);
await writeFile(filename, content, outputDir);
} catch (error) {
throw new Error(`Failed to write JSON file: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Writes data as YAML to a file
* @param filename Name of the file to write
* @param data Data to write as YAML
* @param outputDir Directory to write the file to
* @returns Promise resolving when write is complete
*/
export async function writeYAML(filename: string, data: any, outputDir: string = process.cwd()): Promise<void> {
try {
filename = `${filename}.yml`;
const content = yaml.stringify(data);
await writeFile(filename, content, outputDir);
} catch (error) {
throw new Error(`Failed to write YAML file: ${error instanceof Error ? error.message : String(error)}`);
}
}
// create single method to write data to a file in the requested format
export async function writeData(filename: string, data: any, outputDir: string, format: SupportedFileFormat, options?: Json2CsvOptions): Promise<void> {
switch (format) {
case 'yaml':
await writeYAML(filename, data, outputDir);
break;
case 'csv':
await writeCSV(filename, data, outputDir, {
prependHeader: false,
arrayIndexesAsKeys: false,
...options
});
break;
default:
await writeJSON(filename, data, outputDir);
break;
}
}
/**
* Checks if a file exists
* @param path Path to check
* @returns Promise resolving to true if file exists
*/
export async function exists(path: string): Promise<boolean> {
try {
await fs.access(path);
return true;
} catch {
return false;
}
}
/**
* Converts a JSON array to CSV string
* @param data Array of objects to convert to CSV
* @param options Optional configuration for json-2-csv conversion
* @returns CSV string
*/
export function jsonToCSV(data: any[], options?: Json2CsvOptions): string {
if (!Array.isArray(data) || data.length === 0) {
throw new Error('Input must be a non-empty array of objects');
}
try {
return json2csv(data, {
prependHeader: true,
expandNestedObjects: true,
...options
});
} catch (error) {
throw new Error(`Failed to convert JSON to CSV: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Writes JSON data as CSV to a file
* @param filename Name of the file to write
* @param data Array of objects to write as CSV
* @param outputDir Directory to write the file to
* @param options Optional configuration for json-2-csv conversion
* @returns Promise resolving when write is complete
*/
export async function writeCSV(
filename: string,
data: any,
outputDir: string = process.cwd(),
options?: Json2CsvOptions
): Promise<void> {
try {
filename = `${filename}.csv`;
let safeData = Array.isArray(data) ? data : Object.entries(data);
//if data is array of strings, csv should be a single column
if (Array.isArray(data) && data.every(item => typeof item === 'string')) {
safeData = data.map(item => [item]);
}
const csvContent = jsonToCSV(safeData, options);
await writeFile(filename, csvContent, outputDir);
} catch (error) {
throw new Error(`Failed to write CSV file: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Reads a CSV file and converts it to a JSON array
* @param path Path to the CSV file
* @param options Optional configuration for csv-2-json conversion
* @returns Promise resolving to array of objects
*/
export async function readCSV<T>(path: string, options?: any): Promise<T[]> {
try {
const content = await readFile(path);
return csv2json(content, {
trimFieldValues: true,
trimHeaderFields: true,
...options
}) as T[];
} catch (error) {
throw new Error(`Failed to parse CSV file at ${path}: ${error instanceof Error ? error.message : String(error)}`);
}
}
export async function copyFile(sourceFilePath: string, outputDir: string = process.cwd()) {
const sourceFileContent = await readFile(sourceFilePath);
await writeFile(basename(sourceFilePath), sourceFileContent, outputDir);
} |