From 1c606226281421194133e4f46e9b594ba9ea2b64 Mon Sep 17 00:00:00 2001 From: Paul Salvatore Date: Wed, 24 Jan 2024 11:35:28 -0500 Subject: [PATCH] feat: simplify AST selector to work with compiled code (#16) --- package.json | 5 +- src/__fixtures__/pre-compiled-nextjs/code.js | 63 +++++++++++++++++++ .../pre-compiled-nextjs/mockMessages.js | 10 +++ .../__snapshots__/index.test.js.snap | 58 +++++++++++++++++ src/__tests__/index.test.js | 47 ++++++++++++++ src/index.js | 52 +++------------ yarn.lock | 6 +- 7 files changed, 191 insertions(+), 50 deletions(-) create mode 100644 src/__fixtures__/pre-compiled-nextjs/code.js create mode 100644 src/__fixtures__/pre-compiled-nextjs/mockMessages.js diff --git a/package.json b/package.json index 0bf88b4..e9934a7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@faire/babel-plugin-formatjs-localized-bundle", - "version": "2.1.5", + "version": "2.2.0", "main": "dist/src/index.js", "author": "Paul Salvatore ", "license": "MIT", @@ -57,5 +57,6 @@ "@semantic-release/npm", "@semantic-release/github" ] - } + }, + "dependencies": {} } diff --git a/src/__fixtures__/pre-compiled-nextjs/code.js b/src/__fixtures__/pre-compiled-nextjs/code.js new file mode 100644 index 0000000..ea086cd --- /dev/null +++ b/src/__fixtures__/pre-compiled-nextjs/code.js @@ -0,0 +1,63 @@ +"use strict"; +(exports.id = 885), + (exports.ids = [885, 26456]), + (exports.modules = { + 359692: (e, t, n) => { + let I = (e) => { + let { strictLocalize: t } = (0, i.Pi)(), + { + backgroundColor: n = o.QY.surface.subdued, + content: E, + contentColor: _ = o.QY.text.default, + notificationDot: a, + } = e, + l = t({ + id: "J8xC2I", + defaultMessage: [{ type: 0, value: "with notification" }], + }); + return (0, r.jsxs)(A, { + backgroundColor: n, + contentColor: _, + "data-test-id": e["data-test-id"], + className: e.className, + children: [ + E > 99 ? "99+" : E, + a + ? (0, r.jsxs)(r.Fragment, { + children: [ + (0, r.jsx)(R, { children: l }), + (0, r.jsx)(T, { children: (0, r.jsx)(O.P, {}) }), + ], + }) + : null, + ], + }); + }; + }, + 200077: (t, e, i) => { + let f = class extends m.Component { + constructor(t) { + super(t), + (this.updateCustomOptionReaction = (0, h.reaction)( + () => this.props.value, + (t) => { + !this.isValueInOptions(t) && + this.props.shouldUseCustomOption && + ((this.customOption.value = t), + (this.customOption.label = this.customOptionLabel), + (this.hasEditedCustomOption = !0)); + } + )), + (this.customQuantitySelection = !1), + (this.hasEditedCustomOption = !1), + (this.customOption = { + value: "", + label: this.props.strictLocalize({ + id: "dhKCUV", + defaultMessage: [{ type: 0, value: "Custom Quantity" }], + }), + }); + } + }; + }, + }); diff --git a/src/__fixtures__/pre-compiled-nextjs/mockMessages.js b/src/__fixtures__/pre-compiled-nextjs/mockMessages.js new file mode 100644 index 0000000..9d0d26b --- /dev/null +++ b/src/__fixtures__/pre-compiled-nextjs/mockMessages.js @@ -0,0 +1,10 @@ +module.exports = { + J8xC2I: { + type: 0, + value: "mit Benachrichtigung", + }, + dhKCUV: { + type: 0, + value: "Individuelle Menge", + }, +}; diff --git a/src/__tests__/__snapshots__/index.test.js.snap b/src/__tests__/__snapshots__/index.test.js.snap index b4f78b7..fd46262 100644 --- a/src/__tests__/__snapshots__/index.test.js.snap +++ b/src/__tests__/__snapshots__/index.test.js.snap @@ -142,6 +142,64 @@ var StubImperativeLocalizationComponent = function StubImperativeLocalizationCom };" `; +exports[`babel-plugin-formatjs-localized-bundle transformers code that has been compiled by nextjs 1`] = ` +"\\"use strict\\"; + +exports.id = 885, exports.ids = [885, 26456], exports.modules = { + 359692: (e, t, n) => { + var I = e => { + var { + strictLocalize: t + } = (0, i.Pi)(), + { + backgroundColor: n = o.QY.surface.subdued, + content: E, + contentColor: _ = o.QY.text.default, + notificationDot: a + } = e, + l = t({ + id: \\"J8xC2I\\", + defaultMessage: { + \\"type\\": 0, + \\"value\\": \\"mit Benachrichtigung\\" + } + }); + return (0, r.jsxs)(A, { + backgroundColor: n, + contentColor: _, + \\"data-test-id\\": e[\\"data-test-id\\"], + className: e.className, + children: [E > 99 ? \\"99+\\" : E, a ? (0, r.jsxs)(r.Fragment, { + children: [(0, r.jsx)(R, { + children: l + }), (0, r.jsx)(T, { + children: (0, r.jsx)(O.P, {}) + })] + }) : null] + }); + }; + }, + 200077: (t, e, i) => { + var f = class extends m.Component { + constructor(t) { + super(t), this.updateCustomOptionReaction = (0, h.reaction)(() => this.props.value, t => { + !this.isValueInOptions(t) && this.props.shouldUseCustomOption && (this.customOption.value = t, this.customOption.label = this.customOptionLabel, this.hasEditedCustomOption = !0); + }), this.customQuantitySelection = !1, this.hasEditedCustomOption = !1, this.customOption = { + value: \\"\\", + label: this.props.strictLocalize({ + id: \\"dhKCUV\\", + defaultMessage: { + \\"type\\": 0, + \\"value\\": \\"Individuelle Menge\\" + } + }) + }; + } + }; + } +};" +`; + exports[`babel-plugin-formatjs-localized-bundle transpiles all types of messages 1`] = ` "var x = /*#__PURE__*/React.createElement(\\"div\\", null, /*#__PURE__*/React.createElement(LocalMsg, { id: \\"AST\\", diff --git a/src/__tests__/index.test.js b/src/__tests__/index.test.js index 909a43a..4c3e4ad 100644 --- a/src/__tests__/index.test.js +++ b/src/__tests__/index.test.js @@ -241,4 +241,51 @@ describe("babel-plugin-formatjs-localized-bundle", () => { ).code ).toMatchSnapshot(); }); + + test("transformers code that has been compiled by nextjs", function () { + expect( + transformFileSync( + path.resolve( + __dirname, + "..", + "__fixtures__", + "pre-compiled-nextjs", + "code.js" + ), + { + presets: [ + [ + "@babel/preset-env", + { + targets: { + node: "14", + esmodules: true, + }, + modules: false, + useBuiltIns: false, + ignoreBrowserslistConfig: true, + }, + ], + "@babel/preset-react", + ], + plugins: [ + [ + plugin, + { + translatedMessages: require(path.resolve( + __dirname, + "..", + "__fixtures__", + "pre-compiled-nextjs", + "mockMessages.js" + )), + additionalComponentNames: ["LocalMsg"], + additionalFunctionNames: ["localize"], + }, + ], + ], + } + ).code + ).toMatchSnapshot(); + }); }); diff --git a/src/index.js b/src/index.js index d376089..f1898d9 100644 --- a/src/index.js +++ b/src/index.js @@ -16,20 +16,9 @@ module.exports = (babel, options) => { ? require(options.translatedMessages) : options.translatedMessages; - const replaceMessageInPath = (path, argPosition) => { - const args = path.get("arguments"); - if (!args) { - return; - } - const arg = args[argPosition]; - if (!arg) { - return; - } - if (!arg.has("properties")) { - return; - } - const properties = arg.get("properties"); - const defaultMessageProp = properties.find( + const replaceMessageInPath = (path) => { + const properties = path.get("properties"); + const defaultMessageProp = properties?.find( (p) => p.has("key") && p.get("key").isIdentifier({ name: "defaultMessage" }) ); @@ -69,48 +58,21 @@ module.exports = (babel, options) => { return { name: "babel-plugin-formatjs-localized-bundle", visitor: { - CallExpression(path) { - if (!path) { - return; - } - - const { node } = path; - if ( - !( - node.callee && - (additionalFunctionName.includes(node.callee.name) || - (node.callee.property && - functionNames.includes(node.callee.property.name)) || - // This check handles pre-compiled babel code, used to extract - // messages from our shared dependencies - (node.callee.expressions && - node.callee.expressions.some( - (e) => - e.property && - additionalFunctionName.includes(e.property.name) - ))) - ) - ) { - return; - } - - replaceMessageInPath(path, 0); - }, - Identifier(path) { if (!path) { return; } - if (!componentNames.includes(path.node.name)) { + const { node } = path; + if (node.name !== "defaultMessage") { return; } - const parent = path.findParent((i) => i); + const parent = path.findParent((i) => i)?.findParent((i) => i); if (!parent) { return; } - replaceMessageInPath(parent, 1); + replaceMessageInPath(parent); }, }, }; diff --git a/yarn.lock b/yarn.lock index 8bd01e6..819189c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2503,9 +2503,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001400: - version "1.0.30001431" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz#e7c59bd1bc518fae03a4656be442ce6c4887a795" - integrity sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ== + version "1.0.30001579" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001579.tgz" + integrity sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA== cardinal@^2.1.1: version "2.1.1"