import { Config, optimize } from 'svgo'; import { specifyErrors, SpecifyError } from '../../../errors/index.js'; import { VectorDataBox } from '../../../parsersEngine/index.js'; import { generateVectorDataBoxAndPullSvgsContent, pullSvgContent, } from '../../shared/to-svg-file/generateVectorDataBoxFiles.js'; import { DeriveBuiltInParserHandlerFromDefinition } from '../../internals/createBuiltInParserDefinition.js'; import type { SvgoParserDefinition } from './definition.js'; export const svgoHandler: DeriveBuiltInParserHandlerFromDefinition = async ( previous, toolbox, parserOptions, outputOptions, ) => { let vectorAssets: VectorDataBox['assets']; switch (previous.type) { case 'vector': { vectorAssets = await Promise.all(previous.assets.map(v => pullSvgContent(v, toolbox))); break; } case 'SDTF': { vectorAssets = (await generateVectorDataBoxAndPullSvgsContent(previous.graph, toolbox)) .assets; break; } case 'SDTF Engine': { vectorAssets = (await generateVectorDataBoxAndPullSvgsContent(previous.engine, toolbox)) .assets; break; } default: throw new SpecifyError({ errorKey: specifyErrors.PARSERS_ENGINE_INVALID_PARSER_INPUT.errorKey, publicMessage: `${(previous as any).type} is not a valid input for the svgo parser.`, }); } if (outputOptions?.type && outputOptions?.type !== 'directory') { throw new SpecifyError({ errorKey: specifyErrors.PARSERS_ENGINE_INVALID_OUTPUT_TYPE.errorKey, publicMessage: `The svgo parser only supports the directory output.`, }); } const shouldCreateDirectory = outputOptions?.type === 'directory'; const svgoOptions = (parserOptions?.svgo as Config) ?? undefined; const optimizedAssets = (await Promise.all( vectorAssets.flatMap(asset => { if (asset.format === 'pdf') { return []; } if (!asset.vector) { throw new SpecifyError({ errorKey: specifyErrors.PARSERS_ENGINE_PARSER_EXECUTION_FAILED.errorKey, publicMessage: `The content of the vector "${asset.path.join('.')}" is supposed to be retrieved before`, }); } try { asset.vector = optimize(asset.vector, svgoOptions).data; } catch (err) { toolbox.populateMessage({ type: 'warning', content: 'The SVG file could not be optimized. It will be return without optimization.', errorKey: specifyErrors.PARSERS_ENGINE_PARTIAL_OUTPUT.errorKey, }); } return [asset]; }), )) as Array>; if (shouldCreateDirectory) { toolbox.populateOutput({ type: 'files', files: optimizedAssets.map(asset => { const hasMoreThan1Mode = Object.keys(asset.token.$value).length > 1; return { path: `${outputOptions.directoryPath}/${asset.path.join('/')}${ hasMoreThan1Mode ? `-${asset.mode}` : '' }.svg`, content: { type: 'text' as const, text: asset.vector, }, }; }), }); } return { type: 'vector', assets: optimizedAssets, }; };