Last active
March 8, 2023 12:31
-
-
Save pkuczynski/2392b3392e790fc69627f4a1e43171f1 to your computer and use it in GitHub Desktop.
Sets react-intl defaultMessage based on existing translation file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Requires `npm i jscodeshift @types/jscodeshift` | |
// Run: `npx jscodeshift -t react-intl-default-message.ts src/**/*.ts` | |
import en from './src/i18n/locales/en.json' | |
export const parser = 'tsx' | |
export default function transformer(file, api) { | |
const j = api.jscodeshift | |
const messageDesc = (nodePath) => { | |
const { node } = nodePath | |
const [messageDescriptor, ...otherArguments] = node.arguments | |
const { properties } = messageDescriptor | |
if (!properties) { | |
return node | |
} | |
const id = properties.find(p => p.key.name === 'id') | |
const description = properties.find(p => p.key.name === 'description') | |
const defaultMessage = en[id.value.value] | |
const object = j.objectExpression([ | |
j.property( | |
'init', | |
j.identifier('id'), | |
j.literal(id.value.value) | |
), | |
j.property( | |
'init', | |
j.identifier('defaultMessage'), | |
j.literal(defaultMessage) | |
), | |
description && j.property( | |
'init', | |
j.identifier('description'), | |
j.literal(description.value.value) | |
) | |
].filter(Boolean)) | |
node.arguments = [object, ...otherArguments] | |
return node | |
} | |
const jsxMessageDesc = (nodePath) => { | |
const { node } = nodePath | |
const { attributes } = node.openingElement | |
const id = attributes.find(p => p.name.name === 'id') | |
// const description = properties.find(p => p.name === 'description') | |
// const values = properties.find(p => p.name === 'values') | |
const defaultMessage = attributes.find(p => p.name.name === 'defaultMessage') | |
if (defaultMessage) { | |
defaultMessage.value.value = en[id.value.value] | |
} | |
else { | |
attributes.push(j.jsxAttribute( | |
j.jsxIdentifier('defaultMessage'), | |
j.literal(en[id.value.value]) | |
)) | |
} | |
return node | |
} | |
const root = j(file.source) | |
const intlFormatMessage = root | |
.find(j.CallExpression, { | |
callee: { | |
type: 'MemberExpression', | |
property: { | |
name: 'formatMessage' | |
} | |
} | |
}) | |
const formatMessage = root | |
.find(j.CallExpression, { callee: { name: 'formatMessage' } }) | |
const defineMessage = root | |
.find(j.CallExpression, { callee: { name: 'defineMessage' } }) | |
const jsxFormattedMessage = root.findJSXElements('FormattedMessage') | |
const jsxFormattedHtmlMessage = root.findJSXElements('FormattedHtmlMessage') | |
const found = intlFormatMessage.length + | |
formatMessage.length + | |
defineMessage.length + | |
jsxFormattedMessage.length + | |
jsxFormattedHtmlMessage.length | |
if (found === 0) { | |
return file.source | |
} | |
if (intlFormatMessage.length > 0) { | |
intlFormatMessage.replaceWith(messageDesc) | |
} | |
if (formatMessage.length > 0) { | |
formatMessage.replaceWith(messageDesc) | |
} | |
if (defineMessage.length > 0) { | |
defineMessage.replaceWith(messageDesc) | |
} | |
if (jsxFormattedMessage.length > 0) { | |
jsxFormattedMessage.replaceWith(jsxMessageDesc) | |
} | |
if (jsxFormattedHtmlMessage.length > 0) { | |
jsxFormattedHtmlMessage.replaceWith(jsxMessageDesc) | |
} | |
return root.toSource({ quote: 'single' }) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment