This repository has been archived by the owner on Dec 17, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
codemod-fix-backslash-escapes.js
57 lines (53 loc) · 2.02 KB
/
codemod-fix-backslash-escapes.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**
* 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')