import { makeFilePath } from './fileSystem.js'; import { replaceFile } from './replaceFile.js'; import { writeBufferTextEncodedToFile } from './writeBufferTextEncodedToFile.js'; import { writeStreamToFile } from './writeStreamToFile.js'; import { fetch } from 'undici'; import { ParserOutput } from '../parsersEngine/index.js'; import { SpecifyError, specifyErrors } from '../errors/index.js'; const stringContentType = ['text/plain', 'application/json', 'image/svg+xml']; const fetchFile = async (url: string) => { try { const response = await fetch(url); if (response.status !== 200) { throw new Error(); } return response; } catch (err) { console.warn(`Failed to fetch file from ${url}.`); } }; export async function writeParserOutputToFileSystem( output: ParserOutput, options?: { directoryPath?: string; }, ) { const writtenFilePaths = new Set(); const directoryPath = options?.directoryPath ?? ''; switch (output.type) { case 'files': { for (const file of output.files) { const filePath = makeFilePath(directoryPath, file.path); writtenFilePaths.add(filePath); if (file.content.type === 'url') { const response = await fetchFile(file.content.url); if (response) { const contentType = response.headers.get('content-type'); if (contentType && stringContentType.includes(contentType)) { await writeBufferTextEncodedToFile( filePath, Buffer.from(await response.arrayBuffer()), ); } else if (response.body) { await writeStreamToFile(filePath, response.body); } } } else { await replaceFile(filePath, file.content.text); } } break; } case 'JSON': { const filePath = makeFilePath(directoryPath, 'json-tokens.json'); writtenFilePaths.add(filePath); await replaceFile(filePath, JSON.stringify(output.json, null, 2)); break; } case 'SDTF': { const filePath = makeFilePath(directoryPath, 'sdtf-tokens.json'); writtenFilePaths.add(filePath); await replaceFile(filePath, JSON.stringify(output.graph, null, 2)); break; } case 'text': { const filePath = makeFilePath(directoryPath, 'text-tokens.txt'); writtenFilePaths.add(filePath); await replaceFile(filePath, output.text); break; } default: { throw new SpecifyError({ errorKey: specifyErrors.NODE_UTILS_UNSUPPORTED_OUTPUT_TYPE.errorKey, publicMessage: `The Pipe Engine output type ${ // @ts-expect-error - expected to be never at this point output.type } is not supported by the writePipeEngineResultToFileSystem function.`, }); } } return Array.from(writtenFilePaths); }