From 3b7dd233d10d1456cb4bf4e7afe6306257ee5dd7 Mon Sep 17 00:00:00 2001 From: Braden MacDonald Date: Thu, 13 Aug 2026 15:39:20 -0700 Subject: [PATCH 1/2] chore: bump react-intl to v10. Removes deprecated `injectIntl`+`intlShape` --- package-lock.json | 348 +++++----------------------- package.json | 4 +- runtime/i18n/{index.js => index.ts} | 72 +----- runtime/i18n/injectIntlWithShim.jsx | 48 ---- runtime/index.ts | 7 +- runtime/jest.config.js | 2 +- shell/jest.config.js | 2 +- tools/jest.config.js | 2 +- tools/jest/jest.config.js | 2 +- 9 files changed, 72 insertions(+), 415 deletions(-) rename runtime/i18n/{index.js => index.ts} (55%) delete mode 100644 runtime/i18n/injectIntlWithShim.jsx diff --git a/package-lock.json b/package-lock.json index cb245d16..19765913 100644 --- a/package-lock.json +++ b/package-lock.json @@ -66,7 +66,7 @@ "prop-types": "^15.8.1", "react-dev-utils": "12.0.1", "react-focus-on": "^3.10.2", - "react-intl": "^6.6.6", + "react-intl": "^10.1.20", "react-refresh": "0.18.0", "react-refresh-typescript": "^2.0.9", "react-responsive": "^10.0.0", @@ -113,7 +113,7 @@ "nodemon": "^3.1.4" }, "peerDependencies": { - "@openedx/paragon": "^23.20.0", + "@openedx/paragon": "^23.22.2", "@tanstack/react-query": "^5.81.2", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -2610,106 +2610,14 @@ } }, "node_modules/@formatjs/intl": { - "version": "2.10.15", - "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-2.10.15.tgz", - "integrity": "sha512-i6+xVqT+6KCz7nBfk4ybMXmbKO36tKvbMKtgFz9KV+8idYFyFbfwKooYk8kGjyA5+T5f1kEPQM5IDLXucTAQ9g==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-4.1.18.tgz", + "integrity": "sha512-d+AFsn+luyMAUTQImPJEK76bhEvzFKRG/1PCf1Q6sCH3ojHyHgJJkfvUFElpbDkihtm4uedK7/zoG24EL285nw==", "license": "MIT", "dependencies": { - "@formatjs/ecma402-abstract": "2.2.4", - "@formatjs/fast-memoize": "2.2.3", - "@formatjs/icu-messageformat-parser": "2.9.4", - "@formatjs/intl-displaynames": "6.8.5", - "@formatjs/intl-listformat": "7.7.5", - "intl-messageformat": "10.7.7", - "tslib": "2" - }, - "peerDependencies": { - "typescript": "^4.7 || 5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@formatjs/intl-displaynames": { - "version": "6.8.5", - "resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-6.8.5.tgz", - "integrity": "sha512-85b+GdAKCsleS6cqVxf/Aw/uBd+20EM0wDpgaxzHo3RIR3bxF4xCJqH/Grbzx8CXurTgDDZHPdPdwJC+May41w==", - "license": "MIT", - "dependencies": { - "@formatjs/ecma402-abstract": "2.2.4", - "@formatjs/intl-localematcher": "0.5.8", - "tslib": "2" - } - }, - "node_modules/@formatjs/intl-displaynames/node_modules/@formatjs/ecma402-abstract": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.4.tgz", - "integrity": "sha512-lFyiQDVvSbQOpU+WFd//ILolGj4UgA/qXrKeZxdV14uKiAUiPAtX6XAn7WBCRi7Mx6I7EybM9E5yYn4BIpZWYg==", - "license": "MIT", - "dependencies": { - "@formatjs/fast-memoize": "2.2.3", - "@formatjs/intl-localematcher": "0.5.8", - "tslib": "2" - } - }, - "node_modules/@formatjs/intl-displaynames/node_modules/@formatjs/fast-memoize": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.3.tgz", - "integrity": "sha512-3jeJ+HyOfu8osl3GNSL4vVHUuWFXR03Iz9jjgI7RwjG6ysu/Ymdr0JRCPHfF5yGbTE6JCrd63EpvX1/WybYRbA==", - "license": "MIT", - "dependencies": { - "tslib": "2" - } - }, - "node_modules/@formatjs/intl-displaynames/node_modules/@formatjs/intl-localematcher": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.8.tgz", - "integrity": "sha512-I+WDNWWJFZie+jkfkiK5Mp4hEDyRSEvmyfYadflOno/mmKJKcB17fEpEH0oJu/OWhhCJ8kJBDz2YMd/6cDl7Mg==", - "license": "MIT", - "dependencies": { - "tslib": "2" - } - }, - "node_modules/@formatjs/intl-listformat": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-7.7.5.tgz", - "integrity": "sha512-Wzes10SMNeYgnxYiKsda4rnHP3Q3II4XT2tZyOgnH5fWuHDtIkceuWlRQNsvrI3uiwP4hLqp2XdQTCsfkhXulg==", - "license": "MIT", - "dependencies": { - "@formatjs/ecma402-abstract": "2.2.4", - "@formatjs/intl-localematcher": "0.5.8", - "tslib": "2" - } - }, - "node_modules/@formatjs/intl-listformat/node_modules/@formatjs/ecma402-abstract": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.4.tgz", - "integrity": "sha512-lFyiQDVvSbQOpU+WFd//ILolGj4UgA/qXrKeZxdV14uKiAUiPAtX6XAn7WBCRi7Mx6I7EybM9E5yYn4BIpZWYg==", - "license": "MIT", - "dependencies": { - "@formatjs/fast-memoize": "2.2.3", - "@formatjs/intl-localematcher": "0.5.8", - "tslib": "2" - } - }, - "node_modules/@formatjs/intl-listformat/node_modules/@formatjs/fast-memoize": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.3.tgz", - "integrity": "sha512-3jeJ+HyOfu8osl3GNSL4vVHUuWFXR03Iz9jjgI7RwjG6ysu/Ymdr0JRCPHfF5yGbTE6JCrd63EpvX1/WybYRbA==", - "license": "MIT", - "dependencies": { - "tslib": "2" - } - }, - "node_modules/@formatjs/intl-listformat/node_modules/@formatjs/intl-localematcher": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.8.tgz", - "integrity": "sha512-I+WDNWWJFZie+jkfkiK5Mp4hEDyRSEvmyfYadflOno/mmKJKcB17fEpEH0oJu/OWhhCJ8kJBDz2YMd/6cDl7Mg==", - "license": "MIT", - "dependencies": { - "tslib": "2" + "@formatjs/fast-memoize": "3.1.7", + "@formatjs/icu-messageformat-parser": "3.5.16", + "intl-messageformat": "11.2.13" } }, "node_modules/@formatjs/intl-localematcher": { @@ -2721,55 +2629,26 @@ "tslib": "^2.8.0" } }, - "node_modules/@formatjs/intl/node_modules/@formatjs/ecma402-abstract": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.4.tgz", - "integrity": "sha512-lFyiQDVvSbQOpU+WFd//ILolGj4UgA/qXrKeZxdV14uKiAUiPAtX6XAn7WBCRi7Mx6I7EybM9E5yYn4BIpZWYg==", - "license": "MIT", - "dependencies": { - "@formatjs/fast-memoize": "2.2.3", - "@formatjs/intl-localematcher": "0.5.8", - "tslib": "2" - } - }, "node_modules/@formatjs/intl/node_modules/@formatjs/fast-memoize": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.3.tgz", - "integrity": "sha512-3jeJ+HyOfu8osl3GNSL4vVHUuWFXR03Iz9jjgI7RwjG6ysu/Ymdr0JRCPHfF5yGbTE6JCrd63EpvX1/WybYRbA==", - "license": "MIT", - "dependencies": { - "tslib": "2" - } + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-3.1.7.tgz", + "integrity": "sha512-zXfhLpvA6T7+efdt9JLbBwZ00tT7NsBMDVnDu8rpHeNNv8KfRZAMo2gkG0k9lK/Nzc//3kJ9pImsfuJxk3KhUA==", + "license": "MIT" }, "node_modules/@formatjs/intl/node_modules/@formatjs/icu-messageformat-parser": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.9.4.tgz", - "integrity": "sha512-Tbvp5a9IWuxUcpWNIW6GlMQYEc4rwNHR259uUFoKWNN1jM9obf9Ul0e+7r7MvFOBNcN+13K7NuKCKqQiAn1QEg==", + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.16.tgz", + "integrity": "sha512-kl6b/4D56gjGZi4ZewSmvXbalHwjOUI5ogEHPZqw42goeXTTrL7/yuPzvdrvr0QigDtvaOeb+UeMf62jks43Yg==", "license": "MIT", "dependencies": { - "@formatjs/ecma402-abstract": "2.2.4", - "@formatjs/icu-skeleton-parser": "1.8.8", - "tslib": "2" + "@formatjs/icu-skeleton-parser": "2.1.11" } }, "node_modules/@formatjs/intl/node_modules/@formatjs/icu-skeleton-parser": { - "version": "1.8.8", - "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.8.tgz", - "integrity": "sha512-vHwK3piXwamFcx5YQdCdJxUQ1WdTl6ANclt5xba5zLGDv5Bsur7qz8AD7BevaKxITwpgDeU0u8My3AIibW9ywA==", - "license": "MIT", - "dependencies": { - "@formatjs/ecma402-abstract": "2.2.4", - "tslib": "2" - } - }, - "node_modules/@formatjs/intl/node_modules/@formatjs/intl-localematcher": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.8.tgz", - "integrity": "sha512-I+WDNWWJFZie+jkfkiK5Mp4hEDyRSEvmyfYadflOno/mmKJKcB17fEpEH0oJu/OWhhCJ8kJBDz2YMd/6cDl7Mg==", - "license": "MIT", - "dependencies": { - "tslib": "2" - } + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.11.tgz", + "integrity": "sha512-j8cUmOJzVgkHuS0QiQ6ga76UIoLOFSAMWhs7aZJztH3aAdCOAE6vpC8KVvFB4cU10ON0y2/5oOVmPJ43s2lTwA==", + "license": "MIT" }, "node_modules/@formatjs/ts-transformer": { "version": "3.14.2", @@ -4365,9 +4244,9 @@ } }, "node_modules/@openedx/paragon": { - "version": "23.21.1", - "resolved": "https://registry.npmjs.org/@openedx/paragon/-/paragon-23.21.1.tgz", - "integrity": "sha512-jD7fIaILgqiiDXuUTg5hXgZxI8Ei5x2l2fzSElCTGY7qEYQwd/F3am9UFDp/60mp84L9AlyNW21Hlj0X4e8lYA==", + "version": "23.23.0", + "resolved": "https://registry.npmjs.org/@openedx/paragon/-/paragon-23.23.0.tgz", + "integrity": "sha512-dr4zDytE7YC/Hk3sIl3MBgLyeIJBZpPp0tI2x+SQ1d/tJXhyJk4pDOfG8bFbGHt4jaM/cwjwX25jaTUV1jszIg==", "license": "Apache-2.0", "peer": true, "workspaces": [ @@ -4383,7 +4262,6 @@ "axios": "^1.0.0", "bootstrap": "^4.6.2", "chalk": "^4.1.2", - "child_process": "^1.0.2", "chroma-js": "^3.0.0", "classnames": "^2.3.1", "cli-progress": "^3.12.0", @@ -4429,7 +4307,7 @@ "peerDependencies": { "react": "^16.8.6 || ^17 || ^18", "react-dom": "^16.8.6 || ^17 || ^18", - "react-intl": "^5.25.1 || ^6.4.0" + "react-intl": "^5.25.1 || ^6.4.0 || ^10.1.20" } }, "node_modules/@openedx/paragon/node_modules/glob": { @@ -5517,18 +5395,6 @@ "@types/tinycolor2": "*" } }, - "node_modules/@types/hoist-non-react-statics": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.7.tgz", - "integrity": "sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==", - "license": "MIT", - "dependencies": { - "hoist-non-react-statics": "^3.3.0" - }, - "peerDependencies": { - "@types/react": "*" - } - }, "node_modules/@types/html-minifier-terser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", @@ -7644,13 +7510,6 @@ "license": "MIT", "peer": true }, - "node_modules/child_process": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz", - "integrity": "sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g==", - "license": "ISC", - "peer": true - }, "node_modules/chokidar": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", @@ -10975,21 +10834,6 @@ "he": "bin/he" } }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "license": "BSD-3-Clause", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hoist-non-react-statics/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT" - }, "node_modules/hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", @@ -11580,66 +11424,35 @@ } }, "node_modules/intl-messageformat": { - "version": "10.7.7", - "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.7.tgz", - "integrity": "sha512-F134jIoeYMro/3I0h08D0Yt4N9o9pjddU/4IIxMMURqbAtI2wu70X8hvG1V48W49zXHXv3RKSF/po+0fDfsGjA==", + "version": "11.2.13", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-11.2.13.tgz", + "integrity": "sha512-JaPaE6TIX+TAS5XLhDUh41geLw4QfBHX4s5pW8Km+L9fVC8HzB9yOuhbh4EMR/F1+8C6b9qk4763Cv+LdOG1kg==", "license": "BSD-3-Clause", "dependencies": { - "@formatjs/ecma402-abstract": "2.2.4", - "@formatjs/fast-memoize": "2.2.3", - "@formatjs/icu-messageformat-parser": "2.9.4", - "tslib": "2" - } - }, - "node_modules/intl-messageformat/node_modules/@formatjs/ecma402-abstract": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.4.tgz", - "integrity": "sha512-lFyiQDVvSbQOpU+WFd//ILolGj4UgA/qXrKeZxdV14uKiAUiPAtX6XAn7WBCRi7Mx6I7EybM9E5yYn4BIpZWYg==", - "license": "MIT", - "dependencies": { - "@formatjs/fast-memoize": "2.2.3", - "@formatjs/intl-localematcher": "0.5.8", - "tslib": "2" + "@formatjs/fast-memoize": "3.1.7", + "@formatjs/icu-messageformat-parser": "3.5.16" } }, "node_modules/intl-messageformat/node_modules/@formatjs/fast-memoize": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.3.tgz", - "integrity": "sha512-3jeJ+HyOfu8osl3GNSL4vVHUuWFXR03Iz9jjgI7RwjG6ysu/Ymdr0JRCPHfF5yGbTE6JCrd63EpvX1/WybYRbA==", - "license": "MIT", - "dependencies": { - "tslib": "2" - } + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-3.1.7.tgz", + "integrity": "sha512-zXfhLpvA6T7+efdt9JLbBwZ00tT7NsBMDVnDu8rpHeNNv8KfRZAMo2gkG0k9lK/Nzc//3kJ9pImsfuJxk3KhUA==", + "license": "MIT" }, "node_modules/intl-messageformat/node_modules/@formatjs/icu-messageformat-parser": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.9.4.tgz", - "integrity": "sha512-Tbvp5a9IWuxUcpWNIW6GlMQYEc4rwNHR259uUFoKWNN1jM9obf9Ul0e+7r7MvFOBNcN+13K7NuKCKqQiAn1QEg==", + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.16.tgz", + "integrity": "sha512-kl6b/4D56gjGZi4ZewSmvXbalHwjOUI5ogEHPZqw42goeXTTrL7/yuPzvdrvr0QigDtvaOeb+UeMf62jks43Yg==", "license": "MIT", "dependencies": { - "@formatjs/ecma402-abstract": "2.2.4", - "@formatjs/icu-skeleton-parser": "1.8.8", - "tslib": "2" + "@formatjs/icu-skeleton-parser": "2.1.11" } }, "node_modules/intl-messageformat/node_modules/@formatjs/icu-skeleton-parser": { - "version": "1.8.8", - "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.8.tgz", - "integrity": "sha512-vHwK3piXwamFcx5YQdCdJxUQ1WdTl6ANclt5xba5zLGDv5Bsur7qz8AD7BevaKxITwpgDeU0u8My3AIibW9ywA==", - "license": "MIT", - "dependencies": { - "@formatjs/ecma402-abstract": "2.2.4", - "tslib": "2" - } - }, - "node_modules/intl-messageformat/node_modules/@formatjs/intl-localematcher": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.8.tgz", - "integrity": "sha512-I+WDNWWJFZie+jkfkiK5Mp4hEDyRSEvmyfYadflOno/mmKJKcB17fEpEH0oJu/OWhhCJ8kJBDz2YMd/6cDl7Mg==", - "license": "MIT", - "dependencies": { - "tslib": "2" - } + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.11.tgz", + "integrity": "sha512-j8cUmOJzVgkHuS0QiQ6ga76UIoLOFSAMWhs7aZJztH3aAdCOAE6vpC8KVvFB4cU10ON0y2/5oOVmPJ43s2lTwA==", + "license": "MIT" }, "node_modules/invariant": { "version": "2.2.4", @@ -17000,81 +16813,34 @@ } }, "node_modules/react-intl": { - "version": "6.8.9", - "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-6.8.9.tgz", - "integrity": "sha512-TUfj5E7lyUDvz/GtovC9OMh441kBr08rtIbgh3p0R8iF3hVY+V2W9Am7rb8BpJ/29BH1utJOqOOhmvEVh3GfZg==", + "version": "10.1.20", + "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-10.1.20.tgz", + "integrity": "sha512-dvD9F7CqjlB/cIWakFzScGVPDmhWk34cFWY0etWuVNc07Zmc56OKjQwqu9q74evbttSto5wFXchZtvdRXy/Tkg==", "license": "BSD-3-Clause", "dependencies": { - "@formatjs/ecma402-abstract": "2.2.4", - "@formatjs/icu-messageformat-parser": "2.9.4", - "@formatjs/intl": "2.10.15", - "@formatjs/intl-displaynames": "6.8.5", - "@formatjs/intl-listformat": "7.7.5", - "@types/hoist-non-react-statics": "3", - "@types/react": "16 || 17 || 18", - "hoist-non-react-statics": "3", - "intl-messageformat": "10.7.7", - "tslib": "2" + "@formatjs/icu-messageformat-parser": "3.5.16", + "@formatjs/intl": "4.1.18", + "intl-messageformat": "11.2.13" }, "peerDependencies": { - "react": "^16.6.0 || 17 || 18", - "typescript": "^4.7 || 5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/react-intl/node_modules/@formatjs/ecma402-abstract": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.4.tgz", - "integrity": "sha512-lFyiQDVvSbQOpU+WFd//ILolGj4UgA/qXrKeZxdV14uKiAUiPAtX6XAn7WBCRi7Mx6I7EybM9E5yYn4BIpZWYg==", - "license": "MIT", - "dependencies": { - "@formatjs/fast-memoize": "2.2.3", - "@formatjs/intl-localematcher": "0.5.8", - "tslib": "2" - } - }, - "node_modules/react-intl/node_modules/@formatjs/fast-memoize": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.3.tgz", - "integrity": "sha512-3jeJ+HyOfu8osl3GNSL4vVHUuWFXR03Iz9jjgI7RwjG6ysu/Ymdr0JRCPHfF5yGbTE6JCrd63EpvX1/WybYRbA==", - "license": "MIT", - "dependencies": { - "tslib": "2" + "@types/react": ">=18.0.0", + "react": ">=18.0.0" } }, "node_modules/react-intl/node_modules/@formatjs/icu-messageformat-parser": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.9.4.tgz", - "integrity": "sha512-Tbvp5a9IWuxUcpWNIW6GlMQYEc4rwNHR259uUFoKWNN1jM9obf9Ul0e+7r7MvFOBNcN+13K7NuKCKqQiAn1QEg==", + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.16.tgz", + "integrity": "sha512-kl6b/4D56gjGZi4ZewSmvXbalHwjOUI5ogEHPZqw42goeXTTrL7/yuPzvdrvr0QigDtvaOeb+UeMf62jks43Yg==", "license": "MIT", "dependencies": { - "@formatjs/ecma402-abstract": "2.2.4", - "@formatjs/icu-skeleton-parser": "1.8.8", - "tslib": "2" + "@formatjs/icu-skeleton-parser": "2.1.11" } }, "node_modules/react-intl/node_modules/@formatjs/icu-skeleton-parser": { - "version": "1.8.8", - "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.8.tgz", - "integrity": "sha512-vHwK3piXwamFcx5YQdCdJxUQ1WdTl6ANclt5xba5zLGDv5Bsur7qz8AD7BevaKxITwpgDeU0u8My3AIibW9ywA==", - "license": "MIT", - "dependencies": { - "@formatjs/ecma402-abstract": "2.2.4", - "tslib": "2" - } - }, - "node_modules/react-intl/node_modules/@formatjs/intl-localematcher": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.8.tgz", - "integrity": "sha512-I+WDNWWJFZie+jkfkiK5Mp4hEDyRSEvmyfYadflOno/mmKJKcB17fEpEH0oJu/OWhhCJ8kJBDz2YMd/6cDl7Mg==", - "license": "MIT", - "dependencies": { - "tslib": "2" - } + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.11.tgz", + "integrity": "sha512-j8cUmOJzVgkHuS0QiQ6ga76UIoLOFSAMWhs7aZJztH3aAdCOAE6vpC8KVvFB4cU10ON0y2/5oOVmPJ43s2lTwA==", + "license": "MIT" }, "node_modules/react-is": { "version": "17.0.2", diff --git a/package.json b/package.json index 49832f58..c5b3a496 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "prop-types": "^15.8.1", "react-dev-utils": "12.0.1", "react-focus-on": "^3.10.2", - "react-intl": "^6.6.6", + "react-intl": "^10.1.20", "react-refresh": "0.18.0", "react-refresh-typescript": "^2.0.9", "react-responsive": "^10.0.0", @@ -160,7 +160,7 @@ "nodemon": "^3.1.4" }, "peerDependencies": { - "@openedx/paragon": "^23.20.0", + "@openedx/paragon": "^23.22.2", "@tanstack/react-query": "^5.81.2", "react": "^18.3.1", "react-dom": "^18.3.1", diff --git a/runtime/i18n/index.js b/runtime/i18n/index.ts similarity index 55% rename from runtime/i18n/index.js rename to runtime/i18n/index.ts index 0aa71cc2..32228608 100644 --- a/runtime/i18n/index.js +++ b/runtime/i18n/index.ts @@ -23,66 +23,6 @@ * */ -/** - * @name createIntl - * @kind function - * @see {@link https://formatjs.io/docs/react-intl/api#createIntl Intl} - */ - -/** - * @name FormattedDate - * @kind class - * @see {@link https://formatjs.io/docs/react-intl/components/#formatteddate Intl} - */ - -/** - * @name FormattedTime - * @kind class - * @see {@link https://formatjs.io/docs/react-intl/components/#formattedtime Intl} - */ - -/** - * @name FormattedRelativeTime - * @kind class - * @see {@link https://formatjs.io/docs/react-intl/components/#formattedrelativetime Intl} - */ - -/** - * @name FormattedNumber - * @kind class - * @see {@link https://formatjs.io/docs/react-intl/components/#formattednumber Intl} - */ - -/** - * @name FormattedPlural - * @kind class - * @see {@link https://formatjs.io/docs/react-intl/components/#formattedplural Intl} - */ - -/** - * @name FormattedMessage - * @kind class - * @see {@link https://formatjs.io/docs/react-intl/components/#formattedmessage Intl} - */ - -/** - * @name IntlProvider - * @kind class - * @see {@link https://formatjs.io/docs/react-intl/components/#intlprovider Intl} - */ - -/** - * @name defineMessages - * @kind function - * @see {@link https://formatjs.io/docs/react-intl/api#definemessagesdefinemessage Intl} - */ - -/** - * @name useIntl - * @kind function - * @see {@link https://formatjs.io/docs/react-intl/api#useIntl Intl} - */ - export { createIntl, defineMessages, @@ -93,7 +33,10 @@ export { FormattedRelativeTime, FormattedTime, IntlProvider, - useIntl + useIntl, + type IntlConfig, + type ResolvedIntlConfig, + type IntlShape, } from 'react-intl'; export { @@ -104,14 +47,9 @@ export { getPrimaryLanguageSubtag, getSupportedLanguageList, handleRtl, - intlShape, isRtl, LOCALE_CHANGED, LOCALE_TOPIC, mergeMessages, - updateLocale + updateLocale, } from './lib'; - -export { - default as injectIntl -} from './injectIntlWithShim'; diff --git a/runtime/i18n/injectIntlWithShim.jsx b/runtime/i18n/injectIntlWithShim.jsx deleted file mode 100644 index b4717119..00000000 --- a/runtime/i18n/injectIntlWithShim.jsx +++ /dev/null @@ -1,48 +0,0 @@ -import React from 'react'; -import { injectIntl } from 'react-intl'; -import { EnvironmentTypes } from '../../types'; -import { getSiteConfig } from '../config'; -import { getLoggingService } from '../logging'; -import { intlShape } from './lib'; - -/** - * This function wraps react-intl's injectIntl function in order to add error logging to the intl - * property's formatMessage function. - * - * @memberof I18n - */ -const injectIntlWithShim = (WrappedComponent) => { - class ShimmedIntlComponent extends React.Component { - constructor(props) { - super(props); - this.shimmedIntl = Object.create(this.props.intl, { - formatMessage: { - value: (definition, ...args) => { - if (definition === undefined || definition.id === undefined) { - const error = new Error('i18n error: An undefined message was supplied to intl.formatMessage.'); - if (getSiteConfig().environment === EnvironmentTypes.DEVELOPMENT) { - console.error(error); // eslint-disable-line no-console - return '!!! Missing message supplied to intl.formatMessage !!!'; - } - getLoggingService().logError(error); - return ''; // Fail silently in production - } - return this.props.intl.formatMessage(definition, ...args); - }, - }, - }); - } - - render() { - return ; - } - } - - ShimmedIntlComponent.propTypes = { - intl: intlShape.isRequired, - }; - - return injectIntl(ShimmedIntlComponent); -}; - -export default injectIntlWithShim; diff --git a/runtime/index.ts b/runtime/index.ts index 2cc94a7d..c21c801d 100644 --- a/runtime/index.ts +++ b/runtime/index.ts @@ -67,15 +67,16 @@ export { getPrimaryLanguageSubtag, getSupportedLanguageList, handleRtl, - injectIntl, IntlProvider, - intlShape, isRtl, LOCALE_CHANGED, LOCALE_TOPIC, mergeMessages, updateLocale, - useIntl + useIntl, + type IntlConfig, + type ResolvedIntlConfig, + type IntlShape, } from './i18n'; export { diff --git a/runtime/jest.config.js b/runtime/jest.config.js index 27050a5f..dc221e49 100644 --- a/runtime/jest.config.js +++ b/runtime/jest.config.js @@ -19,7 +19,7 @@ module.exports = { '/setupTest.js', ], transformIgnorePatterns: [ - '/node_modules/(?!(@openedx|@edx)/)', + '/node_modules/(?!(@openedx|@edx|react-intl|@formatjs|intl-messageformat)/)', ], modulePathIgnorePatterns: [ '/dist/', diff --git a/shell/jest.config.js b/shell/jest.config.js index 706927c3..20f2b543 100644 --- a/shell/jest.config.js +++ b/shell/jest.config.js @@ -20,7 +20,7 @@ module.exports = { 'setupTest.js', ], transformIgnorePatterns: [ - '/node_modules/(?!(@openedx|@edx)/)', + '/node_modules/(?!(@openedx|@edx|react-intl|@formatjs|intl-messageformat)/)', ], testPathIgnorePatterns: [ '/site.config.test.tsx', diff --git a/tools/jest.config.js b/tools/jest.config.js index af945138..d2c14450 100644 --- a/tools/jest.config.js +++ b/tools/jest.config.js @@ -7,7 +7,7 @@ module.exports = { 'cli/**/*.{js,jsx,ts,tsx}', ], transformIgnorePatterns: [ - '/node_modules/(?!(@openedx|@edx)/)', + '/node_modules/(?!(@openedx|@edx|react-intl|@formatjs|intl-messageformat)/)', ], modulePathIgnorePatterns: [ '/dist/', diff --git a/tools/jest/jest.config.js b/tools/jest/jest.config.js index f601ce3e..017f4243 100644 --- a/tools/jest/jest.config.js +++ b/tools/jest/jest.config.js @@ -17,7 +17,7 @@ module.exports = { '/node_modules/', ], transformIgnorePatterns: [ - '/node_modules/(?!(@openedx|@edx)/)', + '/node_modules/(?!(@openedx|@edx|react-intl|@formatjs|intl-messageformat)/)', ], modulePathIgnorePatterns: [ '/dist/', From f2c85233ffe7acfcbca4f4193062162222ee741c Mon Sep 17 00:00:00 2001 From: Braden MacDonald Date: Thu, 13 Aug 2026 15:44:05 -0700 Subject: [PATCH 2/2] chore: fix a TypeScript error --- shell/header/helpButtonSlotOperation.test.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shell/header/helpButtonSlotOperation.test.tsx b/shell/header/helpButtonSlotOperation.test.tsx index 3311f41f..c28bed19 100644 --- a/shell/header/helpButtonSlotOperation.test.tsx +++ b/shell/header/helpButtonSlotOperation.test.tsx @@ -19,6 +19,8 @@ describe('helpButtonSlotOperation', () => { mergeAppConfig(TEST_APP_ID, { SUPPORT_URL: 'https://help.example.com/test' }); const op = helpButtonSlotOperation({ appId: TEST_APP_ID, role: TEST_ROLE }); + // The following is for TypeScript, since `WidgetRendererProps` sometimes has 'element' and sometimes 'component'. + if (!('element' in op)) throw new Error(`Expected ${op} to have an 'element'.`); expect(isValidElement(op.element)).toBe(true); const getUrl = (op.element as React.ReactElement<{ getUrl: () => string | undefined }>).props.getUrl;