diff --git a/package-lock.json b/package-lock.json index 0f0a610..738c17f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0-dev", "license": "AGPL-3.0", "devDependencies": { - "@openedx/frontend-base": "^1.0.0 || 0.0.0-dev", + "@openedx/frontend-base": "^2.0.0-alpha.2 || 0.0.0-dev", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.0", "@types/jest": "^29.5.14", @@ -22,7 +22,8 @@ "tsc-alias": "^1.8.16" }, "peerDependencies": { - "@openedx/frontend-base": "^1.0.0 || 0.0.0-dev", + "@openedx/frontend-base": "^2.0.0-alpha.2 || 0.0.0-dev", + "prop-types": "*", "react": "^18" } }, @@ -1881,9 +1882,9 @@ } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.29.2.tgz", - "integrity": "sha512-Lc94FOD5+0aXhdb0Tdg3RUtqT6yWbI/BbFWvlaSJ3gAb9Ks+99nHRDKADVqC37er4eCB0fHyWT+y+K3QOvJKbw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.29.7.tgz", + "integrity": "sha512-ppj9ouYku+RX0ljtgZd+KMO5mkM2bCqg8H2PYAFWnLsHEIKIdRojqbJ2i3eVHrisuxy7nOFCmngTDdWtUCdXUQ==", "dev": true, "license": "MIT", "peer": true, @@ -1957,11 +1958,11 @@ "license": "(Apache-2.0 AND BSD-3-Clause)" }, "node_modules/@bundled-es-modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@bundled-es-modules/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-Rk453EklPUPC3NRWc3VUNI/SSUjdBaFoaQvFRmNBNtMHVtOFD5AntiWg5kEE1hqcPqedYFDzxE3ZcMYPcA195w==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/deepmerge/-/deepmerge-4.3.2.tgz", + "integrity": "sha512-q8doe7ndrY2IolUOFIn0A0++JBX38pMhN7kFhTF4cnjIcILf6X6H2yWczInyv8ZFdR0lrE8088X8XS5efxXz8A==", "dev": true, - "license": "ISC", + "license": "MIT", "peer": true, "dependencies": { "deepmerge": "^4.3.1" @@ -1995,9 +1996,9 @@ "peer": true }, "node_modules/@bundled-es-modules/glob/node_modules/brace-expansion": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", - "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", "dev": true, "license": "MIT", "peer": true, @@ -2088,6 +2089,318 @@ "util": "^0.12.5" } }, + "node_modules/@bundled-es-modules/memfs/node_modules/@jsonjoy.com/base64": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.67.0.tgz", + "integrity": "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@bundled-es-modules/memfs/node_modules/@jsonjoy.com/codegen": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.67.0.tgz", + "integrity": "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@bundled-es-modules/memfs/node_modules/@jsonjoy.com/fs-core": { + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.68.1.tgz", + "integrity": "sha512-V5oZ4Gt9WJKyQef0n9cAd0N9qjSkIBm3E4MYsgNIWBk5aINCDPKxMPo1i29rBxqiT4Ixf1epklqV9VJMKIxwlw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.68.1", + "@jsonjoy.com/fs-node-utils": "4.68.1", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@bundled-es-modules/memfs/node_modules/@jsonjoy.com/fs-fsa": { + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.68.1.tgz", + "integrity": "sha512-HCG72UioncuO7Gw09XNVG+S85e3cq2hrUC/mexBrsWsa3mI7eePkkqWie3uVYbtsb64OR9YGQs5SqaufDRYBcg==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@jsonjoy.com/fs-core": "4.68.1", + "@jsonjoy.com/fs-node-builtins": "4.68.1", + "@jsonjoy.com/fs-node-utils": "4.68.1", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@bundled-es-modules/memfs/node_modules/@jsonjoy.com/fs-node": { + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.68.1.tgz", + "integrity": "sha512-R5D9mWtqdURzcOWj1vdXr3APCwX0xchtFT+kmW7fXLNDifWdDrnh26jSID8pdnUfFBxTyfHtFtTL/NWKzIH7kQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@jsonjoy.com/fs-core": "4.68.1", + "@jsonjoy.com/fs-node-builtins": "4.68.1", + "@jsonjoy.com/fs-node-utils": "4.68.1", + "@jsonjoy.com/fs-print": "4.68.1", + "@jsonjoy.com/fs-snapshot": "4.68.1", + "glob-to-regex.js": "^1.0.0", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@bundled-es-modules/memfs/node_modules/@jsonjoy.com/fs-node-builtins": { + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.68.1.tgz", + "integrity": "sha512-HK1BTksysokNZxNspqDH0yPaqN9YgR/AYIlYiIaU2Ys4BOk5CdybI7r6BgiZuiiPiV8n4sK/kZdice7Znpy2Kw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@bundled-es-modules/memfs/node_modules/@jsonjoy.com/fs-node-to-fsa": { + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.68.1.tgz", + "integrity": "sha512-lpKmU4X9e/oh8GIuAI7EXaS5QiLNM3KD15CkdhfS6PYmrGvoJqKQcyEfnLgnnaGslh/PFUMYSIZBCf2ejJGw8g==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@jsonjoy.com/fs-fsa": "4.68.1", + "@jsonjoy.com/fs-node-builtins": "4.68.1", + "@jsonjoy.com/fs-node-utils": "4.68.1" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@bundled-es-modules/memfs/node_modules/@jsonjoy.com/fs-node-utils": { + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.68.1.tgz", + "integrity": "sha512-/GxfW1DWm9SCdkfbvqevLO/P5duobQfmKkHXxdMIDbcZMQeAgooAstIfZhkXpATzq9QbCQsnoWFM/dGHdZfndw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.68.1", + "glob-to-regex.js": "^1.0.1" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@bundled-es-modules/memfs/node_modules/@jsonjoy.com/fs-print": { + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.68.1.tgz", + "integrity": "sha512-oGeZOGPYKK9v1CgeVeEDsLomH1lCnslSpqUN5GmPzrmAVGQlsmsdcXNA2O4lV8Y4xkuSuynx2ITBkUHJVaTbow==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@jsonjoy.com/fs-node-utils": "4.68.1", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@bundled-es-modules/memfs/node_modules/@jsonjoy.com/fs-snapshot": { + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.68.1.tgz", + "integrity": "sha512-XZfP0FDZN32bbc4t2bZN2qRrYHg5AktJnzk22HRoKGK4BprrbNRH2k5ceSNS/kupKYcofCs+O841+xaAbjnxwQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@jsonjoy.com/buffers": "^17.65.0", + "@jsonjoy.com/fs-node-utils": "4.68.1", + "@jsonjoy.com/json-pack": "^17.65.0", + "@jsonjoy.com/util": "^17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@bundled-es-modules/memfs/node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-17.67.0.tgz", + "integrity": "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@jsonjoy.com/base64": "17.67.0", + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0", + "@jsonjoy.com/json-pointer": "17.67.0", + "@jsonjoy.com/util": "17.67.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@bundled-es-modules/memfs/node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.67.0.tgz", + "integrity": "sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@bundled-es-modules/memfs/node_modules/@jsonjoy.com/json-pointer": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-17.67.0.tgz", + "integrity": "sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@jsonjoy.com/util": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@bundled-es-modules/memfs/node_modules/@jsonjoy.com/json-pointer/node_modules/@jsonjoy.com/util": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.67.0.tgz", + "integrity": "sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, "node_modules/@bundled-es-modules/memfs/node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", @@ -2115,21 +2428,21 @@ } }, "node_modules/@bundled-es-modules/memfs/node_modules/memfs": { - "version": "4.57.2", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.57.2.tgz", - "integrity": "sha512-2nWzSsJzrukurSDna4Z0WywuScK4Id3tSKejgu74u8KCdW4uNrseKRSIDg75C6Yw5ZRqBe0F0EtMNlTbUq8bAQ==", + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.68.1.tgz", + "integrity": "sha512-OD+IDRUvIxu3QHL+nFm9gdyugInD27FDJ+sl4B5QgomPHXMlbw+GP918P8VNKu2FkNlVeqBkpzkwROpamVifRw==", "dev": true, "license": "Apache-2.0", "peer": true, "dependencies": { - "@jsonjoy.com/fs-core": "4.57.2", - "@jsonjoy.com/fs-fsa": "4.57.2", - "@jsonjoy.com/fs-node": "4.57.2", - "@jsonjoy.com/fs-node-builtins": "4.57.2", - "@jsonjoy.com/fs-node-to-fsa": "4.57.2", - "@jsonjoy.com/fs-node-utils": "4.57.2", - "@jsonjoy.com/fs-print": "4.57.2", - "@jsonjoy.com/fs-snapshot": "4.57.2", + "@jsonjoy.com/fs-core": "4.68.1", + "@jsonjoy.com/fs-fsa": "4.68.1", + "@jsonjoy.com/fs-node": "4.68.1", + "@jsonjoy.com/fs-node-builtins": "4.68.1", + "@jsonjoy.com/fs-node-to-fsa": "4.68.1", + "@jsonjoy.com/fs-node-utils": "4.68.1", + "@jsonjoy.com/fs-print": "4.68.1", + "@jsonjoy.com/fs-snapshot": "4.68.1", "@jsonjoy.com/json-pack": "^1.11.0", "@jsonjoy.com/util": "^1.9.0", "glob-to-regex.js": "^1.0.1", @@ -2140,9 +2453,6 @@ "funding": { "type": "github", "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" } }, "node_modules/@bundled-es-modules/postcss-calc-ast-parser": { @@ -2674,115 +2984,15 @@ } }, "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==", - "dev": true, - "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==", - "dev": true, - "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==", - "dev": true, - "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==", - "dev": true, - "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==", - "dev": true, - "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==", - "dev": true, - "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==", - "dev": true, - "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==", - "dev": true, - "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==", + "version": "4.1.19", + "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-4.1.19.tgz", + "integrity": "sha512-bZMROATl+rzfL8wsDZ53i8XWHx5e6rVr8QlGT5GDvHImEUro4WE9pxUd2dobzmI3CtD+zkt/wkEdqcb+3CK8Fg==", "dev": true, "license": "MIT", "dependencies": { - "tslib": "2" + "@formatjs/fast-memoize": "3.1.7", + "@formatjs/icu-messageformat-parser": "3.5.17", + "intl-messageformat": "11.2.14" } }, "node_modules/@formatjs/intl-localematcher": { @@ -2795,60 +3005,29 @@ "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==", - "dev": true, - "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==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-3.1.7.tgz", + "integrity": "sha512-zXfhLpvA6T7+efdt9JLbBwZ00tT7NsBMDVnDu8rpHeNNv8KfRZAMo2gkG0k9lK/Nzc//3kJ9pImsfuJxk3KhUA==", "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "2" - } + "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.17", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.17.tgz", + "integrity": "sha512-cN9jhVqT7u0K9tix43fhjoUwL0nazyW6zsNIXs2QdPADr+nurPfYyssUiMqcSCGlPcCiqnYVxgSn7zBSuI+5Bg==", "dev": true, "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==", + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.11.tgz", + "integrity": "sha512-j8cUmOJzVgkHuS0QiQ6ga76UIoLOFSAMWhs7aZJztH3aAdCOAE6vpC8KVvFB4cU10ON0y2/5oOVmPJ43s2lTwA==", "dev": true, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "2" - } + "license": "MIT" }, "node_modules/@formatjs/ts-transformer": { "version": "3.14.2", @@ -3501,9 +3680,9 @@ } }, "node_modules/@inquirer/external-editor/node_modules/iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", "dev": true, "license": "MIT", "peer": true, @@ -3538,9 +3717,9 @@ } }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", "dev": true, "license": "MIT", "peer": true, @@ -4570,9 +4749,9 @@ } }, "node_modules/@openedx/frontend-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@openedx/frontend-base/-/frontend-base-1.0.1.tgz", - "integrity": "sha512-Xi5D2SqXxTgbGzZRM3F0oSCJkR+6KWnGULAmfw3TQOkmJ43jDIZ0BZ1XrJySScaSXkibG4OZCtcHSjV4IHgm/g==", + "version": "2.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/@openedx/frontend-base/-/frontend-base-2.0.0-alpha.2.tgz", + "integrity": "sha512-oddGOEgY2KV6Qw1IRNPObSjqktXipYc2fpGSc75atj2pw2naoroYm6BbgsOIo0XQ8Njoa66H+9Iaa0KlPwPNXg==", "dev": true, "license": "AGPL-3.0", "dependencies": { @@ -4633,7 +4812,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", @@ -4662,7 +4841,7 @@ "openedx": "dist/tools/cli/openedx.js" }, "peerDependencies": { - "@openedx/paragon": "^23.20.0", + "@openedx/paragon": "^23.23.0", "@tanstack/react-query": "^5.81.2", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -4671,9 +4850,9 @@ } }, "node_modules/@openedx/paragon": { - "version": "23.21.3", - "resolved": "https://registry.npmjs.org/@openedx/paragon/-/paragon-23.21.3.tgz", - "integrity": "sha512-xNyjxK182zKbeHJuBnbN5JAx/Lji5B0ws9kbX45mkvQ7zZcWzn3/o4nIyOb2m/1Mfocd4WbrHG9BDWUtnjkblQ==", + "version": "23.23.0", + "resolved": "https://registry.npmjs.org/@openedx/paragon/-/paragon-23.23.0.tgz", + "integrity": "sha512-dr4zDytE7YC/Hk3sIl3MBgLyeIJBZpPp0tI2x+SQ1d/tJXhyJk4pDOfG8bFbGHt4jaM/cwjwX25jaTUV1jszIg==", "dev": true, "license": "Apache-2.0", "peer": true, @@ -4690,7 +4869,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", @@ -4736,7 +4914,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": { @@ -4759,9 +4937,9 @@ } }, "node_modules/@openedx/paragon/node_modules/lru-cache": { - "version": "11.3.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", - "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", "dev": true, "license": "BlueOak-1.0.0", "peer": true, @@ -5878,19 +6056,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==", - "dev": true, - "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", @@ -6709,9 +6874,9 @@ "peer": true }, "node_modules/@zip.js/zip.js": { - "version": "2.8.26", - "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.8.26.tgz", - "integrity": "sha512-RQ4h9F6DOiHxpdocUDrOl6xBM+yOtz+LkUol47AVWcfebGBDpZ7w7Xvz9PS24JgXvLGiXXzSAfdCdVy1tPlaFA==", + "version": "2.8.60", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.8.60.tgz", + "integrity": "sha512-pULv0waMlnKAUUxrsuAOa0ADONGRuhdHORtuXVgClNlScDB5YjImCV8DZrE1SicaROyE6MwGkH8CLJ+o4Nx07g==", "dev": true, "license": "BSD-3-Clause", "peer": true, @@ -8092,9 +8257,9 @@ } }, "node_modules/chardet": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", - "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.2.0.tgz", + "integrity": "sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==", "dev": true, "license": "MIT", "peer": true @@ -8117,14 +8282,6 @@ "node": ">=22.0.0" } }, - "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==", - "dev": true, - "license": "ISC", - "peer": true - }, "node_modules/chokidar": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", @@ -11730,23 +11887,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==", - "dev": true, - "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==", - "dev": true, - "license": "MIT" - }, "node_modules/hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", @@ -12382,72 +12522,39 @@ } }, "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.14", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-11.2.14.tgz", + "integrity": "sha512-9f2VD1HFuxUvMw0RxsaP8WmMns6JRTnsNB/zghTFrp11ZktiXWwVDeZBPQchBKEmo+Gx/ZhxI7Qht7YglFD4PA==", "dev": true, "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==", - "dev": true, - "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.17" } }, "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==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-3.1.7.tgz", + "integrity": "sha512-zXfhLpvA6T7+efdt9JLbBwZ00tT7NsBMDVnDu8rpHeNNv8KfRZAMo2gkG0k9lK/Nzc//3kJ9pImsfuJxk3KhUA==", "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "2" - } + "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.17", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.17.tgz", + "integrity": "sha512-cN9jhVqT7u0K9tix43fhjoUwL0nazyW6zsNIXs2QdPADr+nurPfYyssUiMqcSCGlPcCiqnYVxgSn7zBSuI+5Bg==", "dev": true, "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==", + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.11.tgz", + "integrity": "sha512-j8cUmOJzVgkHuS0QiQ6ga76UIoLOFSAMWhs7aZJztH3aAdCOAE6vpC8KVvFB4cU10ON0y2/5oOVmPJ43s2lTwA==", "dev": true, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "2" - } + "license": "MIT" }, "node_modules/invariant": { "version": "2.2.4", @@ -14327,13 +14434,12 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, "license": "MIT" }, "node_modules/js-toml": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/js-toml/-/js-toml-1.1.0.tgz", - "integrity": "sha512-ttRqC9rcSsV7diH6CsneXqDJWb0l9Guv2dA/0a3SQwdldCk6qsXN4O7Tg5UQevove7CXaYCcsqBn9wEQiIM3ZQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/js-toml/-/js-toml-1.2.2.tgz", + "integrity": "sha512-NapVhoCRGcW7P5gZJLjRTgabe9EOa+RVSIiyZfElKNiyAayP4kzOd0mvSzkbSt8uJ3psLkU03DuJLDVjYO6ueQ==", "dev": true, "license": "MIT", "peer": true, @@ -14794,7 +14900,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" @@ -15496,7 +15601,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -15996,9 +16100,9 @@ } }, "node_modules/patch-package/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, "license": "ISC", "peer": true, @@ -17162,9 +17266,9 @@ } }, "node_modules/prettier": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", - "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.6.tgz", + "integrity": "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==", "dev": true, "license": "MIT", "peer": true, @@ -17255,7 +17359,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -17290,7 +17393,6 @@ "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true, "license": "MIT" }, "node_modules/proxy-addr": { @@ -17552,9 +17654,9 @@ } }, "node_modules/react-colorful": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz", - "integrity": "sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.8.0.tgz", + "integrity": "sha512-Wy9OzPfjSN9bF12OB8N7UQvlsZ0I+7wHxpN+bV5BjNQGxOj6IiwkRjevJK9yOBjJWGQvAaf1OXtn8rUeEatAng==", "dev": true, "license": "MIT", "peer": true, @@ -18041,87 +18143,37 @@ } }, "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.23", + "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-10.1.23.tgz", + "integrity": "sha512-ky6bkRTUAiymd2l+qOhv4eV46gOd4JuAry2qDgSA3mjk49BrmQMPRumtrLzpUYdvfg0+iq5iPjpBGHgM4XtMJg==", "dev": true, "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.17", + "@formatjs/intl": "4.1.19", + "intl-messageformat": "11.2.14" }, "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==", - "dev": true, - "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==", - "dev": true, - "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.17", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.17.tgz", + "integrity": "sha512-cN9jhVqT7u0K9tix43fhjoUwL0nazyW6zsNIXs2QdPADr+nurPfYyssUiMqcSCGlPcCiqnYVxgSn7zBSuI+5Bg==", "dev": true, "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==", - "dev": true, - "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==", + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.11.tgz", + "integrity": "sha512-j8cUmOJzVgkHuS0QiQ6ga76UIoLOFSAMWhs7aZJztH3aAdCOAE6vpC8KVvFB4cU10ON0y2/5oOVmPJ43s2lTwA==", "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "2" - } + "license": "MIT" }, "node_modules/react-is": { "version": "17.0.2", @@ -18378,26 +18430,12 @@ } }, "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/read-cache/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.2.tgz", + "integrity": "sha512-/peqiBB/n07gQGLsWaHho3WfvUyRscw0gYTsEFMhrIe/nWLkYaf5SbKYjGYqtRV3aPwykJgF2VEMo1ac4bnsGA==", "dev": true, "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } + "peer": true }, "node_modules/readable-stream": { "version": "3.6.2", @@ -21069,9 +21107,9 @@ } }, "node_modules/tmp": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", - "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz", + "integrity": "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==", "dev": true, "license": "MIT", "peer": true, @@ -22921,9 +22959,9 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.4.tgz", - "integrity": "sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", "dev": true, "license": "ISC", "peer": true, diff --git a/package.json b/package.json index fea8e3f..fc0d981 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "url": "https://github.com/openedx/frontend-base-compat/issues" }, "devDependencies": { - "@openedx/frontend-base": "^1.0.0 || 0.0.0-dev", + "@openedx/frontend-base": "^2.0.0-alpha.2 || 0.0.0-dev", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.0", "@types/jest": "^29.5.14", @@ -47,7 +47,8 @@ "tsc-alias": "^1.8.16" }, "peerDependencies": { - "@openedx/frontend-base": "^1.0.0 || 0.0.0-dev", - "react": "^18" + "@openedx/frontend-base": "^2.0.0-alpha.2 || 0.0.0-dev", + "react": "^18", + "prop-types": "*" } } diff --git a/src/fpf/Plugin.tsx b/src/fpf/Plugin.tsx index 0edbdfd..f0a034b 100644 --- a/src/fpf/Plugin.tsx +++ b/src/fpf/Plugin.tsx @@ -1,12 +1,12 @@ import { ReactNode } from 'react'; interface PluginProps { - children?: ReactNode, + children?: ReactNode; /* Accepted for FPF type compatibility; ignored by the stub. */ - className?: string, - style?: Record, - ready?: boolean, - [key: string]: unknown, + className?: string; + style?: Record; + ready?: boolean; + [key: string]: unknown; } /* FPF `` stub. Renders children; lifecycle events from real FPF do not fire. */ diff --git a/src/fpf/PluginSlot.tsx b/src/fpf/PluginSlot.tsx index 46a082b..f999ef9 100644 --- a/src/fpf/PluginSlot.tsx +++ b/src/fpf/PluginSlot.tsx @@ -6,19 +6,19 @@ import { resolveTargetSlot } from '../mappings/resolve'; import { SlotMap } from '../types'; interface LegacySlotOptions { - mergeProps?: boolean, + mergeProps?: boolean; } export interface PluginSlotProps { - as?: ComponentType | string, - children?: ReactNode, - id: string, - idAliases?: string[], - pluginProps?: Record, - slotOptions?: LegacySlotOptions, - slotErrorFallbackComponent?: ReactNode, + as?: ComponentType | string; + children?: ReactNode; + id: string; + idAliases?: string[]; + pluginProps?: Record; + slotOptions?: LegacySlotOptions; + slotErrorFallbackComponent?: ReactNode; /* Test-only override; production uses `defaultSlotMap`. */ - slotMap?: SlotMap, + slotMap?: SlotMap; } /* FPF drop-in. Forwards `pluginProps` nested (not spread) so `Wrap` layouts can read it. */ diff --git a/src/platform/getConfig.ts b/src/platform/getConfig.ts index 0a8b7e9..076c742 100644 --- a/src/platform/getConfig.ts +++ b/src/platform/getConfig.ts @@ -33,7 +33,7 @@ export const SITE_CONFIG_TRANSLATION_MAP: Record = { * type-checks against `any`-valued properties. */ type LegacyConfig = Record; -function lookup(prop: string): { found: boolean, value: unknown } { +function lookup(prop: string): { found: boolean; value: unknown } { const site = getSiteConfig(); if (Object.prototype.hasOwnProperty.call(SITE_CONFIG_TRANSLATION_MAP, prop)) { const camel = SITE_CONFIG_TRANSLATION_MAP[prop]; diff --git a/src/platform/i18n.ts b/src/platform/i18n.ts index 02ebd23..9905d3c 100644 --- a/src/platform/i18n.ts +++ b/src/platform/i18n.ts @@ -1,3 +1,7 @@ +import PropTypes from 'prop-types'; +import { ComponentType, createElement, forwardRef } from 'react'; +import { useIntl } from '@openedx/frontend-base'; + /* Drop-in stand-in for `@edx/frontend-platform/i18n`. * * Re-exports frontend-base's full i18n surface. Sites alias @@ -23,9 +27,7 @@ export { getPrimaryLanguageSubtag, getSupportedLanguageList, handleRtl, - injectIntl, IntlProvider, - intlShape, isRtl, LOCALE_CHANGED, LOCALE_TOPIC, @@ -33,3 +35,71 @@ export { updateLocale, useIntl, } from '@openedx/frontend-base'; + +/** + * prop-types is deprecated, but this minimal definition exists to preserve backwards compatibility in this shim, as + * some MFEs may still be importing `intlShape`. + * @deprecated + */ +export const intlShape = PropTypes.object; + +/* `injectIntl` was dropped from frontend-base's i18n surface, but plenty of + * legacy code (especially class components) still relies on it, so this shim + * reimplements it on top of the `useIntl` hook. */ + +/* Derived from `useIntl` rather than imported by name: frontend-base only + * started exporting the `IntlShape` type after the release that still shipped + * its own `injectIntl`, and this shim supports both. */ +export type IntlShape = ReturnType; + +export interface WrappedComponentProps { + intl: IntlShape; +} + +/* Statics React (or the function object) owns; everything else on the wrapped + * component is copied onto the wrapper, the way react-intl does via + * hoist-non-react-statics. Copying `$$typeof`/`render`/`compare` would turn + * the wrapper into the component it wraps, so those are excluded too. + * + * This code exists so that e.g. something like the following works: + * const Card = injectIntl(BaseCard); // BaseCard.Header, BaseCard.Body + * // undefined without hoisting + */ +const nonHoistableStatics = new Set([ + '$$typeof', '_init', '_payload', 'arguments', 'arity', 'callee', 'caller', + 'childContextTypes', 'compare', 'contextType', 'contextTypes', 'defaultProps', + 'displayName', 'getDefaultProps', 'getDerivedStateFromError', + 'getDerivedStateFromProps', 'length', 'mixins', 'name', 'propTypes', + 'prototype', 'render', 'type', +]); + +/** + * Wraps a component so that it receives the current `IntlShape` as an `intl` prop. + * + * Refs are forwarded to the wrapped component, so `ref` on the wrapper reaches + * the same instance/node it would have without the wrapper. (This matches + * react-intl's `{ forwardRef: true }`; there's no reason to make it opt-in + * because the wrapper itself is never a useful ref target.) + */ +export function injectIntl

(WrappedComponent: ComponentType

) { + const Injected = forwardRef>((props, ref) => { + const intl = useIntl(); + /* `ref` is only set on the element when the caller passed one, so function + * components that can't take a ref are left alone. */ + return createElement(WrappedComponent, { ...props, intl, ref: ref ?? undefined } as unknown as P); + }); + + Injected.displayName = `injectIntl(${WrappedComponent.displayName ?? WrappedComponent.name ?? 'Component'})`; + + for (const key of Object.getOwnPropertyNames(WrappedComponent)) { + if (nonHoistableStatics.has(key)) { + continue; + } + const descriptor = Object.getOwnPropertyDescriptor(WrappedComponent, key); + if (descriptor !== undefined) { + Object.defineProperty(Injected, key, descriptor); + } + } + + return Object.assign(Injected, { WrappedComponent }); +} diff --git a/src/platform/injectIntl.test.tsx b/src/platform/injectIntl.test.tsx new file mode 100644 index 0000000..b391ff8 --- /dev/null +++ b/src/platform/injectIntl.test.tsx @@ -0,0 +1,106 @@ +/* Coverage for the `injectIntl` shim: frontend-base no longer ships one, so + * unlike the rest of `./i18n` this is our own implementation. */ +import { Component, createRef, forwardRef, memo } from 'react'; +import { render, screen } from '@testing-library/react'; +import { IntlProvider } from '@openedx/frontend-base'; + +import { injectIntl, WrappedComponentProps } from './i18n'; + +const messages = { greeting: 'Hello, {name}!' }; + +function renderWithIntl(ui: React.ReactElement) { + return render( + {ui}, + ); +} + +describe('injectIntl', () => { + it('passes an `intl` prop to a function component alongside its own props', () => { + function Greeting({ intl, name }: WrappedComponentProps & { name: string }) { + return

{intl.formatMessage({ id: 'greeting', description: 'Greets the user by name.' }, { name })}

; + } + const Wrapped = injectIntl(Greeting); + + renderWithIntl(); + + expect(screen.getByText('Hello, Ada!')).toBeInTheDocument(); + }); + + it('forwards refs to a class component instance', () => { + class Counter extends Component { + locale() { + return this.props.intl.locale; + } + + render() { + return

counter

; + } + } + const Wrapped = injectIntl(Counter); + const ref = createRef(); + + renderWithIntl(); + + expect(ref.current).toBeInstanceOf(Counter); + expect(ref.current?.locale()).toEqual('en'); + }); + + it('forwards refs through a forwardRef component to the DOM node', () => { + const Input = forwardRef( + function Input({ intl }, ref) { + return ; + }, + ); + const Wrapped = injectIntl(Input); + const ref = createRef(); + + renderWithIntl(); + + expect(ref.current).toBe(screen.getByLabelText('en')); + }); + + it('keeps a memoized component memoized', () => { + let renders = 0; + const Memoized = memo(function Memoized({ intl }: WrappedComponentProps) { + renders += 1; + return

{intl.locale}

; + }); + const Wrapped = injectIntl(Memoized); + + const { rerender } = renderWithIntl(); + rerender( + , + ); + + expect(renders).toEqual(1); + }); + + it('does not attach a ref when the caller passes none', () => { + const spy = jest.spyOn(console, 'error').mockImplementation(() => {}); + function Plain({ intl }: WrappedComponentProps) { + return

{intl.locale}

; + } + const Wrapped = injectIntl(Plain); + + renderWithIntl(); + + /* React warns "Function components cannot be given refs" if we hand a ref + * to a component that can't hold one. */ + expect(spy).not.toHaveBeenCalled(); + spy.mockRestore(); + }); + + it('sets a displayName and exposes the wrapped component and its statics', () => { + function Labelled({ intl }: WrappedComponentProps) { + return

{intl.locale}

; + } + Labelled.displayName = 'Labelled'; + Labelled.someStatic = 'kept'; + + const Wrapped = injectIntl(Labelled); + + expect(Wrapped.displayName).toEqual('injectIntl(Labelled)'); + expect(Wrapped.WrappedComponent).toBe(Labelled); + expect((Wrapped as typeof Wrapped & { someStatic: string }).someStatic).toEqual('kept'); + }); +}); diff --git a/src/platform/reExports.test.ts b/src/platform/reExports.test.ts index 993bd0c..0a44355 100644 --- a/src/platform/reExports.test.ts +++ b/src/platform/reExports.test.ts @@ -1,7 +1,8 @@ /* Smoke test: the symbols re-exported from `./i18n`, `./auth`, and the * platform-aggregate `./` are the same object identities frontend-base * exports. Catches accidental wrappers that would silently desync from - * the underlying implementation. */ + * the underlying implementation. `injectIntl` is deliberately absent: it has + * no frontend-base counterpart and is shimmed locally (see injectIntl.test.tsx). */ import * as base from '@openedx/frontend-base'; import * as platformAuth from './auth'; @@ -13,7 +14,6 @@ describe('platform re-exports', () => { expect(platformI18n.useIntl).toBe(base.useIntl); expect(platformI18n.defineMessages).toBe(base.defineMessages); expect(platformI18n.IntlProvider).toBe(base.IntlProvider); - expect(platformI18n.injectIntl).toBe(base.injectIntl); expect(platformI18n.FormattedMessage).toBe(base.FormattedMessage); expect(platformI18n.configureI18n).toBe(base.configureI18n); }); diff --git a/src/translate.test.tsx b/src/translate.test.tsx index 1bc532d..3c96fe5 100644 --- a/src/translate.test.tsx +++ b/src/translate.test.tsx @@ -53,7 +53,7 @@ function fakeHeaderApp(): App { }; } -function envConfig(plugins: LegacyPluginEntry[], opts: { keepDefault?: boolean, slotId?: string, slotOptions?: Record } = {}): LegacyEnvConfig { +function envConfig(plugins: LegacyPluginEntry[], opts: { keepDefault?: boolean; slotId?: string; slotOptions?: Record } = {}): LegacyEnvConfig { return { pluginSlots: { [opts.slotId ?? HEADER_DESKTOP_LEGACY]: { @@ -549,8 +549,8 @@ describe('translate', () => { component, pluginProps, }: { - component: any, - pluginProps?: Record, + component: any; + pluginProps?: Record; }) => (
{component} diff --git a/src/translate.tsx b/src/translate.tsx index fed7f47..111684a 100644 --- a/src/translate.tsx +++ b/src/translate.tsx @@ -22,11 +22,11 @@ import { import { createWrapLayout } from './wrap'; interface TranslateArgs { - envConfig: LegacyEnvConfig, - slotMap: SlotMap, - widgetMap: WidgetMap, - apps: App[], - routeRoles?: string[], + envConfig: LegacyEnvConfig; + slotMap: SlotMap; + widgetMap: WidgetMap; + apps: App[]; + routeRoles?: string[]; } const defaultContentId = 'defaultContent'; @@ -142,7 +142,7 @@ function emitInsert( } /* Cast lets us read `id`/`type` after the union has been exhausted above. */ - const unknown = widget as { id?: string, type?: string }; + const unknown = widget as { id?: string; type?: string }; warnOnce( `unknown-widget-type:${unknown.id}`, `[fpf-compat] unknown widget type "${unknown.type}" for "${unknown.id}"; skipping.`, @@ -151,8 +151,8 @@ function emitInsert( } interface InsertAnchor { - op: WidgetOperationTypes.INSERT_BEFORE | WidgetOperationTypes.INSERT_AFTER, - relatedId: string, + op: WidgetOperationTypes.INSERT_BEFORE | WidgetOperationTypes.INSERT_AFTER; + relatedId: string; } function resolveInsertAnchor(mapping: SlotMappingEntry): InsertAnchor | null { @@ -166,7 +166,7 @@ function resolveInsertAnchor(mapping: SlotMappingEntry): InsertAnchor | null { } function withAnchor( - base: { slotId: string, id: string, element?: ReactElement, component?: ComponentType }, + base: { slotId: string; id: string; element?: ReactElement; component?: ComponentType }, anchor: InsertAnchor | null, ): SlotOperation { if (anchor) { @@ -312,9 +312,9 @@ function emitWrap( apps: App[], ): SlotOperation[] { const wrapper = entry.wrapper as ComponentType<{ - component: ReactElement, - idx?: number, - count?: number, + component: ReactElement; + idx?: number; + count?: number; }> | undefined; if (typeof wrapper !== 'function') { warnOnce( diff --git a/src/types.ts b/src/types.ts index 7a6b475..51bdf77 100644 --- a/src/types.ts +++ b/src/types.ts @@ -7,42 +7,42 @@ export type LegacyOperation = 'insert' | 'hide' | 'modify' | 'wrap'; export type LegacyPluginType = 'DIRECT_PLUGIN' | 'IFRAME_PLUGIN'; export interface LegacyDirectWidget { - id: string, - type: 'DIRECT_PLUGIN', - priority?: number, - RenderWidget: ComponentType | ReactElement, + id: string; + type: 'DIRECT_PLUGIN'; + priority?: number; + RenderWidget: ComponentType | ReactElement; } export interface LegacyIframeWidget { - id: string, - type: 'IFRAME_PLUGIN', - priority?: number, - url: string, - title: string, + id: string; + type: 'IFRAME_PLUGIN'; + priority?: number; + url: string; + title: string; } export type LegacyWidget = LegacyDirectWidget | LegacyIframeWidget; export interface LegacyInsertEntry { - op: 'insert', - widget: LegacyWidget, + op: 'insert'; + widget: LegacyWidget; } export interface LegacyHideEntry { - op: 'hide', - widgetId: string, + op: 'hide'; + widgetId: string; } export interface LegacyModifyEntry { - op: 'modify', - widgetId: string, - fn: (...args: unknown[]) => unknown, + op: 'modify'; + widgetId: string; + fn: (...args: unknown[]) => unknown; } export interface LegacyWrapEntry { - op: 'wrap', - widgetId: string, - wrapper: ComponentType<{ component: ReactElement, idx?: number, count?: number }>, + op: 'wrap'; + widgetId: string; + wrapper: ComponentType<{ component: ReactElement; idx?: number; count?: number }>; } export type LegacyPluginEntry = @@ -52,19 +52,19 @@ export type LegacyPluginEntry = | LegacyWrapEntry; export interface LegacySlotOptions { - mergeProps?: boolean, - [key: string]: unknown, + mergeProps?: boolean; + [key: string]: unknown; } export interface LegacyPluginSlotConfig { - keepDefault?: boolean, - plugins: LegacyPluginEntry[], - slotOptions?: LegacySlotOptions, + keepDefault?: boolean; + plugins: LegacyPluginEntry[]; + slotOptions?: LegacySlotOptions; } export interface LegacyEnvConfig { - pluginSlots?: Record, - [key: string]: unknown, + pluginSlots?: Record; + [key: string]: unknown; } export type LegacySetConfig = () => LegacyEnvConfig; @@ -82,9 +82,9 @@ export type RouteMap = Record; export interface SlotMappingEntry { /* Legacy `idAliases` accepted by the old slot. */ - sourceAliases?: string[], + sourceAliases?: string[]; /* Default landing slot for `Insert`; per-widget routing overrides via `widgetMap`. */ - targetSlotId: string, + targetSlotId: string; /* * Optional positional anchor for `Insert`. When set, emit an * INSERT_BEFORE / INSERT_AFTER op against the named widget id in @@ -93,8 +93,8 @@ export interface SlotMappingEntry { * `widgetMap` routes the widget to a different slot. If both are * set, `insertBefore` wins. */ - insertBefore?: string, - insertAfter?: string, + insertBefore?: string; + insertAfter?: string; /* * Used by `Hide default_contents` / `keepDefault: false`. Additive layers: * - `slotIds`: REMOVE synthetic `defaultContent` on each (covers JSX-children defaults). @@ -103,30 +103,30 @@ export interface SlotMappingEntry { * Omit the field to fall back to a synthetic REMOVE on `targetSlotId`. */ targetDefaultContent?: { - slotIds?: string[], - fromAppIds?: string[], - widgetMap?: WidgetMap, - }, + slotIds?: string[]; + fromAppIds?: string[]; + widgetMap?: WidgetMap; + }; } export type SlotMap = Record; export interface LegacyPluginAppArgs { - appId: string, - envConfig: LegacyEnvConfigInput, - mfeId?: string, - routeMap?: RouteMap, - slotMap?: SlotMap, - widgetMap?: WidgetMap, + appId: string; + envConfig: LegacyEnvConfigInput; + mfeId?: string; + routeMap?: RouteMap; + slotMap?: SlotMap; + widgetMap?: WidgetMap; } /* Decoupled from the lazy `slots` getter so `translate()` is pure-function-testable. */ export interface TranslateInput { - envConfig: LegacyEnvConfig, - slotMap: SlotMap, - widgetMap: WidgetMap, - apps: App[], - routeRoles?: string[], + envConfig: LegacyEnvConfig; + slotMap: SlotMap; + widgetMap: WidgetMap; + apps: App[]; + routeRoles?: string[]; } export type TranslateOutput = SlotOperation[]; diff --git a/src/wrap.tsx b/src/wrap.tsx index 7f53bed..b9064f9 100644 --- a/src/wrap.tsx +++ b/src/wrap.tsx @@ -2,9 +2,9 @@ import { ComponentType, ReactElement, isValidElement } from 'react'; import { useSlotContext, useWidgets } from '@openedx/frontend-base'; interface WrapLayoutArgs { - wrapper: ComponentType<{ component: ReactElement, pluginProps?: Record }>, + wrapper: ComponentType<{ component: ReactElement; pluginProps?: Record }>; /* Wraps only this id; if absent, wraps every widget. */ - widgetId?: string, + widgetId?: string; } /* Layout that decorates one (or all) widgets via an FPF-shaped wrapper. Best effort per ADR 0001. */