From b51f57300d5a371c979dca7d321acdcfd184fefc Mon Sep 17 00:00:00 2001
From: Long Ho
Date: Fri, 8 May 2020 17:33:54 -0400
Subject: [PATCH] fix(@formatjs/ts-transformer): preserve other attr in the
component
---
packages/ts-transformer/src/transform.ts | 35 +++++++++++++------
.../tests/__snapshots__/index.test.ts.snap | 27 +++++++-------
.../tests/fixtures/FormattedMessage.tsx | 5 ++-
.../tests/fixtures/overrideIdFn.tsx | 3 +-
4 files changed, 42 insertions(+), 28 deletions(-)
diff --git a/packages/ts-transformer/src/transform.ts b/packages/ts-transformer/src/transform.ts
index a4bf16690e..731d0a999a 100644
--- a/packages/ts-transformer/src/transform.ts
+++ b/packages/ts-transformer/src/transform.ts
@@ -10,6 +10,8 @@ export type InterpolateNameFn = (
description?: string
) => string;
+const MESSAGE_DESC_KEYS = new Set(['id', 'defaultMessage', 'description']);
+
export interface Opts {
/**
* Whether the metadata about the location of the message in the source file
@@ -215,19 +217,30 @@ function setAttributesInObject(
msg: MessageDescriptor
) {
const newNode = ts.getMutableClone(node);
- newNode.properties = ts.createNodeArray(
- (['id', 'description', 'defaultMessage'] as Array)
- .filter(k => !!msg[k])
- .map(k => {
+ const newProps = [];
+ for (const prop of node.properties) {
+ if (
+ (ts.isJsxAttribute(prop) || ts.isPropertyAssignment(prop)) &&
+ ts.isIdentifier(prop.name)
+ ) {
+ const k = prop.name.text as keyof MessageDescriptor;
+ if (MESSAGE_DESC_KEYS.has(k)) {
const val = msg[k];
- const keyNode = ts.createIdentifier(k);
- const valNode = ts.createStringLiteral(val + '');
- if (ts.isJsxAttributes(node)) {
- return ts.createJsxAttribute(keyNode, valNode);
+ if (val) {
+ const keyNode = ts.createIdentifier(k);
+ const valNode = ts.createStringLiteral(val + '');
+ if (ts.isJsxAttributes(node)) {
+ newProps.push(ts.createJsxAttribute(keyNode, valNode));
+ } else if (ts.isObjectLiteralExpression(node)) {
+ newProps.push(ts.createPropertyAssignment(k, valNode));
+ }
}
- return ts.createPropertyAssignment(keyNode, valNode);
- })
- ) as ts.NodeArray;
+ continue;
+ }
+ }
+ newProps.push(prop);
+ }
+ newNode.properties = ts.createNodeArray(newProps) as any;
return newNode;
}
diff --git a/packages/ts-transformer/tests/__snapshots__/index.test.ts.snap b/packages/ts-transformer/tests/__snapshots__/index.test.ts.snap
index 347f0fb5a3..132d6f225f 100644
--- a/packages/ts-transformer/tests/__snapshots__/index.test.ts.snap
+++ b/packages/ts-transformer/tests/__snapshots__/index.test.ts.snap
@@ -32,14 +32,16 @@ const react_1 = require(\\"react\\");
const react_intl_1 = require(\\"react-intl\\");
class Foo extends react_1.Component {
render() {
- return (react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'foo.bar.baz', defaultMessage: 'Hello World!' }));
+ return (react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'foo.bar.baz', defaultMessage: 'Hello World! {foo, number}', values: {
+ foo: 1
+ } }));
}
}
exports.default = Foo;
",
"msgs": Array [
Object {
- "defaultMessage": "Hello World!",
+ "defaultMessage": "Hello World! {foo, number}",
"description": "The default message.",
"id": "foo.bar.baz",
},
@@ -183,12 +185,16 @@ class Foo extends react_1.Component {
defaultMessage: \\"Hello Nurse!\\"
}),
invalid: this.props.intl.formatMessage(objectPointer),
- invalid2: this.props.intl.formatMessage({ id, defaultMessage, description: 'asd' })
+ invalid2: this.props.intl.formatMessage({
+ id,
+ defaultMessage,
+ description: 'asd',
+ }),
};
return (react_1.default.createElement(\\"div\\", null,
react_1.default.createElement(\\"h1\\", null, msgs.header),
react_1.default.createElement(\\"p\\", null, msgs.content),
- react_1.default.createElement(\\"input\\", { placeholder: intl.formatMessage({ id: \\"1_ZyCapCsn\\", defaultMessage: \\"inline\\" }) }),
+ react_1.default.createElement(\\"input\\", { placeholder: intl.formatMessage({ defaultMessage: \\"inline\\" }) }),
react_1.default.createElement(\\"span\\", null,
react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'foo', defaultMessage: 'bar' }))));
}
@@ -370,11 +376,9 @@ exports.default = Foo;
exports[`emit asserts for nested 1`] = `
Object {
"code": "intl.formatMessage({
- id: \\"HELLO.undefined.13.undefined\\",
defaultMessage: \\"layer1 {name}\\"
}, {
name: intl.formatMessage({
- id: \\"HELLO.undefined.6.undefined\\",
defaultMessage: \\"layer2\\"
}),
});
@@ -398,15 +402,12 @@ Object {
Object.defineProperty(exports, \\"__esModule\\", { value: true });
function foo() {
props.intl.formatMessage({
- id: \\"2AgGp\\",
defaultMessage: \\"props {intl}\\"
}, { bar: 'bar' });
this.props.intl.formatMessage({
- id: \\"STVHS\\",
defaultMessage: \\"this props {intl}\\"
}, { bar: 'bar' });
return intl.formatMessage({
- id: \\"1aog4\\",
defaultMessage: \\"foo {bar}\\"
}, { bar: 'bar' });
}
@@ -449,7 +450,6 @@ const msgs = react_intl_1.defineMessages({
}
});
react_intl_1.defineMessage({
- id: \\"HELLO.undefined.13.string\\",
defaultMessage: \\"defineMessage\\"
});
class Foo extends react_1.Component {
@@ -457,15 +457,12 @@ class Foo extends react_1.Component {
const { intl } = this.props;
const { formatMessage } = intl;
this.props.intl.formatMessage({
- id: \\"HELLO.undefined.5.string\\",
defaultMessage: \\"no-id\\"
});
intl.formatMessage({
- id: \\"HELLO.undefined.18.string\\",
defaultMessage: \\"intl.formatMessage\\"
});
formatMessage({
- id: \\"HELLO.undefined.13.string\\",
defaultMessage: \\"formatMessage\\"
});
return (react_1.default.createElement(\\"div\\", null,
@@ -473,7 +470,7 @@ class Foo extends react_1.Component {
react_1.default.createElement(react_intl_1.FormattedMessage, Object.assign({}, msgs.header))),
react_1.default.createElement(\\"p\\", null,
react_1.default.createElement(react_intl_1.FormattedMessage, Object.assign({}, msgs.content))),
- react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'foo.bar.zoo', defaultMessage: 'Hello World!' })));
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: 'foo.bar.zoo', defaultMessage: 'Hello World! {abc}', values: { abc: 2 } })));
}
}
exports.default = Foo;
@@ -509,7 +506,7 @@ exports.default = Foo;
"id": "HELLO.undefined.13.string",
},
Object {
- "defaultMessage": "Hello World!",
+ "defaultMessage": "Hello World! {abc}",
"id": "foo.bar.zoo",
},
],
diff --git a/packages/ts-transformer/tests/fixtures/FormattedMessage.tsx b/packages/ts-transformer/tests/fixtures/FormattedMessage.tsx
index a25f03f055..6d3fef655e 100644
--- a/packages/ts-transformer/tests/fixtures/FormattedMessage.tsx
+++ b/packages/ts-transformer/tests/fixtures/FormattedMessage.tsx
@@ -6,8 +6,11 @@ export default class Foo extends Component {
return (
);
}
diff --git a/packages/ts-transformer/tests/fixtures/overrideIdFn.tsx b/packages/ts-transformer/tests/fixtures/overrideIdFn.tsx
index 2a396996f7..984e6e8e0b 100644
--- a/packages/ts-transformer/tests/fixtures/overrideIdFn.tsx
+++ b/packages/ts-transformer/tests/fixtures/overrideIdFn.tsx
@@ -49,11 +49,12 @@ export default class Foo extends Component {
);