import { SDTFEngine, createSDTFEngine } from '@specifyapp/specify-design-token-format'; import { SpecifyError, specifyErrors } from '../../../errors/index.js'; import { DeriveBuiltInParserHandlerFromDefinition } from '../../internals/createBuiltInParserDefinition.js'; import { formatWithPrettier } from '../../shared/prettier/formatWithPrettier.js'; import { PrettierParserDefinition } from './definition.js'; export const prettierHandler: DeriveBuiltInParserHandlerFromDefinition< PrettierParserDefinition > = async (previousDataBox, toolbox, parserOptions, outputConfiguration) => { const currentOutput = toolbox.output; if (currentOutput === null) { throw new SpecifyError({ errorKey: specifyErrors.PARSERS_ENGINE_INVALID_OUTPUTS.errorKey, publicMessage: `The prettier parser requires an output to have been generated within the pipeline "${toolbox.pipelineName}".`, }); } let nextOutput = currentOutput; switch (currentOutput.type) { case 'files': { nextOutput = { type: 'files', files: [], }; for (const file of currentOutput.files) { if (file.content.type !== 'text') { toolbox.populateMessage({ type: 'warning', errorKey: specifyErrors.PARSERS_ENGINE_INVALID_OUTPUT_TYPE.errorKey, content: `the file content type "${file.content.type}" is not supported by the prettier parser. The file will be ignored.`, }); nextOutput.files.push(file); continue; } // Filter on the output file path if specified if (parserOptions?.matchOutputFilePath) { if (!new RegExp(parserOptions.matchOutputFilePath).test(file.path)) { nextOutput.files.push(file); continue; } } try { const formattedContent = await formatWithPrettier(file.content.text, { filepath: file.path, ...(parserOptions?.prettierOptions as any), }); nextOutput.files.push({ path: file.path, content: { type: 'text', text: formattedContent, }, }); } catch (error) { const message = typeof error === 'object' && error !== null && 'message' in error ? error.message : 'Unknown error'; toolbox.populateMessage({ type: 'warning', errorKey: specifyErrors.PARSERS_ENGINE_POST_PROCESS_FAILED.errorKey, content: `An error occurred while formatting the file "${file.path}": ${message}`, }); nextOutput.files.push(file); } } break; } default: { throw new SpecifyError({ errorKey: specifyErrors.PARSERS_ENGINE_INVALID_OUTPUT_TYPE.errorKey, publicMessage: `The output type "${currentOutput.type}" is not supported by the prettier parser.`, }); } } toolbox.updateOutput(() => nextOutput); let sdtfEngine: SDTFEngine; switch (previousDataBox.type) { case 'SDTF': { sdtfEngine = createSDTFEngine(previousDataBox.graph); break; } case 'SDTF Engine': { sdtfEngine = previousDataBox.engine; break; } default: { sdtfEngine = createSDTFEngine({}); toolbox.populateMessage({ type: 'warning', errorKey: specifyErrors.PARSERS_ENGINE_INVALID_INPUT_TYPE.errorKey, content: `The prettier parser received a "${previousDataBox.type}" input type causing the next parser to receive an empty SDTF engine.`, }); } } return { type: 'SDTF Engine', engine: sdtfEngine, }; };