/** * codemod for fixing backslash \escapes to quote 'escapes' in MessageFormat strings * * messageformat-parser v3 (used by messageformat v2) no longer allows for the * characters #{}\ to be escaped with a \ prefix, as well as dropping support * for \u0123 character escapes. This codemod can help fix your MessageFormat * JSON sources to use ICU MessageFormat 'escapes' instead. * * To enable jscodeshift to handle JSON input, you'll need to have an * appropriate parser available: * * npm install --no-save json-estree-ast * * Then apply the codemod: * * npx jscodeshift -t node_modules/messageformat-parser/codemod-fix-backslash-escapes.js [input] * * If your input includes doubled single quotes '', they will need to be * escaped as well; use the command-line option --doubleSingleQuotes=true to * enable that. Note that applying the codemod with that option multiple times * will double your doubled quotes each time. */ let doubleSingleQuotes = false; const fixEscapes = node => { if (node.type !== 'Literal' || typeof node.value !== 'string') return; if (doubleSingleQuotes) node.value = node.value.replace(/''+/g, '$&$&'); node.value = node.value.replace( /('*)\\([#{}\\]|u[0-9a-f]{4})('*)/g, (_, start, char, end) => { switch (char[0]) { case 'u': { const code = parseInt(char.slice(1), 16); return start + String.fromCharCode(code) + end; } case '\\': return `${start}\\${end}`; default: // Assume multiple ' are already escaped if (start === "'") start = "''"; if (end === "'") end = "''"; return `'${start}${char}${end}'`; } } ); }; module.exports = ({ source }, { jscodeshift: j }, options) => { if (options.doubleSingleQuotes) doubleSingleQuotes = true; const ast = j(source); ast.find(j.Property).forEach(({ value: { value } }) => fixEscapes(value)); ast .find(j.ArrayExpression) .forEach(({ value: { elements } }) => elements.forEach(fixEscapes)); return ast.toSource(); }; module.exports.parser = require('json-estree-ast');