import { createSDTFEngine, SDTFEngine } from '@specifyapp/specify-design-token-format'; import type { FilterParserDefinition } from './definition.js'; import { SpecifyError, specifyErrors } from '../../../errors/index.js'; import { DeriveBuiltInParserHandlerFromDefinition } from '../../internals/createBuiltInParserDefinition.js'; export const filterHandler: DeriveBuiltInParserHandlerFromDefinition< FilterParserDefinition > = async (previousResult, toolbox, parserOptions, _, _context) => { let sdtfEngine: SDTFEngine; switch (previousResult.type) { case 'SDTF': { sdtfEngine = createSDTFEngine(previousResult.graph, previousResult.metadata); break; } case 'SDTF Engine': { sdtfEngine = previousResult.engine; break; } default: { throw new SpecifyError({ errorKey: specifyErrors.PARSERS_ENGINE_INVALID_INPUT_TYPE.errorKey, publicMessage: `The input type ${ (previousResult as any).type } is not supported by the filter parser.`, }); } } const { query, resolveAliases, allowUnresolvableAliases } = parserOptions; if (resolveAliases !== true && allowUnresolvableAliases !== undefined) { throw new SpecifyError({ errorKey: specifyErrors.PARSERS_ENGINE_INVALID_OPTION.errorKey, publicMessage: `The option "allowUnresolvableAliases" cannot be used without the option "resolveAliases" being "true".`, }); } if (resolveAliases === true) { sdtfEngine.query.getAllTokenStates().forEach(tokenState => { if (tokenState.isFullyResolvable === false && allowUnresolvableAliases === false) { throw new SpecifyError({ errorKey: specifyErrors.PARSERS_ENGINE_RULE_EXECUTION_FAILED.errorKey, publicMessage: `Allow unresolvable aliases matched :: Token "${tokenState.path.toString()}" has unresolvable references: ${tokenState.aliases .reduce>((msgs, alias) => { if (alias.status === 'unresolvable') { msgs.push(`"${alias.to.treePath.toString()}"`); } return msgs; }, []) .join(', ')}.`, }); } tokenState.resolveValueAliases(); }); } const result = sdtfEngine.query.run(query); if (parserOptions.failOnMutate && result.isContinuous === false) { throw new SpecifyError({ errorKey: specifyErrors.PARSERS_ENGINE_RULE_EXECUTION_FAILED.errorKey, publicMessage: `The query returned more than one graph, thus it cannot be evaluated further. Remove "failOnMutate" to return a merged graph.`, }); } if (parserOptions.failOnMutate) { const details = result.render(); if (details.length === 0) { toolbox.populateMessage({ type: 'warning', errorKey: specifyErrors.PARSERS_ENGINE_RULE_EXECUTION_FAILED.errorKey, content: `The query does not match any node.`, }); } return { type: 'SDTF Engine', engine: createSDTFEngine(details.length > 0 ? details[0].sdtf : {}), }; } const dedupe = parserOptions.deduplicate && typeof parserOptions.deduplicate === 'function' ? parserOptions.deduplicate : parserOptions.deduplicate === true ? true : undefined; const sdtf = result.merge(dedupe).treeState.toJSON(); return { type: 'SDTF Engine', engine: createSDTFEngine(sdtf), }; };