import { createSDTFEngine, SDTFEngine } from '@specifyapp/specify-design-token-format'; import { SpecifyError, specifyErrors } from '../../../errors/index.js'; import { DeriveBuiltInParserHandlerFromDefinition } from '../../internals/createBuiltInParserDefinition.js'; import { PostReplaceStringParserParserDefinition } from './definition.js'; export const postReplaceStringHandler: DeriveBuiltInParserHandlerFromDefinition< PostReplaceStringParserParserDefinition > = async (previousDataBox, toolbox, parserOptions, outputConfiguration) => { const currentOutput = toolbox.output; if (currentOutput === null) { throw new SpecifyError({ errorKey: specifyErrors.PARSERS_ENGINE_INVALID_OUTPUTS.errorKey, publicMessage: `The post-replace-string 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 post-replace-string 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 regex = typeof parserOptions.matchFileContent === 'string' ? new RegExp(parserOptions.matchFileContent, 'g') : new RegExp( parserOptions.matchFileContent.pattern, parserOptions.matchFileContent.flags, ); const formattedContent = file.content.text.replaceAll(regex, parserOptions.replaceBy); 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 processing 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 post-replace-string 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 post-replace-string parser received a "${previousDataBox.type}" input type causing the next parser to receive an empty SDTF engine.`, }); } } return { type: 'SDTF Engine', engine: sdtfEngine, }; };