Skip to content

Commit

Permalink
feat: allow extract to work with i18n._ calls not created from macro (#…
Browse files Browse the repository at this point in the history
…1309)

Co-authored-by: Mitchell Hill <mitchell.hill@capitalontap.com>
  • Loading branch information
mitchjhill and Mitchell Hill authored Dec 8, 2022
1 parent c863322 commit 90be171
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 24 deletions.
64 changes: 40 additions & 24 deletions packages/babel-plugin-extract-messages/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,28 @@ function extractStringContatentation(t, node, error): string {
}
}

function extractCommentString(t, path, valuePath, valueObj): string {
if (t.isStringLiteral(valueObj)) {
// Comment is a single line string
return valueObj.value;
}

// Comment is a multi-line string.
const errorIfNotAString = path
.get(valuePath)
.buildCodeFrameError("Only strings are supported as comments.")

if (t.isBinaryExpression(valueObj)) {
return extractStringContatentation(
t,
valueObj,
errorIfNotAString
)
} else {
throw errorIfNotAString
}
}

export default function ({ types: t }) {
let localTransComponentName

Expand Down Expand Up @@ -220,25 +242,32 @@ export default function ({ types: t }) {
)
}
)
if (!hasComment) return


const isNonMacroI18n = isI18nMethod(path.node.callee) && !hasComment && path.node.arguments[0] && !path.node.arguments[0].leadingComments;
if (!hasComment && !isNonMacroI18n) return;
const props = {
id: path.node.arguments[0].value,
}
id: path.node.arguments[0].value
};

if (!props.id) {
console.warn("Missing message ID, skipping.")
console.warn("Missing message ID, skipping.");
console.warn(generate(path.node).code)
return
return;
}

const copyOptions = ["message", "comment", "context"]

if (t.isObjectExpression(path.node.arguments[2])) {
path.node.arguments[2].properties.forEach((property) => {
if (!copyOptions.includes(property.key.name)) return
path.node.arguments[2].properties.forEach(({key, value}, i) => {
if (!copyOptions.includes(key.name)) return

let valueToExtract = value.value;

if (key.name === "comment") {
valueToExtract = extractCommentString(t, path, `arguments.2.properties.${i}.value`, value);
}

props[property.key.name] = property.value.value
props[key.name] = valueToExtract
})
}

Expand Down Expand Up @@ -298,21 +327,8 @@ export default function ({ types: t }) {
// By default, the value is just the string value of the object property.
let valueToExtract = value.value;

if (key.name === "comment" && !t.isStringLiteral(value)) {
// Comments can be single or multi-line strings.
const errorIfNotAString = path
.get(`properties.${i}.value`)
.buildCodeFrameError("Only strings are supported as comments.")

if (t.isBinaryExpression(value)) {
valueToExtract = extractStringContatentation(
t,
value,
errorIfNotAString
)
} else {
throw errorIfNotAString
}
if (key.name === "comment") {
valueToExtract = extractCommentString(t, path, `properties.${i}.value`, value);
} else if (key.name === "id") {
const isIdLiteral = !value.value && t.isTemplateLiteral(value)
if (isIdLiteral) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,72 @@ Object {
}
`;

exports[`@lingui/babel-plugin-extract-messages should extract all messages from JS files (without macros or i18n comments) 1`] = `
Object {
Context1: Object {
Some id: Object {
extractedComments: Array [],
origin: Array [
Array [
js-without-macros-or-comments.js,
11,
],
],
},
},
Description: Object {
extractedComments: Array [
description,
],
origin: Array [
Array [
js-without-macros-or-comments.js,
3,
],
],
},
ID: Object {
extractedComments: Array [],
message: Message with id,
origin: Array [
Array [
js-without-macros-or-comments.js,
7,
],
],
},
Message: Object {
extractedComments: Array [],
origin: Array [
Array [
js-without-macros-or-comments.js,
1,
],
],
},
Multiline: Object {
extractedComments: Array [
this is 2 lines long,
],
origin: Array [
Array [
js-without-macros-or-comments.js,
5,
],
],
},
Values {param}: Object {
extractedComments: Array [],
origin: Array [
Array [
js-without-macros-or-comments.js,
9,
],
],
},
}
`;

exports[`@lingui/babel-plugin-extract-messages should extract all messages from JS files 1`] = `
Object {
Context1: Object {
Expand Down Expand Up @@ -321,3 +387,30 @@ Object {
},
}
`;

exports[`@lingui/babel-plugin-extract-messages should handle duplicate ids 1`] = `
Object {
msg: Object {
extractedComments: Array [],
message: Hello World!,
origin: Array [
Array [
duplicate-id-valid.js,
5,
],
Array [
duplicate-id-valid.js,
8,
],
Array [
duplicate-id-valid.js,
11,
],
Array [
duplicate-id-valid.js,
14,
],
],
},
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const msg = i18n._('Message')

const withDescription = i18n._('Description', {}, { comment: "description"});

const withMultilineComment = i18n._('Multiline', {}, { comment: "this is " + "2 lines long" });

const withId = i18n._('ID', {}, { message: 'Message with id' });

const withValues = i18n._('Values {param}', { param: param });

const withContext = i18n._('Some id', {},{ context: 'Context1'});
10 changes: 10 additions & 0 deletions packages/babel-plugin-extract-messages/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ describe("@lingui/babel-plugin-extract-messages", function () {
).toBeFalsy()
})

testCase(
"should handle duplicate ids",
"duplicate-id-valid.js"
)

testCase(
"should extract all messages from JSX files",
"jsx-without-macros.js"
Expand All @@ -134,4 +139,9 @@ describe("@lingui/babel-plugin-extract-messages", function () {
"should extract all messages from JS files (macros)",
"js-with-macros.js"
)

testCase(
"should extract all messages from JS files (without macros or i18n comments)",
"js-without-macros-or-comments.js"
)
})

0 comments on commit 90be171

Please sign in to comment.