eslint-plugin-formatjs 6.4.7 → 6.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +48 -34
- package/index.js.map +1 -1
- package/package.json +3 -3
- package/util.d.ts +2 -2
- package/util.js +47 -33
- package/util.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-formatjs",
|
|
3
3
|
"description": "ESLint plugin for formatjs",
|
|
4
|
-
"version": "6.4.
|
|
4
|
+
"version": "6.4.9",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Long Ho <holevietlong@gmail.com>",
|
|
7
7
|
"type": "module",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"@unicode/unicode-17.0.0": "^1.6.16",
|
|
16
16
|
"magic-string": "^0.30.0",
|
|
17
17
|
"picomatch": "2 || 3 || 4",
|
|
18
|
-
"@formatjs/icu-messageformat-parser": "3.5.
|
|
19
|
-
"@formatjs/ts-transformer": "4.4.
|
|
18
|
+
"@formatjs/icu-messageformat-parser": "3.5.8",
|
|
19
|
+
"@formatjs/ts-transformer": "4.4.8"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"eslint": "9 || 10"
|
package/util.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MessageFormatElement } from "@formatjs/icu-messageformat-parser";
|
|
2
2
|
import { Rule } from "eslint";
|
|
3
3
|
|
|
4
|
-
//#region node_modules/.aspect_rules_js/@types+estree@1.0.
|
|
4
|
+
//#region node_modules/.aspect_rules_js/@types+estree@1.0.9/node_modules/@types/estree/index.d.ts
|
|
5
5
|
// This definition file follows a somewhat unusual format. ESTree allows
|
|
6
6
|
// runtime type checks based on the `type` parameter. In order to explain this
|
|
7
7
|
// to typescript we want to use discriminated union types:
|
|
@@ -251,7 +251,7 @@ interface PrivateIdentifier extends BaseNode {
|
|
|
251
251
|
}
|
|
252
252
|
interface Property extends BaseNode {
|
|
253
253
|
type: "Property";
|
|
254
|
-
key: Expression
|
|
254
|
+
key: Expression;
|
|
255
255
|
value: Expression | Pattern; // Could be an AssignmentProperty
|
|
256
256
|
kind: "init" | "get" | "set";
|
|
257
257
|
method: boolean;
|
package/util.js
CHANGED
|
@@ -9,22 +9,54 @@ const DECLARATION_FUNCTION_NAMES = new Set(["defineMessage"]);
|
|
|
9
9
|
function getSettings({ settings }) {
|
|
10
10
|
return settings.formatjs ?? settings;
|
|
11
11
|
}
|
|
12
|
-
function isStringLiteral(node) {
|
|
13
|
-
return node.type === "Literal" && typeof node.value === "string";
|
|
14
|
-
}
|
|
15
12
|
function isTemplateLiteralWithoutVar(node) {
|
|
16
13
|
return node.type === "TemplateLiteral" && node.quasis.length === 1;
|
|
17
14
|
}
|
|
18
|
-
function
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
15
|
+
function getStaticStringFromTemplateLiteral(node) {
|
|
16
|
+
return node.quasis.length === 1 ? node.quasis[0].value.cooked ?? void 0 : void 0;
|
|
17
|
+
}
|
|
18
|
+
function isStaticMessageExpression(node) {
|
|
19
|
+
switch (node.type) {
|
|
20
|
+
case "ArrayPattern":
|
|
21
|
+
case "AssignmentPattern":
|
|
22
|
+
case "ObjectPattern": return false;
|
|
23
|
+
default: return true;
|
|
26
24
|
}
|
|
27
|
-
|
|
25
|
+
}
|
|
26
|
+
function getStaticStringFromMessageExpression(node) {
|
|
27
|
+
switch (node.type) {
|
|
28
|
+
case "TSAsExpression":
|
|
29
|
+
case "TSSatisfiesExpression":
|
|
30
|
+
case "TSNonNullExpression":
|
|
31
|
+
case "TSTypeAssertion": return getStaticStringFromMessageExpression(node.expression);
|
|
32
|
+
case "Literal": return typeof node.value === "string" ? node.value : void 0;
|
|
33
|
+
case "TemplateLiteral": return getStaticStringFromTemplateLiteral(node);
|
|
34
|
+
case "TaggedTemplateExpression":
|
|
35
|
+
if (!isTemplateLiteralWithoutVar(node.quasi)) throw new Error("Tagged template expression must be no substitution");
|
|
36
|
+
return getStaticStringFromTemplateLiteral(node.quasi);
|
|
37
|
+
case "BinaryExpression": {
|
|
38
|
+
const [result, isStaticallyEvaluatable] = staticallyEvaluateStringConcat(node);
|
|
39
|
+
return isStaticallyEvaluatable ? result : void 0;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function getStaticStringFromBinaryExpressionOperand(node) {
|
|
44
|
+
switch (node.type) {
|
|
45
|
+
case "TSAsExpression":
|
|
46
|
+
case "TSSatisfiesExpression":
|
|
47
|
+
case "TSNonNullExpression":
|
|
48
|
+
case "TSTypeAssertion": return getStaticStringFromBinaryExpressionOperand(node.expression);
|
|
49
|
+
case "Literal": return typeof node.value === "string" ? node.value : void 0;
|
|
50
|
+
case "BinaryExpression": {
|
|
51
|
+
const [result, isStaticallyEvaluatable] = staticallyEvaluateStringConcat(node);
|
|
52
|
+
return isStaticallyEvaluatable ? result : void 0;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function staticallyEvaluateStringConcat(node) {
|
|
57
|
+
const right = getStaticStringFromBinaryExpressionOperand(node.right);
|
|
58
|
+
const left = getStaticStringFromBinaryExpressionOperand(node.left);
|
|
59
|
+
return left !== void 0 && right !== void 0 ? [left + right, true] : ["", false];
|
|
28
60
|
}
|
|
29
61
|
function isIntlFormatMessageCall(node) {
|
|
30
62
|
if (node.type !== "CallExpression") return false;
|
|
@@ -54,17 +86,7 @@ function extractMessageDescriptor(node) {
|
|
|
54
86
|
const propName = prop.key.name;
|
|
55
87
|
if (propName !== "id" && propName !== "defaultMessage" && propName !== "description") continue;
|
|
56
88
|
const valueNode = prop.value;
|
|
57
|
-
|
|
58
|
-
if (isStringLiteral(valueNode)) value = valueNode.value;
|
|
59
|
-
else if (isTemplateLiteralWithoutVar(valueNode)) value = valueNode.quasis[0].value.cooked ?? void 0;
|
|
60
|
-
else if (valueNode.type === "TaggedTemplateExpression") {
|
|
61
|
-
const { quasi } = valueNode;
|
|
62
|
-
if (!isTemplateLiteralWithoutVar(quasi)) throw new Error("Tagged template expression must be no substitution");
|
|
63
|
-
value = quasi.quasis[0].value.cooked ?? void 0;
|
|
64
|
-
} else if (valueNode.type === "BinaryExpression") {
|
|
65
|
-
const [result, isStatic] = staticallyEvaluateStringConcat(valueNode);
|
|
66
|
-
if (isStatic) value = result;
|
|
67
|
-
}
|
|
89
|
+
const value = isStaticMessageExpression(valueNode) ? getStaticStringFromMessageExpression(valueNode) : void 0;
|
|
68
90
|
switch (propName) {
|
|
69
91
|
case "defaultMessage":
|
|
70
92
|
result.messagePropNode = prop;
|
|
@@ -105,18 +127,10 @@ function extractMessageDescriptorFromJSXElement(node) {
|
|
|
105
127
|
let valueNode = prop.value;
|
|
106
128
|
let value = void 0;
|
|
107
129
|
if (valueNode && isMessageProp) {
|
|
108
|
-
if (
|
|
130
|
+
if (valueNode.type === "Literal" && typeof valueNode.value === "string") value = valueNode.value;
|
|
109
131
|
else if (valueNode?.type === "JSXExpressionContainer") {
|
|
110
132
|
const { expression } = valueNode;
|
|
111
|
-
if (expression.type
|
|
112
|
-
const [result, isStatic] = staticallyEvaluateStringConcat(expression);
|
|
113
|
-
if (isStatic) value = result;
|
|
114
|
-
} else if (isTemplateLiteralWithoutVar(expression)) value = expression.quasis[0].value.cooked ?? void 0;
|
|
115
|
-
else if (expression.type === "TaggedTemplateExpression") {
|
|
116
|
-
const { quasi } = expression;
|
|
117
|
-
if (!isTemplateLiteralWithoutVar(quasi)) throw new Error("Tagged template expression must be no substitution");
|
|
118
|
-
value = quasi.quasis[0].value.cooked ?? void 0;
|
|
119
|
-
}
|
|
133
|
+
if (expression.type !== "JSXEmptyExpression") value = getStaticStringFromMessageExpression(expression);
|
|
120
134
|
}
|
|
121
135
|
}
|
|
122
136
|
switch (keyName) {
|
package/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","names":[],"sources":["../util.ts"],"sourcesContent":["import type {MessageFormatElement} from '@formatjs/icu-messageformat-parser'\nimport type {Rule} from 'eslint'\nimport type {\n BinaryExpression,\n Expression,\n Literal,\n Node,\n ObjectExpression,\n Property,\n TemplateLiteral,\n} from 'estree-jsx'\nimport type {JSXAttribute, JSXOpeningElement} from 'estree-jsx'\n\nexport interface MessageDescriptor {\n id?: string\n defaultMessage?: string\n description?: string | object\n}\n\nconst FORMAT_FUNCTION_NAMES = new Set(['$formatMessage', 'formatMessage', '$t'])\nconst COMPONENT_NAMES = new Set(['FormattedMessage'])\nconst DECLARATION_FUNCTION_NAMES = new Set(['defineMessage'])\n\nexport interface Settings {\n excludeMessageDeclCalls?: boolean\n additionalFunctionNames?: string[]\n additionalComponentNames?: string[]\n ignoreTag?: boolean\n}\nexport interface MessageDescriptorNodeInfo {\n message: MessageDescriptor\n messageDescriptorNode: ObjectExpression | JSXOpeningElement\n messageNode?: Property['value'] | JSXAttribute['value']\n messagePropNode?: Property | JSXAttribute\n descriptionNode?: Property['value'] | JSXAttribute['value']\n idValueNode?: Property['value'] | JSXAttribute['value']\n idPropNode?: Property | JSXAttribute\n}\n\nexport function getSettings({settings}: Rule.RuleContext): Settings {\n return settings.formatjs ?? settings\n}\n\nfunction isStringLiteral(node: Node): node is Literal & {value: string} {\n return node.type === 'Literal' && typeof node.value === 'string'\n}\n\nfunction isTemplateLiteralWithoutVar(node: Node): node is TemplateLiteral {\n return node.type === 'TemplateLiteral' && node.quasis.length === 1\n}\n\nfunction staticallyEvaluateStringConcat(\n node: BinaryExpression\n): [result: string, isStaticallyEvaluatable: boolean] {\n const right = node.right as Node\n const left = node.left as Node\n if (!isStringLiteral(right)) {\n return ['', false]\n }\n if (isStringLiteral(left)) {\n return [left.value + right.value, true]\n }\n if (node.left.type === 'BinaryExpression') {\n const [result, isStaticallyEvaluatable] = staticallyEvaluateStringConcat(\n node.left\n )\n return [result + right.value, isStaticallyEvaluatable]\n }\n return ['', false]\n}\n\nexport function isIntlFormatMessageCall(node: Node): boolean {\n // GH #4890: Check for both MemberExpression (intl.formatMessage) and Identifier (formatMessage) patterns\n if (node.type !== 'CallExpression') {\n return false\n }\n\n // Check if call has at least one argument that is an object expression\n if (\n node.arguments.length < 1 ||\n node.arguments[0].type !== 'ObjectExpression'\n ) {\n return false\n }\n\n // Pattern 1: intl.formatMessage() or something.intl.formatMessage()\n if (node.callee.type === 'MemberExpression') {\n return (\n ((node.callee.object.type === 'Identifier' &&\n node.callee.object.name === 'intl') ||\n (node.callee.object.type === 'MemberExpression' &&\n node.callee.object.property.type === 'Identifier' &&\n node.callee.object.property.name === 'intl')) &&\n node.callee.property.type === 'Identifier' &&\n (node.callee.property.name === 'formatMessage' ||\n node.callee.property.name === '$t')\n )\n }\n\n // Pattern 2: formatMessage() (destructured from useIntl)\n if (node.callee.type === 'Identifier') {\n return FORMAT_FUNCTION_NAMES.has(node.callee.name)\n }\n\n return false\n}\n\nfunction isSingleMessageDescriptorDeclaration(\n node: Node,\n functionNames: Set<string>\n) {\n return (\n node.type === 'CallExpression' &&\n node.callee.type === 'Identifier' &&\n functionNames.has(node.callee.name)\n )\n}\n\nfunction isMultipleMessageDescriptorDeclaration(node: Node) {\n return (\n node.type === 'CallExpression' &&\n node.callee.type === 'Identifier' &&\n node.callee.name === 'defineMessages'\n )\n}\n\nexport function extractMessageDescriptor(\n node?: Expression\n): MessageDescriptorNodeInfo | undefined {\n if (!node || node.type !== 'ObjectExpression') {\n return\n }\n const result: MessageDescriptorNodeInfo = {\n messageDescriptorNode: node,\n message: {},\n messageNode: undefined,\n messagePropNode: undefined,\n descriptionNode: undefined,\n idValueNode: undefined,\n }\n for (const prop of node.properties) {\n if (prop.type !== 'Property' || prop.key.type !== 'Identifier') {\n continue\n }\n\n // Only extract values for message-related props\n // GH #5069: Don't process other props like tagName, values, etc.\n const propName = prop.key.name\n if (\n propName !== 'id' &&\n propName !== 'defaultMessage' &&\n propName !== 'description'\n ) {\n continue\n }\n\n const valueNode = prop.value\n let value: string | undefined = undefined\n if (isStringLiteral(valueNode as Node)) {\n value = (valueNode as Literal & {value: string}).value\n }\n // like \"`asd`\"\n else if (isTemplateLiteralWithoutVar(valueNode as Node)) {\n value = (valueNode as TemplateLiteral).quasis[0].value.cooked ?? undefined\n }\n // like \"dedent`asd`\"\n else if (valueNode.type === 'TaggedTemplateExpression') {\n const {quasi} = valueNode\n if (!isTemplateLiteralWithoutVar(quasi as Node)) {\n throw new Error('Tagged template expression must be no substitution')\n }\n value = quasi.quasis[0].value.cooked ?? undefined\n }\n // like \"`asd` + `asd`\"\n else if (valueNode.type === 'BinaryExpression') {\n const [result, isStatic] = staticallyEvaluateStringConcat(valueNode)\n if (isStatic) {\n value = result\n }\n }\n\n switch (propName) {\n case 'defaultMessage':\n result.messagePropNode = prop\n result.messageNode = valueNode\n result.message.defaultMessage = value\n break\n case 'description':\n result.descriptionNode = valueNode\n result.message.description = value\n break\n case 'id':\n result.message.id = value\n result.idValueNode = valueNode\n result.idPropNode = prop\n break\n }\n }\n return result\n}\n\nfunction extractMessageDescriptorFromJSXElement(\n node?: JSXOpeningElement\n): [MessageDescriptorNodeInfo, ObjectExpression | undefined] | undefined {\n if (!node || !node.attributes) {\n return\n }\n let values: ObjectExpression | undefined\n const result: MessageDescriptorNodeInfo = {\n messageDescriptorNode: node,\n message: {},\n messageNode: undefined,\n messagePropNode: undefined,\n descriptionNode: undefined,\n idValueNode: undefined,\n idPropNode: undefined,\n }\n let hasSpreadAttribute = false\n for (const prop of node.attributes) {\n // We can't analyze spread attr\n if (prop.type === 'JSXSpreadAttribute') {\n hasSpreadAttribute = true\n }\n if (prop.type !== 'JSXAttribute' || prop.name.type !== 'JSXIdentifier') {\n continue\n }\n const key = prop.name\n const keyName = key.name\n\n // Only extract values for message-related props\n // GH #5069: Don't process other props like tagName, values, etc.\n // Allow them to have tagged templates with substitutions\n const isMessageProp =\n keyName === 'id' ||\n keyName === 'defaultMessage' ||\n keyName === 'description'\n\n let valueNode = prop.value\n let value: string | undefined = undefined\n if (valueNode && isMessageProp) {\n if (isStringLiteral(valueNode as Node)) {\n value = (valueNode as Literal & {value: string}).value\n } else if (valueNode?.type === 'JSXExpressionContainer') {\n const {expression} = valueNode\n if (expression.type === 'BinaryExpression') {\n const [result, isStatic] = staticallyEvaluateStringConcat(expression)\n if (isStatic) {\n value = result\n }\n }\n // like \"`asd`\"\n else if (isTemplateLiteralWithoutVar(expression as Node)) {\n value =\n (expression as TemplateLiteral).quasis[0].value.cooked ?? undefined\n }\n // like \"dedent`asd`\"\n else if (expression.type === 'TaggedTemplateExpression') {\n const {quasi} = expression\n if (!isTemplateLiteralWithoutVar(quasi as Node)) {\n throw new Error(\n 'Tagged template expression must be no substitution'\n )\n }\n value = quasi.quasis[0].value.cooked ?? undefined\n }\n }\n }\n\n switch (keyName) {\n case 'defaultMessage':\n result.messagePropNode = prop\n result.messageNode = valueNode\n if (value) {\n result.message.defaultMessage = value\n }\n break\n case 'description':\n result.descriptionNode = valueNode\n if (value) {\n result.message.description = value\n }\n break\n case 'id':\n result.idValueNode = valueNode\n result.idPropNode = prop\n if (value) {\n result.message.id = value\n }\n break\n case 'values':\n if (\n valueNode?.type === 'JSXExpressionContainer' &&\n valueNode.expression.type === 'ObjectExpression'\n ) {\n values = valueNode.expression\n }\n break\n }\n }\n if (\n !result.messagePropNode &&\n !result.descriptionNode &&\n !result.idPropNode &&\n hasSpreadAttribute\n ) {\n return\n }\n return [result, values]\n}\n\nfunction extractMessageDescriptors(node?: Expression) {\n if (!node || node.type !== 'ObjectExpression' || !node.properties.length) {\n return []\n }\n const msgs = []\n for (const prop of node.properties) {\n if (prop.type !== 'Property') {\n continue\n }\n const msg = prop.value\n if (msg.type !== 'ObjectExpression') {\n continue\n }\n const nodeInfo = extractMessageDescriptor(msg as Expression)\n if (nodeInfo) {\n msgs.push(nodeInfo)\n }\n }\n return msgs\n}\n\nexport function extractMessages(\n node: Node,\n {\n additionalComponentNames,\n additionalFunctionNames,\n excludeMessageDeclCalls,\n }: Settings = {}\n): Array<[MessageDescriptorNodeInfo, Expression | undefined]> {\n const allFormatFunctionNames = Array.isArray(additionalFunctionNames)\n ? new Set([\n ...Array.from(FORMAT_FUNCTION_NAMES),\n ...additionalFunctionNames,\n ])\n : FORMAT_FUNCTION_NAMES\n const allComponentNames = Array.isArray(additionalComponentNames)\n ? new Set([...Array.from(COMPONENT_NAMES), ...additionalComponentNames])\n : COMPONENT_NAMES\n if (node.type === 'CallExpression') {\n const args0 = node.arguments[0]\n const args1 = node.arguments[1]\n // We can't really analyze spread element\n if (!args0 || args0.type === 'SpreadElement') {\n return []\n }\n if (\n (!excludeMessageDeclCalls &&\n isSingleMessageDescriptorDeclaration(\n node,\n DECLARATION_FUNCTION_NAMES\n )) ||\n isIntlFormatMessageCall(node) ||\n isSingleMessageDescriptorDeclaration(node, allFormatFunctionNames)\n ) {\n const msgDescriptorNodeInfo = extractMessageDescriptor(args0)\n if (msgDescriptorNodeInfo && (!args1 || args1.type !== 'SpreadElement')) {\n return [[msgDescriptorNodeInfo, args1 as Expression]]\n }\n } else if (\n !excludeMessageDeclCalls &&\n isMultipleMessageDescriptorDeclaration(node)\n ) {\n return extractMessageDescriptors(args0).map(msg => [msg, undefined])\n }\n } else if (\n node.type === 'JSXOpeningElement' &&\n node.name &&\n node.name.type === 'JSXIdentifier' &&\n allComponentNames.has(node.name.name)\n ) {\n const msgDescriptorNodeInfo = extractMessageDescriptorFromJSXElement(node)\n if (msgDescriptorNodeInfo) {\n return [msgDescriptorNodeInfo]\n }\n }\n return []\n}\n\n/**\n * Apply changes to the ICU message in code. The return value can be used in\n * `fixer.replaceText(messageNode, <return value>)`. If the return value is null,\n * it means that the patch cannot be applied.\n */\nexport function patchMessage(\n messageNode: Node,\n ast: MessageFormatElement[],\n patcher: (messageContent: string, ast: MessageFormatElement[]) => string\n): string | null {\n if (\n messageNode.type === 'Literal' &&\n messageNode.value &&\n typeof messageNode.value === 'string'\n ) {\n return (\n '\"' + patcher(messageNode.value as string, ast).replace('\"', '\\\\\"') + '\"'\n )\n } else if (\n messageNode.type === 'TemplateLiteral' &&\n messageNode.quasis.length === 1 &&\n messageNode.expressions.length === 0\n ) {\n return (\n '`' +\n patcher(messageNode.quasis[0].value.cooked!, ast)\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/`/g, '\\\\`') +\n '`'\n )\n }\n\n return null\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"util.js","names":[],"sources":["../util.ts"],"sourcesContent":["import type {MessageFormatElement} from '@formatjs/icu-messageformat-parser'\nimport type {Rule} from 'eslint'\nimport type {\n BinaryExpression,\n Expression,\n Node,\n ObjectExpression,\n Property,\n TemplateLiteral,\n} from 'estree-jsx'\nimport type {JSXAttribute, JSXOpeningElement} from 'estree-jsx'\n\nexport interface MessageDescriptor {\n id?: string\n defaultMessage?: string\n description?: string | object\n}\n\nconst FORMAT_FUNCTION_NAMES = new Set(['$formatMessage', 'formatMessage', '$t'])\nconst COMPONENT_NAMES = new Set(['FormattedMessage'])\nconst DECLARATION_FUNCTION_NAMES = new Set(['defineMessage'])\n\nexport interface Settings {\n excludeMessageDeclCalls?: boolean\n additionalFunctionNames?: string[]\n additionalComponentNames?: string[]\n ignoreTag?: boolean\n}\nexport interface MessageDescriptorNodeInfo {\n message: MessageDescriptor\n messageDescriptorNode: ObjectExpression | JSXOpeningElement\n messageNode?: Property['value'] | JSXAttribute['value']\n messagePropNode?: Property | JSXAttribute\n descriptionNode?: Property['value'] | JSXAttribute['value']\n idValueNode?: Property['value'] | JSXAttribute['value']\n idPropNode?: Property | JSXAttribute\n}\n\nexport function getSettings({settings}: Rule.RuleContext): Settings {\n return settings.formatjs ?? settings\n}\n\ntype BinaryExpressionOperand =\n | BinaryExpression['left']\n | BinaryExpression['right']\n\nfunction isTemplateLiteralWithoutVar(node: Node): node is TemplateLiteral {\n return node.type === 'TemplateLiteral' && node.quasis.length === 1\n}\n\ntype TransparentTypeScriptExpressionType =\n | 'TSAsExpression'\n | 'TSSatisfiesExpression'\n | 'TSNonNullExpression'\n | 'TSTypeAssertion'\n\ninterface TypeScriptExpressionWrapper {\n type: TransparentTypeScriptExpressionType\n expression: StaticMessageExpression\n}\n\ninterface TypeScriptBinaryExpressionOperandWrapper {\n type: TransparentTypeScriptExpressionType\n expression: StaticStringConcatOperand\n}\n\ntype StaticMessageExpression = Expression | TypeScriptExpressionWrapper\ntype MessagePropertyValue = Property['value'] | TypeScriptExpressionWrapper\ntype StaticStringConcatOperand =\n | BinaryExpressionOperand\n | TypeScriptBinaryExpressionOperandWrapper\n\nfunction getStaticStringFromTemplateLiteral(\n node: TemplateLiteral\n): string | undefined {\n return node.quasis.length === 1\n ? (node.quasis[0].value.cooked ?? undefined)\n : undefined\n}\n\nfunction isStaticMessageExpression(\n node: MessagePropertyValue\n): node is StaticMessageExpression {\n switch (node.type) {\n case 'ArrayPattern':\n case 'AssignmentPattern':\n case 'ObjectPattern':\n return false\n default:\n return true\n }\n}\n\nfunction getStaticStringFromMessageExpression(\n node: StaticMessageExpression\n): string | undefined {\n switch (node.type) {\n case 'TSAsExpression':\n case 'TSSatisfiesExpression':\n case 'TSNonNullExpression':\n case 'TSTypeAssertion':\n return getStaticStringFromMessageExpression(node.expression)\n case 'Literal':\n return typeof node.value === 'string' ? node.value : undefined\n case 'TemplateLiteral':\n return getStaticStringFromTemplateLiteral(node)\n case 'TaggedTemplateExpression':\n if (!isTemplateLiteralWithoutVar(node.quasi)) {\n throw new Error('Tagged template expression must be no substitution')\n }\n return getStaticStringFromTemplateLiteral(node.quasi)\n case 'BinaryExpression': {\n const [result, isStaticallyEvaluatable] =\n staticallyEvaluateStringConcat(node)\n return isStaticallyEvaluatable ? result : undefined\n }\n }\n}\n\nfunction getStaticStringFromBinaryExpressionOperand(\n node: StaticStringConcatOperand\n): string | undefined {\n switch (node.type) {\n case 'TSAsExpression':\n case 'TSSatisfiesExpression':\n case 'TSNonNullExpression':\n case 'TSTypeAssertion':\n return getStaticStringFromBinaryExpressionOperand(node.expression)\n case 'Literal':\n return typeof node.value === 'string' ? node.value : undefined\n case 'BinaryExpression': {\n const [result, isStaticallyEvaluatable] =\n staticallyEvaluateStringConcat(node)\n return isStaticallyEvaluatable ? result : undefined\n }\n }\n}\n\nfunction staticallyEvaluateStringConcat(\n node: BinaryExpression\n): [result: string, isStaticallyEvaluatable: boolean] {\n const right = getStaticStringFromBinaryExpressionOperand(node.right)\n const left = getStaticStringFromBinaryExpressionOperand(node.left)\n return left !== undefined && right !== undefined\n ? [left + right, true]\n : ['', false]\n}\n\nexport function isIntlFormatMessageCall(node: Node): boolean {\n // GH #4890: Check for both MemberExpression (intl.formatMessage) and Identifier (formatMessage) patterns\n if (node.type !== 'CallExpression') {\n return false\n }\n\n // Check if call has at least one argument that is an object expression\n if (\n node.arguments.length < 1 ||\n node.arguments[0].type !== 'ObjectExpression'\n ) {\n return false\n }\n\n // Pattern 1: intl.formatMessage() or something.intl.formatMessage()\n if (node.callee.type === 'MemberExpression') {\n return (\n ((node.callee.object.type === 'Identifier' &&\n node.callee.object.name === 'intl') ||\n (node.callee.object.type === 'MemberExpression' &&\n node.callee.object.property.type === 'Identifier' &&\n node.callee.object.property.name === 'intl')) &&\n node.callee.property.type === 'Identifier' &&\n (node.callee.property.name === 'formatMessage' ||\n node.callee.property.name === '$t')\n )\n }\n\n // Pattern 2: formatMessage() (destructured from useIntl)\n if (node.callee.type === 'Identifier') {\n return FORMAT_FUNCTION_NAMES.has(node.callee.name)\n }\n\n return false\n}\n\nfunction isSingleMessageDescriptorDeclaration(\n node: Node,\n functionNames: Set<string>\n) {\n return (\n node.type === 'CallExpression' &&\n node.callee.type === 'Identifier' &&\n functionNames.has(node.callee.name)\n )\n}\n\nfunction isMultipleMessageDescriptorDeclaration(node: Node) {\n return (\n node.type === 'CallExpression' &&\n node.callee.type === 'Identifier' &&\n node.callee.name === 'defineMessages'\n )\n}\n\nexport function extractMessageDescriptor(\n node?: Expression\n): MessageDescriptorNodeInfo | undefined {\n if (!node || node.type !== 'ObjectExpression') {\n return\n }\n const result: MessageDescriptorNodeInfo = {\n messageDescriptorNode: node,\n message: {},\n messageNode: undefined,\n messagePropNode: undefined,\n descriptionNode: undefined,\n idValueNode: undefined,\n }\n for (const prop of node.properties) {\n if (prop.type !== 'Property' || prop.key.type !== 'Identifier') {\n continue\n }\n\n // Only extract values for message-related props\n // GH #5069: Don't process other props like tagName, values, etc.\n const propName = prop.key.name\n if (\n propName !== 'id' &&\n propName !== 'defaultMessage' &&\n propName !== 'description'\n ) {\n continue\n }\n\n const valueNode: MessagePropertyValue = prop.value\n const value = isStaticMessageExpression(valueNode)\n ? getStaticStringFromMessageExpression(valueNode)\n : undefined\n\n switch (propName) {\n case 'defaultMessage':\n result.messagePropNode = prop\n result.messageNode = valueNode\n result.message.defaultMessage = value\n break\n case 'description':\n result.descriptionNode = valueNode\n result.message.description = value\n break\n case 'id':\n result.message.id = value\n result.idValueNode = valueNode\n result.idPropNode = prop\n break\n }\n }\n return result\n}\n\nfunction extractMessageDescriptorFromJSXElement(\n node?: JSXOpeningElement\n): [MessageDescriptorNodeInfo, ObjectExpression | undefined] | undefined {\n if (!node || !node.attributes) {\n return\n }\n let values: ObjectExpression | undefined\n const result: MessageDescriptorNodeInfo = {\n messageDescriptorNode: node,\n message: {},\n messageNode: undefined,\n messagePropNode: undefined,\n descriptionNode: undefined,\n idValueNode: undefined,\n idPropNode: undefined,\n }\n let hasSpreadAttribute = false\n for (const prop of node.attributes) {\n // We can't analyze spread attr\n if (prop.type === 'JSXSpreadAttribute') {\n hasSpreadAttribute = true\n }\n if (prop.type !== 'JSXAttribute' || prop.name.type !== 'JSXIdentifier') {\n continue\n }\n const key = prop.name\n const keyName = key.name\n\n // Only extract values for message-related props\n // GH #5069: Don't process other props like tagName, values, etc.\n // Allow them to have tagged templates with substitutions\n const isMessageProp =\n keyName === 'id' ||\n keyName === 'defaultMessage' ||\n keyName === 'description'\n\n let valueNode = prop.value\n let value: string | undefined = undefined\n if (valueNode && isMessageProp) {\n if (valueNode.type === 'Literal' && typeof valueNode.value === 'string') {\n value = valueNode.value\n } else if (valueNode?.type === 'JSXExpressionContainer') {\n const {expression} = valueNode\n if (expression.type !== 'JSXEmptyExpression') {\n value = getStaticStringFromMessageExpression(expression)\n }\n }\n }\n\n switch (keyName) {\n case 'defaultMessage':\n result.messagePropNode = prop\n result.messageNode = valueNode\n if (value) {\n result.message.defaultMessage = value\n }\n break\n case 'description':\n result.descriptionNode = valueNode\n if (value) {\n result.message.description = value\n }\n break\n case 'id':\n result.idValueNode = valueNode\n result.idPropNode = prop\n if (value) {\n result.message.id = value\n }\n break\n case 'values':\n if (\n valueNode?.type === 'JSXExpressionContainer' &&\n valueNode.expression.type === 'ObjectExpression'\n ) {\n values = valueNode.expression\n }\n break\n }\n }\n if (\n !result.messagePropNode &&\n !result.descriptionNode &&\n !result.idPropNode &&\n hasSpreadAttribute\n ) {\n return\n }\n return [result, values]\n}\n\nfunction extractMessageDescriptors(node?: Expression) {\n if (!node || node.type !== 'ObjectExpression' || !node.properties.length) {\n return []\n }\n const msgs = []\n for (const prop of node.properties) {\n if (prop.type !== 'Property') {\n continue\n }\n const msg = prop.value\n if (msg.type !== 'ObjectExpression') {\n continue\n }\n const nodeInfo = extractMessageDescriptor(msg as Expression)\n if (nodeInfo) {\n msgs.push(nodeInfo)\n }\n }\n return msgs\n}\n\nexport function extractMessages(\n node: Node,\n {\n additionalComponentNames,\n additionalFunctionNames,\n excludeMessageDeclCalls,\n }: Settings = {}\n): Array<[MessageDescriptorNodeInfo, Expression | undefined]> {\n const allFormatFunctionNames = Array.isArray(additionalFunctionNames)\n ? new Set([\n ...Array.from(FORMAT_FUNCTION_NAMES),\n ...additionalFunctionNames,\n ])\n : FORMAT_FUNCTION_NAMES\n const allComponentNames = Array.isArray(additionalComponentNames)\n ? new Set([...Array.from(COMPONENT_NAMES), ...additionalComponentNames])\n : COMPONENT_NAMES\n if (node.type === 'CallExpression') {\n const args0 = node.arguments[0]\n const args1 = node.arguments[1]\n // We can't really analyze spread element\n if (!args0 || args0.type === 'SpreadElement') {\n return []\n }\n if (\n (!excludeMessageDeclCalls &&\n isSingleMessageDescriptorDeclaration(\n node,\n DECLARATION_FUNCTION_NAMES\n )) ||\n isIntlFormatMessageCall(node) ||\n isSingleMessageDescriptorDeclaration(node, allFormatFunctionNames)\n ) {\n const msgDescriptorNodeInfo = extractMessageDescriptor(args0)\n if (msgDescriptorNodeInfo && (!args1 || args1.type !== 'SpreadElement')) {\n return [[msgDescriptorNodeInfo, args1 as Expression]]\n }\n } else if (\n !excludeMessageDeclCalls &&\n isMultipleMessageDescriptorDeclaration(node)\n ) {\n return extractMessageDescriptors(args0).map(msg => [msg, undefined])\n }\n } else if (\n node.type === 'JSXOpeningElement' &&\n node.name &&\n node.name.type === 'JSXIdentifier' &&\n allComponentNames.has(node.name.name)\n ) {\n const msgDescriptorNodeInfo = extractMessageDescriptorFromJSXElement(node)\n if (msgDescriptorNodeInfo) {\n return [msgDescriptorNodeInfo]\n }\n }\n return []\n}\n\n/**\n * Apply changes to the ICU message in code. The return value can be used in\n * `fixer.replaceText(messageNode, <return value>)`. If the return value is null,\n * it means that the patch cannot be applied.\n */\nexport function patchMessage(\n messageNode: Node,\n ast: MessageFormatElement[],\n patcher: (messageContent: string, ast: MessageFormatElement[]) => string\n): string | null {\n if (\n messageNode.type === 'Literal' &&\n messageNode.value &&\n typeof messageNode.value === 'string'\n ) {\n return (\n '\"' + patcher(messageNode.value as string, ast).replace('\"', '\\\\\"') + '\"'\n )\n } else if (\n messageNode.type === 'TemplateLiteral' &&\n messageNode.quasis.length === 1 &&\n messageNode.expressions.length === 0\n ) {\n return (\n '`' +\n patcher(messageNode.quasis[0].value.cooked!, ast)\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/`/g, '\\\\`') +\n '`'\n )\n }\n\n return null\n}\n"],"mappings":";AAkBA,MAAM,wBAAwB,IAAI,IAAI;CAAC;CAAkB;CAAiB;CAAK,CAAC;AAChF,MAAM,kBAAkB,IAAI,IAAI,CAAC,mBAAmB,CAAC;AACrD,MAAM,6BAA6B,IAAI,IAAI,CAAC,gBAAgB,CAAC;AAkB7D,SAAgB,YAAY,EAAC,YAAuC;AAClE,QAAO,SAAS,YAAY;;AAO9B,SAAS,4BAA4B,MAAqC;AACxE,QAAO,KAAK,SAAS,qBAAqB,KAAK,OAAO,WAAW;;AAyBnE,SAAS,mCACP,MACoB;AACpB,QAAO,KAAK,OAAO,WAAW,IACzB,KAAK,OAAO,GAAG,MAAM,UAAU,KAAA,IAChC,KAAA;;AAGN,SAAS,0BACP,MACiC;AACjC,SAAQ,KAAK,MAAb;EACE,KAAK;EACL,KAAK;EACL,KAAK,gBACH,QAAO;EACT,QACE,QAAO;;;AAIb,SAAS,qCACP,MACoB;AACpB,SAAQ,KAAK,MAAb;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,kBACH,QAAO,qCAAqC,KAAK,WAAW;EAC9D,KAAK,UACH,QAAO,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,KAAA;EACvD,KAAK,kBACH,QAAO,mCAAmC,KAAK;EACjD,KAAK;AACH,OAAI,CAAC,4BAA4B,KAAK,MAAM,CAC1C,OAAM,IAAI,MAAM,qDAAqD;AAEvE,UAAO,mCAAmC,KAAK,MAAM;EACvD,KAAK,oBAAoB;GACvB,MAAM,CAAC,QAAQ,2BACb,+BAA+B,KAAK;AACtC,UAAO,0BAA0B,SAAS,KAAA;;;;AAKhD,SAAS,2CACP,MACoB;AACpB,SAAQ,KAAK,MAAb;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,kBACH,QAAO,2CAA2C,KAAK,WAAW;EACpE,KAAK,UACH,QAAO,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,KAAA;EACvD,KAAK,oBAAoB;GACvB,MAAM,CAAC,QAAQ,2BACb,+BAA+B,KAAK;AACtC,UAAO,0BAA0B,SAAS,KAAA;;;;AAKhD,SAAS,+BACP,MACoD;CACpD,MAAM,QAAQ,2CAA2C,KAAK,MAAM;CACpE,MAAM,OAAO,2CAA2C,KAAK,KAAK;AAClE,QAAO,SAAS,KAAA,KAAa,UAAU,KAAA,IACnC,CAAC,OAAO,OAAO,KAAK,GACpB,CAAC,IAAI,MAAM;;AAGjB,SAAgB,wBAAwB,MAAqB;AAE3D,KAAI,KAAK,SAAS,iBAChB,QAAO;AAIT,KACE,KAAK,UAAU,SAAS,KACxB,KAAK,UAAU,GAAG,SAAS,mBAE3B,QAAO;AAIT,KAAI,KAAK,OAAO,SAAS,mBACvB,SACI,KAAK,OAAO,OAAO,SAAS,gBAC5B,KAAK,OAAO,OAAO,SAAS,UAC3B,KAAK,OAAO,OAAO,SAAS,sBAC3B,KAAK,OAAO,OAAO,SAAS,SAAS,gBACrC,KAAK,OAAO,OAAO,SAAS,SAAS,WACzC,KAAK,OAAO,SAAS,SAAS,iBAC7B,KAAK,OAAO,SAAS,SAAS,mBAC7B,KAAK,OAAO,SAAS,SAAS;AAKpC,KAAI,KAAK,OAAO,SAAS,aACvB,QAAO,sBAAsB,IAAI,KAAK,OAAO,KAAK;AAGpD,QAAO;;AAGT,SAAS,qCACP,MACA,eACA;AACA,QACE,KAAK,SAAS,oBACd,KAAK,OAAO,SAAS,gBACrB,cAAc,IAAI,KAAK,OAAO,KAAK;;AAIvC,SAAS,uCAAuC,MAAY;AAC1D,QACE,KAAK,SAAS,oBACd,KAAK,OAAO,SAAS,gBACrB,KAAK,OAAO,SAAS;;AAIzB,SAAgB,yBACd,MACuC;AACvC,KAAI,CAAC,QAAQ,KAAK,SAAS,mBACzB;CAEF,MAAM,SAAoC;EACxC,uBAAuB;EACvB,SAAS,EAAE;EACX,aAAa,KAAA;EACb,iBAAiB,KAAA;EACjB,iBAAiB,KAAA;EACjB,aAAa,KAAA;EACd;AACD,MAAK,MAAM,QAAQ,KAAK,YAAY;AAClC,MAAI,KAAK,SAAS,cAAc,KAAK,IAAI,SAAS,aAChD;EAKF,MAAM,WAAW,KAAK,IAAI;AAC1B,MACE,aAAa,QACb,aAAa,oBACb,aAAa,cAEb;EAGF,MAAM,YAAkC,KAAK;EAC7C,MAAM,QAAQ,0BAA0B,UAAU,GAC9C,qCAAqC,UAAU,GAC/C,KAAA;AAEJ,UAAQ,UAAR;GACE,KAAK;AACH,WAAO,kBAAkB;AACzB,WAAO,cAAc;AACrB,WAAO,QAAQ,iBAAiB;AAChC;GACF,KAAK;AACH,WAAO,kBAAkB;AACzB,WAAO,QAAQ,cAAc;AAC7B;GACF,KAAK;AACH,WAAO,QAAQ,KAAK;AACpB,WAAO,cAAc;AACrB,WAAO,aAAa;AACpB;;;AAGN,QAAO;;AAGT,SAAS,uCACP,MACuE;AACvE,KAAI,CAAC,QAAQ,CAAC,KAAK,WACjB;CAEF,IAAI;CACJ,MAAM,SAAoC;EACxC,uBAAuB;EACvB,SAAS,EAAE;EACX,aAAa,KAAA;EACb,iBAAiB,KAAA;EACjB,iBAAiB,KAAA;EACjB,aAAa,KAAA;EACb,YAAY,KAAA;EACb;CACD,IAAI,qBAAqB;AACzB,MAAK,MAAM,QAAQ,KAAK,YAAY;AAElC,MAAI,KAAK,SAAS,qBAChB,sBAAqB;AAEvB,MAAI,KAAK,SAAS,kBAAkB,KAAK,KAAK,SAAS,gBACrD;EAGF,MAAM,UADM,KAAK,KACG;EAKpB,MAAM,gBACJ,YAAY,QACZ,YAAY,oBACZ,YAAY;EAEd,IAAI,YAAY,KAAK;EACrB,IAAI,QAA4B,KAAA;AAChC,MAAI,aAAa;OACX,UAAU,SAAS,aAAa,OAAO,UAAU,UAAU,SAC7D,SAAQ,UAAU;YACT,WAAW,SAAS,0BAA0B;IACvD,MAAM,EAAC,eAAc;AACrB,QAAI,WAAW,SAAS,qBACtB,SAAQ,qCAAqC,WAAW;;;AAK9D,UAAQ,SAAR;GACE,KAAK;AACH,WAAO,kBAAkB;AACzB,WAAO,cAAc;AACrB,QAAI,MACF,QAAO,QAAQ,iBAAiB;AAElC;GACF,KAAK;AACH,WAAO,kBAAkB;AACzB,QAAI,MACF,QAAO,QAAQ,cAAc;AAE/B;GACF,KAAK;AACH,WAAO,cAAc;AACrB,WAAO,aAAa;AACpB,QAAI,MACF,QAAO,QAAQ,KAAK;AAEtB;GACF,KAAK;AACH,QACE,WAAW,SAAS,4BACpB,UAAU,WAAW,SAAS,mBAE9B,UAAS,UAAU;AAErB;;;AAGN,KACE,CAAC,OAAO,mBACR,CAAC,OAAO,mBACR,CAAC,OAAO,cACR,mBAEA;AAEF,QAAO,CAAC,QAAQ,OAAO;;AAGzB,SAAS,0BAA0B,MAAmB;AACpD,KAAI,CAAC,QAAQ,KAAK,SAAS,sBAAsB,CAAC,KAAK,WAAW,OAChE,QAAO,EAAE;CAEX,MAAM,OAAO,EAAE;AACf,MAAK,MAAM,QAAQ,KAAK,YAAY;AAClC,MAAI,KAAK,SAAS,WAChB;EAEF,MAAM,MAAM,KAAK;AACjB,MAAI,IAAI,SAAS,mBACf;EAEF,MAAM,WAAW,yBAAyB,IAAkB;AAC5D,MAAI,SACF,MAAK,KAAK,SAAS;;AAGvB,QAAO;;AAGT,SAAgB,gBACd,MACA,EACE,0BACA,yBACA,4BACY,EAAE,EAC4C;CAC5D,MAAM,yBAAyB,MAAM,QAAQ,wBAAwB,GACjE,IAAI,IAAI,CACN,GAAG,MAAM,KAAK,sBAAsB,EACpC,GAAG,wBACJ,CAAC,GACF;CACJ,MAAM,oBAAoB,MAAM,QAAQ,yBAAyB,GAC7D,IAAI,IAAI,CAAC,GAAG,MAAM,KAAK,gBAAgB,EAAE,GAAG,yBAAyB,CAAC,GACtE;AACJ,KAAI,KAAK,SAAS,kBAAkB;EAClC,MAAM,QAAQ,KAAK,UAAU;EAC7B,MAAM,QAAQ,KAAK,UAAU;AAE7B,MAAI,CAAC,SAAS,MAAM,SAAS,gBAC3B,QAAO,EAAE;AAEX,MACG,CAAC,2BACA,qCACE,MACA,2BACD,IACH,wBAAwB,KAAK,IAC7B,qCAAqC,MAAM,uBAAuB,EAClE;GACA,MAAM,wBAAwB,yBAAyB,MAAM;AAC7D,OAAI,0BAA0B,CAAC,SAAS,MAAM,SAAS,iBACrD,QAAO,CAAC,CAAC,uBAAuB,MAAoB,CAAC;aAGvD,CAAC,2BACD,uCAAuC,KAAK,CAE5C,QAAO,0BAA0B,MAAM,CAAC,KAAI,QAAO,CAAC,KAAK,KAAA,EAAU,CAAC;YAGtE,KAAK,SAAS,uBACd,KAAK,QACL,KAAK,KAAK,SAAS,mBACnB,kBAAkB,IAAI,KAAK,KAAK,KAAK,EACrC;EACA,MAAM,wBAAwB,uCAAuC,KAAK;AAC1E,MAAI,sBACF,QAAO,CAAC,sBAAsB;;AAGlC,QAAO,EAAE;;;;;;;AAQX,SAAgB,aACd,aACA,KACA,SACe;AACf,KACE,YAAY,SAAS,aACrB,YAAY,SACZ,OAAO,YAAY,UAAU,SAE7B,QACE,OAAM,QAAQ,YAAY,OAAiB,IAAI,CAAC,QAAQ,MAAK,OAAM,GAAG;UAGxE,YAAY,SAAS,qBACrB,YAAY,OAAO,WAAW,KAC9B,YAAY,YAAY,WAAW,EAEnC,QACE,MACA,QAAQ,YAAY,OAAO,GAAG,MAAM,QAAS,IAAI,CAC9C,QAAQ,OAAO,OAAO,CACtB,QAAQ,MAAM,MAAM,GACvB;AAIJ,QAAO"}
|