import { createSDTFEngine, SDTFEngine } from '@specifyapp/specify-design-token-format'; import { ParserToolbox } from '../../../parsersEngine/ParserToolbox.js'; import type { ChangeCaseParserDefinition, ChangeCaseParserOptions } from './definition.js'; import { camelCase, capitalCase, constantCase, kebabCase, noCase, pascalCase, pascalSnakeCase, pathCase, sentenceCase, snakeCase, trainCase, } from 'change-case'; import { SpecifyError, specifyErrors } from '../../../errors/index.js'; import { getSdtfQuery } from '../../utils/getSdtfQuery.js'; import { DeriveBuiltInParserHandlerFromDefinition } from '../../internals/createBuiltInParserDefinition.js'; /** * @internal */ export const changeCaseMap = { camelCase: camelCase, capitalCase: capitalCase, constantCase: constantCase, kebabCase: kebabCase, noCase: noCase, pascalCase: pascalCase, pascalSnakeCase: pascalSnakeCase, pathCase: pathCase, sentenceCase: sentenceCase, snakeCase: snakeCase, trainCase: trainCase, } as const; export const changeCaseHandler: DeriveBuiltInParserHandlerFromDefinition< ChangeCaseParserDefinition > = async (previousDataBox, toolbox, parserOptions, _, _context) => { let sdtfEngine: SDTFEngine; switch (previousDataBox.type) { case 'SDTF': { sdtfEngine = createSDTFEngine(previousDataBox.graph, previousDataBox.metadata); break; } case 'SDTF Engine': { sdtfEngine = previousDataBox.engine; break; } default: { throw new SpecifyError({ errorKey: specifyErrors.PARSERS_ENGINE_INVALID_INPUT_TYPE.errorKey, publicMessage: `The input type "${ (previousDataBox as any).type }" is not supported by the change-case parser.`, }); } } changeCaseInner(sdtfEngine, parserOptions, toolbox); return { type: 'SDTF Engine', engine: sdtfEngine, }; }; export function changeCaseInner( sdtfEngine: SDTFEngine, parserOptions: ChangeCaseParserOptions, toolbox: ParserToolbox, ) { const { change: maybeChange, toCase, applyTo } = parserOptions; const actualChange = maybeChange ?? 'names'; const transform = changeCaseMap[toCase]; if (!transform) { throw new SpecifyError({ errorKey: specifyErrors.PARSERS_ENGINE_RULE_EXECUTION_FAILED.errorKey, publicMessage: `The change-case parser does not support the case ${toCase}.`, }); } const query = getSdtfQuery(applyTo, { selectChildren: true, }); sdtfEngine.query.run(query).forEach(node => { if (actualChange === 'names') { try { node.rename(transform(node.name)); } catch (error: any) { if (error && 'errorKey' in error && error.errorKey === 'SDTF_PATH_ALREADY_TAKEN') { toolbox.populateMessage({ type: 'warning', errorKey: specifyErrors.PARSERS_ENGINE_RULE_EXECUTION_FAILED.errorKey, content: error.message, location: { type: 'SDTF', graphPath: node.path.toArray(), valuePath: [], targetMode: null, localMode: null, }, }); return; } throw error; } } else if (actualChange === 'modes') { try { if (node.isCollection) { node.allowedModes.forEach(mode => { node.renameMode(mode, transform(mode)); }); } else if (node.isToken) { node.modes.forEach(mode => { node.renameMode(mode, transform(mode)); }); } } catch (error: any) { if (error && 'errorKey' in error && error.errorKey === 'SDTF_MODE_RENAME_FAILED') { toolbox.populateMessage({ type: 'warning', errorKey: specifyErrors.PARSERS_ENGINE_RULE_EXECUTION_FAILED.errorKey, content: error.message, location: { type: 'SDTF', graphPath: node.path.toArray(), valuePath: [], targetMode: null, localMode: null, }, }); return; } throw error; } } }); }