diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 0db94630..00000000 --- a/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -coverage/* -dist/ -node_modules/ -__mocks__/ -__snapshots__/ diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index b8f9a534..00000000 --- a/.eslintrc.js +++ /dev/null @@ -1,26 +0,0 @@ -const path = require('path'); -const { merge } = require('webpack-merge'); - -const config = require('./tools/eslint/.eslintrc.js'); - -module.exports = merge(config, { - ignorePatterns: [ - 'test-project', - 'docs', - '.eslintrc.js', - 'frontend-base.d.ts', - 'coverage', - 'tools', - 'config', - 'dist', - ], - parserOptions: { - project: path.resolve(__dirname, './tsconfig.json'), - }, - rules: { - 'no-console': 'off', - 'import/no-dynamic-require': 'off', - 'global-require': 'off', - 'no-template-curly-in-string': 'off', - }, -}); diff --git a/.gitignore b/.gitignore index 44c2a7b3..d043b493 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ .vscode coverage dist -config +/config scss node_modules npm-debug.log diff --git a/.npmignore b/.npmignore index 2ed768b0..64c5908d 100644 --- a/.npmignore +++ b/.npmignore @@ -1,6 +1,5 @@ __mocks__ -.eslintignore -./.eslintrc.js +./eslint.config.js .github .gitignore *.test.js diff --git a/docs/how_tos/migrate-frontend-app.md b/docs/how_tos/migrate-frontend-app.md index a1e6e2a4..700118b1 100644 --- a/docs/how_tos/migrate-frontend-app.md +++ b/docs/how_tos/migrate-frontend-app.md @@ -295,35 +295,57 @@ mergeConfig(siteConfig); ``` -## 11. Edit `.eslintrc.js` +## 11. Replace `.eslintrc.js` with `eslint.config.js` -Replace the import from 'frontend-build' with 'frontend-base'. +ESLint has been upgraded to v9, which has a new 'flat' file format. Replace the repository's `.eslintrc.js` file with a new `eslint.config.js` file with the following contents: -```diff -- const { createConfig } = require('@openedx/frontend-build'); -+ const { createConfig } = require('@openedx/frontend-base/config'); ``` +// @ts-check -Use 'lint' instead of 'eslint' as the config type for createConfig() +const { createLintConfig } = require('@openedx/frontend-base/config'); +module.exports = createLintConfig( + { + files: [ + 'src/**/*', + 'site.config.*', + ], + }, +); ``` -module.exports = createConfig('lint', { - // ... custom config -}) -``` -You will also need to set the `project` in `parserOptions`. An uncustomized `.eslintrc.js` file looks like: +## 12. Replace `.eslintignore`, if it exists, with entries in `eslint.config.js` + +The base eslint config provided by frontend-base ignores a number of common folders by default: ``` -const path = require('path'); + { + ignores: [ + 'coverage/*', + 'dist/*', + 'node_modules/*', + '**/__mocks__/*', + '**/__snapshots__/*', + ], + }, +``` -const { createConfig } = require('@openedx/frontend-base/config'); +You can configure additional ignores in your own `eslint.config.js` file using the above syntax, as a separate object from the existing 'files' object: -module.exports = createConfig('lint', { - parserOptions: { - project: path.resolve(__dirname, './tsconfig.json'), +```diff +module.exports = createLintConfig( + { + files: [ + 'src/**/*', + 'site.config.*', + ], }, -}); ++ { ++ ignores: [ ++ 'ignoredfolder/*' ++ ] ++ } +); ``` ## 12. Search for any other usages of `frontend-build` @@ -536,3 +558,34 @@ https://react-redux.js.org/using-react-redux/accessing-store#multiple-stores ## 27. Subdomains!? ## 28. Add LEARNER_DASHBOARD_URL to config + +## 29. Convert @import to @use in SCSS files. + +## 30. Changes to i81n + +configureI18n no longer takes `config` or `loggingService` as options + +The `getLoggingService` export from _i18n_ has also been removed. No one should be using that. + +`getLanguageList` has been removed. Modules that need a list of countries should install `@cospired/i18n-iso-languages` as a dependency. + +`getSupportedLanguageList` now returns an array of objects containing the `name` and `code` of all the languages that have translations bundled with the app, rather than a hard-coded list. + +`getCountryList` has been removed. MFEs that need a list of countries should install `i18n-iso-countries` or `countries-list` as a dependency. + +frontend-app-account should use the supported language list from frontend-base, rather than the hard-coded list in https://github.com/openedx/frontend-app-account/blob/master/src/account-settings/site-language/constants.js + +This would help it match the behavior of the footer's language dropdown. + +## Removal of pubsub-js + +frontend-platform used pubsub-js behind the scenes for event subscriptions/publishing. It used it in a very rudimentary way, and the library was noisy in test suites, complaining about being re-initialized. Because of these reasons, we've removed our dependency on pubsub-js and replaced it with a simple subscription system with a very similar API: + +- `subscribe(topic: string, callback: (topic: string, data?: any) => void)` +- `publish(topic: string, data?: any)` +- `unsubscribe(topic: string, callback: (topic: string, data?: any) => void)` +- `clearAllSubscriptions()` + +The unsubscribe function as a different API than pubsub-js's unsubscribe function, taking a topic and a callback rather than an unsubscribe token. + +Consumers who were using the `PubSub` global variable should instead import the above functions directly from `@openedx/frontend-base`. diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000..b10cb1ab --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,18 @@ +// @ts-check + +const tseslint = require('typescript-eslint'); +const eslintConfig = require('./tools/eslint/base.eslint.config.js'); + +module.exports = tseslint.config( + { + extends: eslintConfig, + }, + { + ignores: [ + 'tools/*', + 'test-project/*', + 'config/*', + 'docs/*', + ], + }, +); diff --git a/frontend-base.d.ts b/frontend-base.d.ts index 4278d0e1..c068892d 100644 --- a/frontend-base.d.ts +++ b/frontend-base.d.ts @@ -1,4 +1,4 @@ -import { ProjectSiteConfig } from "./index"; +import { ProjectSiteConfig } from './index'; declare module 'site.config' { export default ProjectSiteConfig; diff --git a/index.ts b/index.ts index 494669de..40390d89 100644 --- a/index.ts +++ b/index.ts @@ -39,6 +39,7 @@ export { SegmentAnalyticsService, auth, camelCaseObject, + clearAllSubscriptions, configureAnalytics, configureAuth, configureI18n, @@ -54,13 +55,10 @@ export { getAuthenticatedUser, getBasename, getConfig, - getCountryList, - getCountryMessages, getHistory, getHttpClient, - getLanguageList, - getLanguageMessages, getLocale, + getLocalizedLanguageName, getLoggingService, getLoginRedirectUrl, getLogoutRedirectUrl, @@ -68,6 +66,7 @@ export { getPath, getPrimaryLanguageSubtag, getQueryParameters, + getSupportedLanguageList, handleRtl, hydrateAuthenticatedUser, identifyAnonymousUser, @@ -81,10 +80,10 @@ export { logError, logInfo, mergeConfig, - mergeMessages, mockMessages, modifyObjectKeys, parseURL, + patchMessages, publish, redirectToLogin, redirectToLogout, @@ -98,6 +97,7 @@ export { snakeCaseObject, subscribe, unsubscribe, + updateLocale, useAppEvent, useAuthenticatedUser, useConfig, @@ -105,19 +105,12 @@ export { } from './runtime'; export type { - ApplicationModuleConfig, - ExternalAppConfig, - FederatedAppConfig, - InsertDirectPluginWidget, - InsertIframePluginWidget, - InternalAppConfig, ProjectModuleConfig, ProjectSiteConfig } from './types'; export { - AppConfigTypes, EnvironmentTypes, - PluginOperations, + PluginOperationTypes, PluginTypes } from './types'; diff --git a/package-lock.json b/package-lock.json index aed282d9..82c5166c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,50 +13,47 @@ "@babel/preset-env": "^7.24.8", "@babel/preset-react": "^7.24.7", "@babel/preset-typescript": "^7.24.7", - "@cospired/i18n-iso-languages": "^4.2.0", "@edx/new-relic-source-map-webpack-plugin": "2.1.0", + "@eslint/compat": "^1.2.1", + "@eslint/js": "^9.13.0", "@formatjs/cli": "^6.0.3", - "@formatjs/intl-pluralrules": "^4.3.3", - "@formatjs/intl-relativetimeformat": "^10.0.1", "@formatjs/ts-transformer": "^3.13.14", - "@module-federation/enhanced": "^0.4.0", - "@module-federation/runtime": "^0.2.6", - "@pmmmwh/react-refresh-webpack-plugin": "0.5.15", + "@module-federation/enhanced": "^0.6.12", + "@module-federation/runtime": "^0.6.12", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.15", + "@stylistic/eslint-plugin": "^2.9.0", + "@types/eslint__js": "^8.42.3", "@types/gradient-string": "^1.1.6", - "@typescript-eslint/eslint-plugin": "^6.21.0", - "@typescript-eslint/parser": "^6.21.0", - "autoprefixer": "10.4.19", + "autoprefixer": "^10.4.20", "axios": "^1.7.7", "axios-cache-interceptor": "^1.6.0", "babel-jest": "^29.7.0", "babel-plugin-formatjs": "^10.5.16", - "chalk": "4.1.2", + "chalk": "^4.1.2", "classnames": "^2.5.1", - "clean-webpack-plugin": "4.0.0", + "clean-webpack-plugin": "^4.0.0", "compression": "^1.7.4", - "css-loader": "5.2.7", - "cssnano": "6.0.3", - "eslint": "8.44.0", - "eslint-config-airbnb": "19.0.4", - "eslint-config-airbnb-typescript": "^17.0.0", - "eslint-plugin-formatjs": "^4.12.2", - "eslint-plugin-import": "2.27.5", - "eslint-plugin-jsx-a11y": "6.7.1", - "eslint-plugin-react": "7.32.2", - "eslint-plugin-react-hooks": "4.6.0", + "css-loader": "^7.1.2", + "cssnano": "^6.1.2", + "eslint": "^9.13.0", + "eslint-plugin-formatjs": "^5.1.3", + "eslint-plugin-jest": "^28.8.3", + "eslint-plugin-jsx-a11y": "^6.10.1", + "eslint-plugin-react": "^7.37.2", + "eslint-plugin-react-hooks": "^5.0.0", "express": "^4.18.2", "file-loader": "6.2.0", "fork-ts-checker-webpack-plugin": "^9.0.2", "form-urlencoded": "^6.1.5", "glob": "^7.2.3", + "globals": "^15.11.0", "gradient-string": "^2.0.2", "history": "^4.10.1", "html-webpack-plugin": "5.6.0", - "i18n-iso-countries": "^4.3.1", "identity-obj-proxy": "3.0.0", "image-minimizer-webpack-plugin": "3.8.3", - "jest": "29.6.1", - "jest-environment-jsdom": "29.6.1", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", "jwt-decode": "^3.1.2", "localforage": "^1.10.0", "localforage-memoryStorageDriver": "^0.9.2", @@ -66,12 +63,11 @@ "lodash.snakecase": "^4.1.1", "mini-css-extract-plugin": "1.6.2", "parse5": "7.1.2", - "postcss": "8.4.40", + "postcss": "^8.4.47", "postcss-custom-media": "10.0.8", "postcss-loader": "7.3.4", - "postcss-rtlcss": "5.1.2", + "postcss-rtlcss": "^5.5.0", "prop-types": "^15.8.1", - "pubsub-js": "^1.9.4", "react-dev-utils": "12.0.1", "react-focus-on": "^3.9.4", "react-intl": "^6.6.6", @@ -79,20 +75,22 @@ "react-refresh-typescript": "^2.0.9", "react-responsive": "^10.0.0", "react-transition-group": "^4.4.5", - "resolve-url-loader": "5.0.0", - "sass": "1.69.7", - "sass-loader": "13.3.3", - "sharp": "0.32.6", + "resolve-url-loader": "^5.0.0", + "sass-embedded": "^1.80.4", + "sass-loader": "^16.0.2", + "sharp": "^0.33.5", "source-map-loader": "4.0.2", - "style-loader": "3.3.4", + "style-loader": "^4.0.0", "ts-loader": "^9.5.1", - "typescript": "^5.5.3", + "typescript": "^5.6.3", + "typescript-eslint": "^8.11.0", "universal-cookie": "^4.0.4", - "url-loader": "4.1.1", - "webpack": "^5.89.0", + "url-loader": "^4.1.1", + "uuid": "^11.0.2", + "webpack": "^5.95.0", "webpack-bundle-analyzer": "^4.10.1", "webpack-cli": "^5.1.4", - "webpack-dev-server": "^4.15.1", + "webpack-dev-server": "^5.1.0", "webpack-merge": "^5.10.0", "webpack-remove-empty-scripts": "1.0.4" }, @@ -109,7 +107,7 @@ "@testing-library/user-event": "^14.5.2", "@tsconfig/node18": "^18.2.4", "@types/compression": "^1.7.5", - "@types/jest": "^29.5.12", + "@types/jest": "^29.5.14", "@types/lodash.camelcase": "^4.3.9", "@types/lodash.merge": "^4.6.9", "@types/node": "^18.19.43", @@ -1024,6 +1022,14 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-classes/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", @@ -1919,6 +1925,14 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/types": { "version": "7.25.6", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", @@ -1937,13 +1951,10 @@ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" }, - "node_modules/@cospired/i18n-iso-languages": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@cospired/i18n-iso-languages/-/i18n-iso-languages-4.2.0.tgz", - "integrity": "sha512-vy8cq1176MTxVwB1X9niQjcIYOH29F8Huxtx8hLmT5Uz3l1ztGDGri8KN/4zE7LV2mCT7JrcAoNV/I9yb+lNUw==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } + "node_modules/@bufbuild/protobuf": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.2.0.tgz", + "integrity": "sha512-+imAQkHf7U/Rwvu0wk1XWgsP3WnpCWmK7B48f0XqSNzgk64+grljTKC7pnO/xBiEMUziF7vKRfbBnOQhg126qQ==" }, "node_modules/@csstools/cascade-layer-name-parser": { "version": "1.0.13", @@ -2044,6 +2055,15 @@ "@newrelic/publish-sourcemap": "^5.0.1" } }, + "node_modules/@emnapi/runtime": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", + "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -2066,15 +2086,52 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/compat": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.2.1.tgz", + "integrity": "sha512-JbHG2TWuCeNzh87fXo+/46Z1LEo9DBA9T188d0fZgGxAD+cNyS6sx9fdiyxjGPBMyQVRlCutTByZ6a5+YMkF7g==", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^9.10.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/config-array": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", + "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -2082,7 +2139,7 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -2093,24 +2150,12 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dependencies": { - "type-fest": "^0.20.2" - }, + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2127,34 +2172,31 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "node_modules/@eslint/js": { + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.13.0.tgz", + "integrity": "sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==", "engines": { - "node": "*" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/js": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", - "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "node_modules/@eslint/plugin-kit": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.1.tgz", + "integrity": "sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==", + "dependencies": { + "levn": "^0.4.1" + }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@formatjs/cli": { @@ -2204,15 +2246,6 @@ } } }, - "node_modules/@formatjs/ecma402-abstract": { - "version": "1.11.4", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz", - "integrity": "sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==", - "dependencies": { - "@formatjs/intl-localematcher": "0.2.25", - "tslib": "^2.1.0" - } - }, "node_modules/@formatjs/fast-memoize": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz", @@ -2350,34 +2383,6 @@ "tslib": "^2.4.0" } }, - "node_modules/@formatjs/intl-localematcher": { - "version": "0.2.25", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.25.tgz", - "integrity": "sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@formatjs/intl-pluralrules": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@formatjs/intl-pluralrules/-/intl-pluralrules-4.3.3.tgz", - "integrity": "sha512-NLZN8gf2qLpCuc0m565IbKLNUarEGOzk0mkdTkE4XTuNCofzoQTurW6lL3fmDlneAoYl2FiTdHa5q4o2vZF50g==", - "dependencies": { - "@formatjs/ecma402-abstract": "1.11.4", - "@formatjs/intl-localematcher": "0.2.25", - "tslib": "^2.1.0" - } - }, - "node_modules/@formatjs/intl-relativetimeformat": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-10.0.1.tgz", - "integrity": "sha512-AABPQtPjFilXegQsnmVHrSlzjFNUffAEk5DgowY6b7WSwDI7g2W6QgW903/lbZ58emhphAbgHdtKeUBXqTiLpw==", - "dependencies": { - "@formatjs/ecma402-abstract": "1.11.4", - "@formatjs/intl-localematcher": "0.2.25", - "tslib": "^2.1.0" - } - }, "node_modules/@formatjs/intl/node_modules/@formatjs/ecma402-abstract": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.0.0.tgz", @@ -2456,38 +2461,24 @@ "react": ">=16.x" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, + "node_modules/@humanfs/core": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", + "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node": ">=18.18.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@humanfs/node": { + "version": "0.16.5", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", + "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", "dependencies": { - "brace-expansion": "^1.1.7" + "@humanfs/core": "^0.19.0", + "@humanwhocodes/retry": "^0.3.0" }, "engines": { - "node": "*" + "node": ">=18.18.0" } }, "node_modules/@humanwhocodes/module-importer": { @@ -2502,141 +2493,489 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead" - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" + "node": ">=18.18" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "funding": { + "url": "https://opencollective.com/libvips" }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" } }, - "node_modules/@jest/core/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=10" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "url": "https://opencollective.com/libvips" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" } }, - "node_modules/@jest/core/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, - "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", - "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@jest/expect": { + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", @@ -2911,7 +3250,58 @@ "lodash": "^4.17.21" }, "engines": { - "node": ">=v12.0.0" + "node": ">=v12.0.0" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.0.tgz", + "integrity": "sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==", + "dependencies": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.5.0.tgz", + "integrity": "sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" } }, "node_modules/@leichtgewicht/ip-codec": { @@ -2920,24 +3310,51 @@ "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==" }, "node_modules/@module-federation/bridge-react-webpack-plugin": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@module-federation/bridge-react-webpack-plugin/-/bridge-react-webpack-plugin-0.4.0.tgz", - "integrity": "sha512-su/ZpRZcyZ8yVa5+zmZyh2pW/BdCQsto52Xmp75GRgPgwG7IrczcQ/GlMCHZz9hQQdmLEQuPe4BIvpnH+GS9Jw==", + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@module-federation/bridge-react-webpack-plugin/-/bridge-react-webpack-plugin-0.6.12.tgz", + "integrity": "sha512-AF+5iKtfBsQU8XDudw55C5zo442uiqU3hY1uGJInr+/v16MrXviFQqrZ2VuXKiu9C8vPXbsAtBNB6MbOH5JARA==", + "dependencies": { + "@module-federation/sdk": "0.6.12", + "@types/semver": "7.5.8", + "semver": "7.6.3" + } + }, + "node_modules/@module-federation/bridge-react-webpack-plugin/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@module-federation/data-prefetch": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@module-federation/data-prefetch/-/data-prefetch-0.6.12.tgz", + "integrity": "sha512-Pg0N/H9stucS6Olmrc8Ib75f5bqx0I3ayWgkY5dahe2B8E3Bhbr1zw3seidPKXIosemRZxA11QsPD5of5SyNmA==", "dependencies": { - "@module-federation/sdk": "0.4.0" + "@module-federation/runtime": "0.6.12", + "@module-federation/sdk": "0.6.12", + "fs-extra": "9.1.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" } }, "node_modules/@module-federation/dts-plugin": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@module-federation/dts-plugin/-/dts-plugin-0.4.0.tgz", - "integrity": "sha512-KCFIdUh6PhoNqU8OlLmbhjec+wWyo9HAUukR84TnjiktVYMcCqmlmSeWoma2llyPE3GeOHqln+cPR7hMPXbR6w==", + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@module-federation/dts-plugin/-/dts-plugin-0.6.12.tgz", + "integrity": "sha512-JFoHXVrwQDqcbRc7Ws/19zmCajx3xyRZarvM8592OLoLOK/QzrA9xg/o1ltiC4a7tRA3aubm9clo+pzVgqECwQ==", "dependencies": { - "@module-federation/managers": "0.4.0", - "@module-federation/sdk": "0.4.0", - "@module-federation/third-party-dts-extractor": "0.4.0", + "@module-federation/managers": "0.6.12", + "@module-federation/sdk": "0.6.12", + "@module-federation/third-party-dts-extractor": "0.6.12", "adm-zip": "^0.5.10", "ansi-colors": "^4.1.3", - "axios": "^1.6.7", + "axios": "^1.7.4", "chalk": "3.0.0", "fs-extra": "9.1.0", "isomorphic-ws": "5.0.0", @@ -2946,7 +3363,7 @@ "log4js": "6.9.1", "node-schedule": "2.1.1", "rambda": "^9.1.0", - "ws": "8.17.1" + "ws": "8.18.0" }, "peerDependencies": { "typescript": "^4.9.0 || ^5.0.0", @@ -2971,17 +3388,18 @@ } }, "node_modules/@module-federation/enhanced": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@module-federation/enhanced/-/enhanced-0.4.0.tgz", - "integrity": "sha512-F398RJioMiU4zpXjtF+bJG7sROGNnY1dyPxwfhAnfDxtm/5urWnR2od2+zTvucyWdNeWQxbEe9XUOpgt42egqw==", - "dependencies": { - "@module-federation/bridge-react-webpack-plugin": "0.4.0", - "@module-federation/dts-plugin": "0.4.0", - "@module-federation/managers": "0.4.0", - "@module-federation/manifest": "0.4.0", - "@module-federation/rspack": "0.4.0", - "@module-federation/runtime-tools": "0.4.0", - "@module-federation/sdk": "0.4.0", + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@module-federation/enhanced/-/enhanced-0.6.12.tgz", + "integrity": "sha512-HkcXPbgugcYKq5gFWWh/VSlPYEPEunVFWAINgKPu03YGSTDaFRo9jbvNWA+CR7pFNUOMTg2weudlP10olbvPdQ==", + "dependencies": { + "@module-federation/bridge-react-webpack-plugin": "0.6.12", + "@module-federation/data-prefetch": "0.6.12", + "@module-federation/dts-plugin": "0.6.12", + "@module-federation/managers": "0.6.12", + "@module-federation/manifest": "0.6.12", + "@module-federation/rspack": "0.6.12", + "@module-federation/runtime-tools": "0.6.12", + "@module-federation/sdk": "0.6.12", "btoa": "^1.2.1", "upath": "2.0.1" }, @@ -3003,23 +3421,23 @@ } }, "node_modules/@module-federation/managers": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@module-federation/managers/-/managers-0.4.0.tgz", - "integrity": "sha512-c4apAaQjwR01qlDSNwPfBBTTzVyErO6POayaRIeAoQMoJLgf+HvL2YFsVPTc4+n8w4lNBMAghPr/BVGlTK9SJQ==", + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@module-federation/managers/-/managers-0.6.12.tgz", + "integrity": "sha512-86UH9UuGBkoQvUOW7Xgl5PEyTj86YLUfvnj7MBS7p7XEJyFjcg1EwlS+JJGmLx0csovWgNkaUlNveKiZjYIbTQ==", "dependencies": { - "@module-federation/sdk": "0.4.0", + "@module-federation/sdk": "0.6.12", "find-pkg": "2.0.0", "fs-extra": "9.1.0" } }, "node_modules/@module-federation/manifest": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@module-federation/manifest/-/manifest-0.4.0.tgz", - "integrity": "sha512-TT2H5z3tFtkVarWz6Zsyi4T6wGxxRQjk3O6lSjYrZzWDYyVnrVhAkBgcN9WlkxqSY/V/ifZlTUWUpfSMObRTig==", + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@module-federation/manifest/-/manifest-0.6.12.tgz", + "integrity": "sha512-blpSrM9mQfV56L7jZAgjWL5xoBeSFxdQtQoiIyrs6CC4v2RCMGVwJeBGyvenwvu+K1sLeWZN2dVU9E+WBqDgnQ==", "dependencies": { - "@module-federation/dts-plugin": "0.4.0", - "@module-federation/managers": "0.4.0", - "@module-federation/sdk": "0.4.0", + "@module-federation/dts-plugin": "0.6.12", + "@module-federation/managers": "0.6.12", + "@module-federation/sdk": "0.6.12", "chalk": "3.0.0", "find-pkg": "2.0.0" } @@ -3037,16 +3455,16 @@ } }, "node_modules/@module-federation/rspack": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@module-federation/rspack/-/rspack-0.4.0.tgz", - "integrity": "sha512-yPzJwVs/JQcWPw5wy79nEydYAX74TMOJqf4AQijEpdAcE52wWSAm84GymZmAAo55rC74wLGy/DgqQlYNF8WIxw==", + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@module-federation/rspack/-/rspack-0.6.12.tgz", + "integrity": "sha512-hGduVfTEf7xYcaSOWTJG6Y8SzOEjClImpc8mw6MbysBDf62dK4fWE/1nY+ienHlkMTuONg44DulTUSgh/Aotjw==", "dependencies": { - "@module-federation/bridge-react-webpack-plugin": "0.4.0", - "@module-federation/dts-plugin": "0.4.0", - "@module-federation/managers": "0.4.0", - "@module-federation/manifest": "0.4.0", - "@module-federation/runtime-tools": "0.4.0", - "@module-federation/sdk": "0.4.0" + "@module-federation/bridge-react-webpack-plugin": "0.6.12", + "@module-federation/dts-plugin": "0.6.12", + "@module-federation/managers": "0.6.12", + "@module-federation/manifest": "0.6.12", + "@module-federation/runtime-tools": "0.6.12", + "@module-federation/sdk": "0.6.12" }, "peerDependencies": { "typescript": "^4.9.0 || ^5.0.0", @@ -3062,44 +3480,31 @@ } }, "node_modules/@module-federation/runtime": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.2.8.tgz", - "integrity": "sha512-8xmA/+z1zD09F5qU8VnSWLExqTCVWoHOguXsCX79kkqp7i0c+D2YaebWzlQ2kku+DU+0VIzXpQ3BBcumZ3v3wQ==", + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.6.12.tgz", + "integrity": "sha512-zNIhdNc/LcYUqb5guAZRyIGEVQSSALbr7TLuIyzF9eF4jVKBnkOcR/kphaisspkhc467x/mC99/41TzCfAORfA==", "dependencies": { - "@module-federation/sdk": "0.2.8" + "@module-federation/sdk": "0.6.12" } }, "node_modules/@module-federation/runtime-tools": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.4.0.tgz", - "integrity": "sha512-Mr/ewsZbKmv4ZG3FYNrfdgRh5OauJy5IiZ/Z5jtYlNkLfYjUBHSBkh986l/Bpa385+RCCPs3Lg6yFBQlOiYlug==", - "dependencies": { - "@module-federation/runtime": "0.4.0", - "@module-federation/webpack-bundler-runtime": "0.4.0" - } - }, - "node_modules/@module-federation/runtime-tools/node_modules/@module-federation/runtime": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.4.0.tgz", - "integrity": "sha512-zEhMil0JbB0eS1bflV9qOJFJNmDCWMJbKUN7Xw5OMLDnveKTg9l/rLqDGwt/kAP0/Lhq1PNuXEvYm1CeIKKU8A==", + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.6.12.tgz", + "integrity": "sha512-oiTRUZ/Sj+Nw10oheh8EizhYavBfAWCmlScTtjxSFvya2ixt6h4j1Z2EV0SFpylI7WugjkckRNEsUq1UCCCuLQ==", "dependencies": { - "@module-federation/sdk": "0.4.0" + "@module-federation/runtime": "0.6.12", + "@module-federation/webpack-bundler-runtime": "0.6.12" } }, - "node_modules/@module-federation/runtime/node_modules/@module-federation/sdk": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.2.8.tgz", - "integrity": "sha512-eGMnJxdRDgt6dtMv8gkAlzEbTPWVHb3AHUNUG0w56wcbIF0RHC6kmvpHpSQyq4DVGWv3U4g/ZiH5BvBlqEelDQ==" - }, "node_modules/@module-federation/sdk": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.4.0.tgz", - "integrity": "sha512-fQ/5aABzksXajRLJsocN9XkW8SOB5JRt7xoDmkFFEeb0HLmcbq5K5GURImPm/jysy0Y7a6DkpxhzP9QJU2Z1Zw==" + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.6.12.tgz", + "integrity": "sha512-QC2uwlnDPxf7OYJAKot0zCJl95VV+iBmvCKGGeXLlzbdBFYIFpmE8IkFBLQqTRxtSKF9hv2z4Zltonu7YjRUdQ==" }, "node_modules/@module-federation/third-party-dts-extractor": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@module-federation/third-party-dts-extractor/-/third-party-dts-extractor-0.4.0.tgz", - "integrity": "sha512-zXIfgHiOyZFF6rLjHFt0LJ1SgjO5t/UP05HQgIyMvyZ/Q1cQAcNHGy4iLshrPHthh25sJkClAcrfNTw3/JD9xQ==", + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@module-federation/third-party-dts-extractor/-/third-party-dts-extractor-0.6.12.tgz", + "integrity": "sha512-jhHjd4WYA+Td1c0wK5zYxDEXyZYV4ldIUb2blnE8GuwXRWr5nbdG4RgmPbV7ISyQo6B+uEmE55YIbLeX5r6M5g==", "dependencies": { "find-pkg": "2.0.0", "fs-extra": "9.1.0", @@ -3107,20 +3512,12 @@ } }, "node_modules/@module-federation/webpack-bundler-runtime": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.4.0.tgz", - "integrity": "sha512-IVwqAuBxvgj2j2HEkV2Q1tDrD9ha6mS0qkBgbtabBjbg8fDc4k+NCmZMB7ou5DCojchqtKXBH2iYNzX062CQ8A==", - "dependencies": { - "@module-federation/runtime": "0.4.0", - "@module-federation/sdk": "0.4.0" - } - }, - "node_modules/@module-federation/webpack-bundler-runtime/node_modules/@module-federation/runtime": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.4.0.tgz", - "integrity": "sha512-zEhMil0JbB0eS1bflV9qOJFJNmDCWMJbKUN7Xw5OMLDnveKTg9l/rLqDGwt/kAP0/Lhq1PNuXEvYm1CeIKKU8A==", + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.6.12.tgz", + "integrity": "sha512-LeeRualyA6vA2syhzveNK61JFTMixUFu08JD+jW6OcubXN7EV11K8w6IyWemQ5qmM8V2sDjXCebOyZ+TGafSdg==", "dependencies": { - "@module-federation/sdk": "0.4.0" + "@module-federation/runtime": "0.6.12", + "@module-federation/sdk": "0.6.12" } }, "node_modules/@newrelic/publish-sourcemap": { @@ -3170,17 +3567,10 @@ } }, "node_modules/@openedx/paragon": { - "version": "22.8.1", - "resolved": "https://registry.npmjs.org/@openedx/paragon/-/paragon-22.8.1.tgz", - "integrity": "sha512-lm2x0tvNZrtJvp0L+cjvLLmkE9NoUbNIzt9L1FaOx9g92gf8rFVgq4aadq7IVAjN12HW19/QJMEJaQ0SVsvY2A==", + "version": "22.9.0", + "resolved": "https://registry.npmjs.org/@openedx/paragon/-/paragon-22.9.0.tgz", + "integrity": "sha512-r5xD+z64U3phkgT4ooUQaxE/4Rv0D91tpS3kA+mLfOT1vMD8jXIjDZp+/k4BEw4yqWQ8Eyb//ar8xiwL/ugojQ==", "peer": true, - "workspaces": [ - "example", - "component-generator", - "www", - "icons", - "dependent-usage-analyzer" - ], "dependencies": { "@fortawesome/fontawesome-svg-core": "^6.1.1", "@fortawesome/react-fontawesome": "^0.1.18", @@ -3267,25 +3657,325 @@ "resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-8.2.0.tgz", "integrity": "sha512-iagCqVrw4QSjhxKp3I/YK6+ODkWY6G+YPElvdYKiUUbywwh9Ds0M7r26Fj2/7dWFFbOpcGnJE6uE7aMck8j5Qg==", "peer": true, - "dependencies": { - "hyphenate-style-name": "^1.0.0", - "matchmediaquery": "^0.3.0", - "prop-types": "^15.6.1", - "shallow-equal": "^1.1.0" + "dependencies": { + "hyphenate-style-name": "^1.0.0", + "matchmediaquery": "^0.3.0", + "prop-types": "^15.6.1", + "shallow-equal": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@openedx/paragon/node_modules/shallow-equal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", + "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==", + "peer": true + }, + "node_modules/@openedx/paragon/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "peer": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.4.1.tgz", + "integrity": "sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==", + "optional": true, + "peer": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.4.1", + "@parcel/watcher-darwin-arm64": "2.4.1", + "@parcel/watcher-darwin-x64": "2.4.1", + "@parcel/watcher-freebsd-x64": "2.4.1", + "@parcel/watcher-linux-arm-glibc": "2.4.1", + "@parcel/watcher-linux-arm64-glibc": "2.4.1", + "@parcel/watcher-linux-arm64-musl": "2.4.1", + "@parcel/watcher-linux-x64-glibc": "2.4.1", + "@parcel/watcher-linux-x64-musl": "2.4.1", + "@parcel/watcher-win32-arm64": "2.4.1", + "@parcel/watcher-win32-ia32": "2.4.1", + "@parcel/watcher-win32-x64": "2.4.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.4.1.tgz", + "integrity": "sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz", + "integrity": "sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.4.1.tgz", + "integrity": "sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.4.1.tgz", + "integrity": "sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.4.1.tgz", + "integrity": "sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.4.1.tgz", + "integrity": "sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.4.1.tgz", + "integrity": "sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.1.tgz", + "integrity": "sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.4.1.tgz", + "integrity": "sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.4.1.tgz", + "integrity": "sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.4.1.tgz", + "integrity": "sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.4.1.tgz", + "integrity": "sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "optional": true, + "peer": true, + "bin": { + "detect-libc": "bin/detect-libc.js" }, "engines": { - "node": ">= 0.10" - }, - "peerDependencies": { - "react": ">=16.8.0" + "node": ">=0.10" } }, - "node_modules/@openedx/paragon/node_modules/shallow-equal": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", - "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==", - "peer": true - }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.15", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.15.tgz", @@ -3399,6 +4089,46 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@stylistic/eslint-plugin": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.9.0.tgz", + "integrity": "sha512-OrDyFAYjBT61122MIY1a3SfEgy3YCMgt2vL4eoPmvTwDBwyQhAXurxNQznlRD/jESNfYWfID8Ej+31LljvF7Xg==", + "dependencies": { + "@typescript-eslint/utils": "^8.8.0", + "eslint-visitor-keys": "^4.1.0", + "espree": "^10.2.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/eslint-visitor-keys": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", + "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@testing-library/dom": { "version": "8.20.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", @@ -3640,14 +4370,22 @@ "integrity": "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==" }, "node_modules/@types/eslint": { - "version": "8.56.12", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", - "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, + "node_modules/@types/eslint__js": { + "version": "8.42.3", + "resolved": "https://registry.npmjs.org/@types/eslint__js/-/eslint__js-8.42.3.tgz", + "integrity": "sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw==", + "dependencies": { + "@types/eslint": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -3766,9 +4504,9 @@ } }, "node_modules/@types/jest": { - "version": "29.5.13", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.13.tgz", - "integrity": "sha512-wd+MVEZCHt23V0/L642O5APvspWply/rGY5BcW4SUETo2UzPU3Z26qr8jC2qxpimI2jjx9h7+2cj2FwIr01bXg==", + "version": "29.5.14", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", + "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", "dev": true, "dependencies": { "expect": "^29.0.0", @@ -3827,11 +4565,6 @@ "resolved": "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.36.tgz", "integrity": "sha512-b7bq23s4fgBB76n34m2b3RBf6M369B0Z9uRR8aHTMd8kZISRkmDEpPD8hhpYvDFzr3bJCPES96cm3Q6qRNDbQw==" }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" - }, "node_modules/@types/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", @@ -3910,9 +4643,9 @@ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" }, "node_modules/@types/picomatch": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@types/picomatch/-/picomatch-2.3.4.tgz", - "integrity": "sha512-0so8lU8O5zatZS/2Fi4zrwks+vZv7e0dygrgEZXljODXBig97l4cPQD+9LabXfGJOWwoRkTVz6Q4edZvD12UOA==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/picomatch/-/picomatch-3.0.1.tgz", + "integrity": "sha512-1MRgzpzY0hOp9pW/kLRxeQhUWwil6gnrUYd3oEpeYBqp/FexhaCPv3F8LsYr47gtUU45fO2cm1dbwkSrHEo8Uw==" }, "node_modules/@types/prop-types": { "version": "15.7.13", @@ -3958,9 +4691,9 @@ } }, "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==" }, "node_modules/@types/scheduler": { "version": "0.16.8", @@ -4056,32 +4789,30 @@ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", - "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", - "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/type-utils": "6.21.0", - "@typescript-eslint/utils": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.11.0.tgz", + "integrity": "sha512-KhGn2LjW1PJT2A/GfDpiyOfS4a8xHQv2myUagTM5+zsormOmBlYsnQ6pobJ8XxJmh6hnHwa2Mbe3fPrDJoDhbA==", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.11.0", + "@typescript-eslint/type-utils": "8.11.0", + "@typescript-eslint/utils": "8.11.0", + "@typescript-eslint/visitor-keys": "8.11.0", "graphemer": "^1.4.0", - "ignore": "^5.2.4", + "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -4089,37 +4820,26 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/parser": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", - "dependencies": { - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.11.0.tgz", + "integrity": "sha512-lmt73NeHdy1Q/2ul295Qy3uninSqi6wQI18XwSpm8w0ZbQXUpjCAWP1Vlv/obudoBiIjJVjlztjQ+d/Md98Yxg==", + "dependencies": { + "@typescript-eslint/scope-manager": "8.11.0", + "@typescript-eslint/types": "8.11.0", + "@typescript-eslint/typescript-estree": "8.11.0", + "@typescript-eslint/visitor-keys": "8.11.0", "debug": "^4.3.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -4128,15 +4848,15 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.11.0.tgz", + "integrity": "sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ==", "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" + "@typescript-eslint/types": "8.11.0", + "@typescript-eslint/visitor-keys": "8.11.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -4144,25 +4864,22 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", - "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.11.0.tgz", + "integrity": "sha512-ItiMfJS6pQU0NIKAaybBKkuVzo6IdnAhPFZA/2Mba/uBjuPQPet/8+zh5GtLHwmuFRShZx+8lhIs7/QeDHflOg==", "dependencies": { - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/typescript-estree": "8.11.0", + "@typescript-eslint/utils": "8.11.0", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -4170,11 +4887,11 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.11.0.tgz", + "integrity": "sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw==", "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -4182,21 +4899,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.11.0.tgz", + "integrity": "sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg==", "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", + "@typescript-eslint/types": "8.11.0", + "@typescript-eslint/visitor-keys": "8.11.0", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -4208,6 +4925,20 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -4220,50 +4951,36 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.11.0.tgz", + "integrity": "sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g==", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" + "@typescript-eslint/scope-manager": "8.11.0", + "@typescript-eslint/types": "8.11.0", + "@typescript-eslint/typescript-estree": "8.11.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "eslint": "^8.57.0 || ^9.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.11.0.tgz", + "integrity": "sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw==", "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "8.11.0", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -4728,6 +5445,7 @@ "version": "5.1.3", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, "dependencies": { "deep-equal": "^2.0.5" } @@ -4787,6 +5505,25 @@ "node": ">=0.10.0" } }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.flat": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", @@ -4864,9 +5601,9 @@ "peer": true }, "node_modules/ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==" }, "node_modules/asynckit": { "version": "0.4.0", @@ -4891,9 +5628,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", "funding": [ { "type": "opencollective", @@ -4909,11 +5646,11 @@ } ], "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -4941,9 +5678,9 @@ } }, "node_modules/axe-core": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.0.tgz", - "integrity": "sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==", + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz", + "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==", "engines": { "node": ">=4" } @@ -4991,18 +5728,13 @@ } }, "node_modules/axobject-query": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.4.tgz", - "integrity": "sha512-aPTElBrbifBU1krmZxGZOlBkslORe7Ll7+BDnI50Wy4LgOt69luMgevkDfTq1O/ZgprooPCtWpjCwKSZw/iZ4A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "engines": { "node": ">= 0.4" } }, - "node_modules/b4a": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", - "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==" - }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -5151,48 +5883,6 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, - "node_modules/bare-events": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", - "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", - "optional": true - }, - "node_modules/bare-fs": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", - "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", - "optional": true, - "dependencies": { - "bare-events": "^2.0.0", - "bare-path": "^2.0.0", - "bare-stream": "^2.0.0" - } - }, - "node_modules/bare-os": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", - "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", - "optional": true - }, - "node_modules/bare-path": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", - "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", - "optional": true, - "dependencies": { - "bare-os": "^2.1.0" - } - }, - "node_modules/bare-stream": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.0.tgz", - "integrity": "sha512-pVRWciewGUeCyKEuRxwv06M079r+fRjAQjBEK2P6OYGrO43O+Z0LrPZZEjlc4mB6C2RpZ9AxJ1s7NLEtOHO6eA==", - "optional": true, - "dependencies": { - "b4a": "^1.6.6", - "streamx": "^2.20.0" - } - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -5210,7 +5900,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "peer": true }, "node_modules/batch": { "version": "0.6.1", @@ -5240,6 +5931,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "peer": true, "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -5417,16 +6109,36 @@ "url": "https://feross.org/support" } ], + "peer": true, "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, + "node_modules/buffer-builder": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/buffer-builder/-/buffer-builder-0.2.0.tgz", + "integrity": "sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -5621,11 +6333,6 @@ "node": ">= 6" } }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, "node_modules/chrome-trace-event": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", @@ -5833,6 +6540,11 @@ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" }, + "node_modules/colorjs.io": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.5.2.tgz", + "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -5906,11 +6618,6 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, - "node_modules/confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" - }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", @@ -5963,9 +6670,9 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "engines": { "node": ">= 0.6" } @@ -6116,47 +6823,37 @@ } }, "node_modules/css-loader": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.7.tgz", - "integrity": "sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", + "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", "dependencies": { "icss-utils": "^5.1.0", - "loader-utils": "^2.0.0", - "postcss": "^8.2.15", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.1.0", - "schema-utils": "^3.0.0", - "semver": "^7.3.5" + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.27.0 || ^5.0.0" - } - }, - "node_modules/css-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, "node_modules/css-loader/node_modules/semver": { @@ -6231,12 +6928,12 @@ } }, "node_modules/cssnano": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.0.3.tgz", - "integrity": "sha512-MRq4CIj8pnyZpcI2qs6wswoYoDD1t0aL28n+41c1Ukcpm56m1h6mCexIHBGjfZfnTqtGSSCP4/fB1ovxgjBOiw==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", "dependencies": { - "cssnano-preset-default": "^6.0.3", - "lilconfig": "^3.0.0" + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" }, "engines": { "node": "^14 || ^16 || >=18.0" @@ -6468,20 +7165,6 @@ "node": ">=0.10" } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/dedent": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", @@ -6499,6 +7182,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", "call-bind": "^1.0.5", @@ -6526,14 +7210,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -6547,15 +7223,30 @@ "node": ">=0.10.0" } }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", "dependencies": { - "execa": "^5.0.0" + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" }, "engines": { - "node": ">= 10" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/defaults": { @@ -6755,11 +7446,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/diacritics": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/diacritics/-/diacritics-1.3.0.tgz", - "integrity": "sha512-wlwEkqcsaxvPJML+rDh/2iS824jbREk6DUMUKkEaSlxdYHeS43cClJtsWglvw2RfeXGm6ohKDqsXteJ5sP5enA==" - }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -6791,14 +7477,14 @@ } }, "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dependencies": { "esutils": "^2.0.2" }, "engines": { - "node": ">=6.0.0" + "node": ">=0.10.0" } }, "node_modules/dom-accessibility-api": { @@ -6969,14 +7655,6 @@ "node": ">= 0.8" } }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/enhanced-resolve": { "version": "5.17.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", @@ -7109,6 +7787,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", @@ -7124,6 +7803,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-iterator-helpers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.1.0.tgz", + "integrity": "sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.4", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.3", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", @@ -7231,283 +7934,211 @@ } }, "node_modules/eslint": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz", - "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz", + "integrity": "sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.1.0", - "@eslint/js": "8.44.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.18.0", + "@eslint/core": "^0.7.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.13.0", + "@eslint/plugin-kit": "^0.2.0", + "@humanfs/node": "^0.16.5", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "@humanwhocodes/retry": "^0.3.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.6.0", - "esquery": "^1.4.2", + "eslint-scope": "^8.1.0", + "eslint-visitor-keys": "^4.1.0", + "espree": "^10.2.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-airbnb": { - "version": "19.0.4", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz", - "integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==", - "dependencies": { - "eslint-config-airbnb-base": "^15.0.0", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5" - }, - "engines": { - "node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^7.32.0 || ^8.2.0", - "eslint-plugin-import": "^2.25.3", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.28.0", - "eslint-plugin-react-hooks": "^4.3.0" - } - }, - "node_modules/eslint-config-airbnb-base": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", - "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5", - "semver": "^6.3.0" + "eslint": "bin/eslint.js" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "eslint": "^7.32.0 || ^8.2.0", - "eslint-plugin-import": "^2.25.2" - } - }, - "node_modules/eslint-config-airbnb-typescript": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-17.1.0.tgz", - "integrity": "sha512-GPxI5URre6dDpJ0CtcthSZVBAfI+Uw7un5OYNVxP2EYi3H81Jw701yFP7AU+/vCE7xBtFmjge7kfhhk4+RAiig==", - "dependencies": { - "eslint-config-airbnb-base": "^15.0.0" + "funding": { + "url": "https://eslint.org/donate" }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^5.13.0 || ^6.0.0", - "@typescript-eslint/parser": "^5.0.0 || ^6.0.0", - "eslint": "^7.32.0 || ^8.2.0", - "eslint-plugin-import": "^2.25.3" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.11.1.tgz", - "integrity": "sha512-EwcbfLOhwVMAfatfqLecR2yv3dE5+kQ8kx+Rrt0DvDXEVwW86KQ/xbMDQhtp5l42VXukD5SOF8mQQHbaNtO0CQ==", - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" + "jiti": "*" }, "peerDependenciesMeta": { - "eslint": { + "jiti": { "optional": true } } }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, "node_modules/eslint-plugin-formatjs": { - "version": "4.13.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-formatjs/-/eslint-plugin-formatjs-4.13.3.tgz", - "integrity": "sha512-4j3IVwaLEXblnvH2/ZIOZwc9zaaZf2+zyn/b8oLJRt6kMCTu2rIs4UsIxy5nBRYZzsBSh7k34JJ5/ngGtJ3kYw==", - "dependencies": { - "@formatjs/icu-messageformat-parser": "2.7.8", - "@formatjs/ts-transformer": "3.13.14", - "@types/eslint": "7 || 8", - "@types/picomatch": "^2.3.0", - "@typescript-eslint/utils": "^6.18.1", - "emoji-regex": "^10.2.1", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-formatjs/-/eslint-plugin-formatjs-5.1.3.tgz", + "integrity": "sha512-6PweMZPBPFX4Corrn2PoKGKPdiUiHabvOts76XuW9//UWSybUUBBqmPtdc+GUTOurv3/kkowBE7r7XsJ1KaSaw==", + "dependencies": { + "@formatjs/icu-messageformat-parser": "2.8.0", + "@formatjs/ts-transformer": "3.13.18", + "@types/eslint": "9", + "@types/picomatch": "3", + "@typescript-eslint/utils": "8.11.0", + "emoji-regex": "10", "magic-string": "^0.30.0", - "picomatch": "^2.3.1", - "tslib": "2.6.2", + "picomatch": "2 || 3 || 4", + "tslib": "^2.7.0", "typescript": "5", "unicode-emoji-utils": "^1.2.0" }, "peerDependencies": { - "eslint": "7 || 8" + "eslint": "9" } }, - "node_modules/eslint-plugin-formatjs/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "node_modules/eslint-plugin-formatjs/node_modules/@formatjs/ecma402-abstract": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.0.tgz", + "integrity": "sha512-IpM+ev1E4QLtstniOE29W1rqH9eTdx5hQdNL8pzrflMj/gogfaoONZqL83LUeQScHAvyMbpqP5C9MzNf+fFwhQ==", + "dependencies": { + "@formatjs/fast-memoize": "2.2.1", + "@formatjs/intl-localematcher": "0.5.5", + "tslib": "^2.7.0" + } }, - "node_modules/eslint-plugin-import": { - "version": "2.27.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", - "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", + "node_modules/eslint-plugin-formatjs/node_modules/@formatjs/fast-memoize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.1.tgz", + "integrity": "sha512-XS2RcOSyWxmUB7BUjj3mlPH0exsUzlf6QfhhijgI941WaJhVxXQ6mEWkdUFIdnKi3TuTYxRdelsgv3mjieIGIA==", "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.7.4", - "has": "^1.0.3", - "is-core-module": "^2.11.0", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.6", - "resolve": "^1.22.1", - "semver": "^6.3.0", - "tsconfig-paths": "^3.14.1" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "tslib": "^2.7.0" } }, - "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/eslint-plugin-formatjs/node_modules/@formatjs/icu-messageformat-parser": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.8.0.tgz", + "integrity": "sha512-r2un3fmF9oJv3mOkH+wwQZ037VpqmdfahbcCZ9Lh+p6Sx+sNsonI7Zcr6jNMm1s+Si7ejQORS4Ezlh05mMPAXA==", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@formatjs/ecma402-abstract": "2.2.0", + "@formatjs/icu-skeleton-parser": "1.8.4", + "tslib": "^2.7.0" } }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/eslint-plugin-formatjs/node_modules/@formatjs/icu-skeleton-parser": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.4.tgz", + "integrity": "sha512-LMQ1+Wk1QSzU4zpd5aSu7+w5oeYhupRwZnMQckLPRYhSjf2/8JWQ882BauY9NyHxs5igpuQIXZDgfkaH3PoATg==", "dependencies": { - "ms": "^2.1.1" + "@formatjs/ecma402-abstract": "2.2.0", + "tslib": "^2.7.0" } }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/eslint-plugin-formatjs/node_modules/@formatjs/intl-localematcher": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.5.tgz", + "integrity": "sha512-t5tOGMgZ/i5+ALl2/offNqAQq/lfUnKLEw0mXQI4N4bqpedhrSE+fyKLpwnd22sK0dif6AV+ufQcTsKShB9J1g==", "dependencies": { - "esutils": "^2.0.2" + "tslib": "^2.7.0" + } + }, + "node_modules/eslint-plugin-formatjs/node_modules/@formatjs/ts-transformer": { + "version": "3.13.18", + "resolved": "https://registry.npmjs.org/@formatjs/ts-transformer/-/ts-transformer-3.13.18.tgz", + "integrity": "sha512-bRUJsYLJ4n7GcKAa3a05ePmlsJPum0whNzqr4scUazH6DNr5twLLd2qzmQ9Qu4DDSA/l5X7+ZyuawYxYIpmpAQ==", + "dependencies": { + "@formatjs/icu-messageformat-parser": "2.8.0", + "@types/json-stable-stringify": "1", + "@types/node": "14 || 16 || 17 || 18 || 20", + "chalk": "4", + "json-stable-stringify": "1", + "tslib": "^2.7.0", + "typescript": "5" }, - "engines": { - "node": ">=0.10.0" + "peerDependencies": { + "ts-jest": ">=27" + }, + "peerDependenciesMeta": { + "ts-jest": { + "optional": true + } } }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/eslint-plugin-jest": { + "version": "28.8.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.8.3.tgz", + "integrity": "sha512-HIQ3t9hASLKm2IhIOqnu+ifw7uLZkIlR7RYNv7fMcEi/p0CIiJmfriStQS2LDkgtY4nyLbIZAD+JL347Yc2ETQ==", "dependencies": { - "brace-expansion": "^1.1.7" + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "engines": { - "node": "*" + "node": "^16.10.0 || ^18.12.0 || >=20.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", + "jest": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } } }, "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz", - "integrity": "sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==", - "dependencies": { - "@babel/runtime": "^7.20.7", - "aria-query": "^5.1.3", - "array-includes": "^3.1.6", - "array.prototype.flatmap": "^1.3.1", - "ast-types-flow": "^0.0.7", - "axe-core": "^4.6.2", - "axobject-query": "^3.1.1", + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.1.tgz", + "integrity": "sha512-zHByM9WTUMnfsDTafGXRiqxp6lFtNoSOWBY6FonVRn3A+BUwN1L/tdBXT40BcBJi0cZjOGTXZ0eD/rTG9fEJ0g==", + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", - "has": "^1.0.3", - "jsx-ast-utils": "^3.3.3", - "language-tags": "=1.0.5", + "es-iterator-helpers": "^1.1.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", "minimatch": "^3.1.2", - "object.entries": "^1.1.6", - "object.fromentries": "^2.0.6", - "semver": "^6.3.0" + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" }, "engines": { "node": ">=4.0" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "engines": { + "node": ">= 0.4" } }, "node_modules/eslint-plugin-jsx-a11y/node_modules/emoji-regex": { @@ -7515,85 +8146,46 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/eslint-plugin-react": { - "version": "7.32.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz", - "integrity": "sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==", - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flatmap": "^1.3.1", - "array.prototype.tosorted": "^1.1.1", + "version": "7.37.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz", + "integrity": "sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.1.0", "estraverse": "^5.3.0", + "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.6", - "object.fromentries": "^2.0.6", - "object.hasown": "^1.1.2", - "object.values": "^1.1.6", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.0", "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.4", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.8" + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.11", + "string.prototype.repeat": "^1.0.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0.tgz", + "integrity": "sha512-hIOwI+5hYGpJEc4uPRmz2ulCjAGD/N13Lukkh8cLV0i2IRk/bdZDYjgLVHj+U9Z704kLIdIO6iueGvxNur0sgw==", "engines": { "node": ">=10" }, "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/eslint-plugin-react/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-react/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "node_modules/eslint-plugin-react/node_modules/resolve": { @@ -7613,15 +8205,15 @@ } }, "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", + "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -7638,18 +8230,15 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", + "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/find-up": { @@ -7667,31 +8256,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/eslint/node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -7706,17 +8270,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/eslint/node_modules/p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", @@ -7731,28 +8284,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/espree": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", + "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", + "dependencies": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.1.0" + }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/eslint" } }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", + "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -7859,14 +8412,6 @@ "node": ">= 0.8.0" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "engines": { - "node": ">=6" - } - }, "node_modules/expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -7894,16 +8439,16 @@ } }, "node_modules/express": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -7995,11 +8540,6 @@ "resolved": "https://registry.npmjs.org/fast-defer/-/fast-defer-1.1.8.tgz", "integrity": "sha512-lEJeOH5VL5R09j6AA0D4Uvq7AgsHw0dAImQQ+F3iSyHZuAxyQfWobsagGpTcOPvJr3urmKRHrs+Gs9hV+/Qm/Q==" }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" - }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -8101,14 +8641,14 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/file-loader": { @@ -8260,31 +8800,15 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=16" } }, "node_modules/flatted": { @@ -8366,37 +8890,17 @@ "webpack": "^5.11.0" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dependencies": { - "brace-expansion": "^1.1.7" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": "*" + "node": ">=12" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { @@ -8482,11 +8986,6 @@ "node": ">= 0.6" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, "node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -8634,11 +9133,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -8675,26 +9169,6 @@ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -8731,11 +9205,14 @@ } }, "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "version": "15.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.11.0.tgz", + "integrity": "sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==", "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globalthis": { @@ -8829,14 +9306,6 @@ "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" }, - "node_modules/has": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", - "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -9202,9 +9671,9 @@ } }, "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", @@ -9244,22 +9713,19 @@ "node": ">=10.17.0" } }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "engines": { + "node": ">=10.18" + } + }, "node_modules/hyphenate-style-name": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==" }, - "node_modules/i18n-iso-countries": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/i18n-iso-countries/-/i18n-iso-countries-4.3.1.tgz", - "integrity": "sha512-yxeCvmT8yO1p/epv93c1OHnnYNNMOX6NUNpNfuvzSIcDyripS7OGeKXgzYGd5QI31UK+GBrMG0nPFNv0jrHggw==", - "dependencies": { - "diacritics": "^1.3.0" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -9310,7 +9776,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "peer": true }, "node_modules/ignore": { "version": "5.3.2", @@ -9563,6 +10030,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -9594,6 +10062,20 @@ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -9729,6 +10211,17 @@ "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -9770,6 +10263,37 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -9801,6 +10325,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -9853,14 +10388,6 @@ "node": ">=6" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-obj": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", @@ -10152,15 +10679,30 @@ "node": ">=8" } }, + "node_modules/iterator.prototype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz", + "integrity": "sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==", + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/jest": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.6.1.tgz", - "integrity": "sha512-Nirw5B4nn69rVUZtemCQhwxOBhm0nsp3hmtF4rzCeWD7BkjAXRIji7xWQfnTNbz9g0aVsBX6aZK3n+23LM6uDw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dependencies": { - "@jest/core": "^29.6.1", - "@jest/types": "^29.6.1", + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", "import-local": "^3.0.2", - "jest-cli": "^29.6.1" + "jest-cli": "^29.7.0" }, "bin": { "jest": "bin/jest.js" @@ -10513,17 +11055,17 @@ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" }, "node_modules/jest-environment-jsdom": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.6.1.tgz", - "integrity": "sha512-PoY+yLaHzVRhVEjcVKSfJ7wXmJW4UqPYNhR05h7u/TK0ouf6DmRNZFBL/Z00zgQMyWGMBXn69/FmOvhEJu8cIw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz", + "integrity": "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==", "dependencies": { - "@jest/environment": "^29.6.1", - "@jest/fake-timers": "^29.6.1", - "@jest/types": "^29.6.1", + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/jsdom": "^20.0.0", "@types/node": "*", - "jest-mock": "^29.6.1", - "jest-util": "^29.6.1", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0", "jsdom": "^20.0.0" }, "engines": { @@ -11395,11 +11937,14 @@ "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==" }, "node_modules/language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", "dependencies": { - "language-subtag-registry": "~0.3.2" + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" } }, "node_modules/launch-editor": { @@ -11639,9 +12184,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } @@ -11864,17 +12409,6 @@ "node": ">=6" } }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -11927,25 +12461,23 @@ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, "node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/minimatch/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, "node_modules/mkdirp": { @@ -11960,11 +12492,6 @@ "node": ">=10" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" - }, "node_modules/mrmime": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", @@ -12013,11 +12540,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -12045,37 +12567,17 @@ "tslib": "^2.0.3" } }, - "node_modules/node-abi": { - "version": "3.68.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.68.0.tgz", - "integrity": "sha512-7vbj10trelExNjFSBm5kTvZXXa7pZyKWx9RCKIyqe6I9Ev3IzGpQoqBP3a+cOdxY+pWj6VkP28n/2wWysBHD/A==", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-abi/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/node-abort-controller": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" }, "node_modules/node-addon-api": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", - "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==" + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "optional": true, + "peer": true }, "node_modules/node-forge": { "version": "1.3.1", @@ -12136,16 +12638,6 @@ "url": "https://opencollective.com/nodemon" } }, - "node_modules/nodemon/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/nodemon/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -12155,18 +12647,6 @@ "node": ">=4" } }, - "node_modules/nodemon/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/nodemon/node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -12268,6 +12748,7 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1" @@ -12334,22 +12815,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.hasown": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", - "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", - "dependencies": { - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object.values": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", @@ -12537,15 +13002,19 @@ } }, "node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz", + "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==", "dependencies": { - "@types/retry": "0.12.0", + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", "retry": "^0.13.1" }, "engines": { - "node": ">=8" + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-try": { @@ -12825,9 +13294,9 @@ } }, "node_modules/postcss": { - "version": "8.4.40", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz", - "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==", + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "funding": [ { "type": "opencollective", @@ -12844,8 +13313,8 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -13317,11 +13786,11 @@ } }, "node_modules/postcss-rtlcss": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-rtlcss/-/postcss-rtlcss-5.1.2.tgz", - "integrity": "sha512-cmcgRoO1wL7IJyVHw0RneWI/5Oe75NLC2NLlQLsNI7hcui+yRcW4RrILfQa4FqKQRLTU4r5eF0YPi1qZpMzQpA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/postcss-rtlcss/-/postcss-rtlcss-5.5.0.tgz", + "integrity": "sha512-NkUw3Pq6JNLk/4yE4BszZNpvmLvcX5phTNA0X2thOOPmVVR7sgQXWY+0UjvucsLFL9mQ9IY+YckLyy07yLVijQ==", "dependencies": { - "rtlcss": "4.1.1" + "rtlcss": "4.3.0" }, "engines": { "node": ">=18.0.0" @@ -13376,57 +13845,6 @@ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, - "node_modules/prebuild-install": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", - "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prebuild-install/node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/prebuild-install/node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -13549,20 +13967,6 @@ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, - "node_modules/pubsub-js": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/pubsub-js/-/pubsub-js-1.9.4.tgz", - "integrity": "sha512-hJYpaDvPH4w8ZX/0Fdf9ma1AwRgU353GfbaVfPjfJQf1KxZ2iHaHl3fAUw1qlJIR5dr4F3RzjGaWohYUEyoh7A==" - }, - "node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -13651,11 +14055,6 @@ } ] }, - "node_modules/queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" - }, "node_modules/rambda": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/rambda/-/rambda-9.3.0.tgz", @@ -13699,28 +14098,6 @@ "node": ">= 0.8" } }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", @@ -13818,15 +14195,6 @@ "node": ">=14" } }, - "node_modules/react-dev-utils/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/react-dev-utils/node_modules/cosmiconfig": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", @@ -13917,17 +14285,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/react-dev-utils/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/react-dev-utils/node_modules/p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", @@ -14484,26 +14841,6 @@ "node": ">=6.0.0" } }, - "node_modules/recursive-readdir/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/recursive-readdir/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -14526,6 +14863,26 @@ "@babel/runtime": "^7.9.2" } }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -14837,9 +15194,9 @@ } }, "node_modules/rtlcss": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.1.1.tgz", - "integrity": "sha512-/oVHgBtnPNcggP2aVXQjSy6N1mMAfHg4GSag0QtZBlD5bdDgAHwr4pydqJGd+SUCu9260+Pjqbjwtvu7EMH1KQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", + "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0", @@ -14853,6 +15210,17 @@ "node": ">=12.0.0" } }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -14888,7 +15256,6 @@ "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "peer": true, "dependencies": { "tslib": "^2.1.0" } @@ -14937,44 +15304,403 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sass": { - "version": "1.69.7", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.7.tgz", - "integrity": "sha512-rzj2soDeZ8wtE2egyLXgOOHQvaC2iosZrkF6v3EUG+tBwEvhqUCzm0VP3k9gHF9LXbSrRhT5SksoI56Iw8NPnQ==", + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.4.tgz", + "integrity": "sha512-rhMQ2tSF5CsuuspvC94nPM9rToiAFw2h3JTrLlgmNw1MH79v8Cr3DH6KF6o6r+8oofY3iYVPUf66KzC8yuVN1w==", + "optional": true, + "peer": true, + "dependencies": { + "@parcel/watcher": "^2.4.1", + "chokidar": "^4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.80.4.tgz", + "integrity": "sha512-lPzKX5g79ZxohlPxh0pXTPFseWj9RfgYI0cPm14CH5ok77Ujuheq/DCp7RStvNDWS8RCQ8Ii6gJC/5WTkGyrhA==", + "dependencies": { + "@bufbuild/protobuf": "^2.0.0", + "buffer-builder": "^0.2.0", + "colorjs.io": "^0.5.0", + "immutable": "^4.0.0", + "rxjs": "^7.4.0", + "supports-color": "^8.1.1", + "varint": "^6.0.0" + }, + "bin": { + "sass": "dist/bin/sass.js" + }, + "engines": { + "node": ">=16.0.0" + }, + "optionalDependencies": { + "sass-embedded-android-arm": "1.80.4", + "sass-embedded-android-arm64": "1.80.4", + "sass-embedded-android-ia32": "1.80.4", + "sass-embedded-android-riscv64": "1.80.4", + "sass-embedded-android-x64": "1.80.4", + "sass-embedded-darwin-arm64": "1.80.4", + "sass-embedded-darwin-x64": "1.80.4", + "sass-embedded-linux-arm": "1.80.4", + "sass-embedded-linux-arm64": "1.80.4", + "sass-embedded-linux-ia32": "1.80.4", + "sass-embedded-linux-musl-arm": "1.80.4", + "sass-embedded-linux-musl-arm64": "1.80.4", + "sass-embedded-linux-musl-ia32": "1.80.4", + "sass-embedded-linux-musl-riscv64": "1.80.4", + "sass-embedded-linux-musl-x64": "1.80.4", + "sass-embedded-linux-riscv64": "1.80.4", + "sass-embedded-linux-x64": "1.80.4", + "sass-embedded-win32-arm64": "1.80.4", + "sass-embedded-win32-ia32": "1.80.4", + "sass-embedded-win32-x64": "1.80.4" + } + }, + "node_modules/sass-embedded-android-arm": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.80.4.tgz", + "integrity": "sha512-iAZ7AiKTLGxQGTkZ37c2/7YC4lkbP1o3eP/K74YaF8O+qhKTLyLOwV7OcmzIywac7dqLcNuGqhFCmFqTYpewZw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-arm64": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.80.4.tgz", + "integrity": "sha512-htAuBmRvvN2d4smrqxZ6WBw4+OOURaoHzq5oZKqS/E35zYl5FHmrJzp4S5e26a0tEBcjca014tfb/uu9cQgnqA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-ia32": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-android-ia32/-/sass-embedded-android-ia32-1.80.4.tgz", + "integrity": "sha512-IIee89Jco8/ad2s/oRJTFqpLhBMzg0UXteJyZ5waZPZmkeSR/t9l67Ef1lLQVh9t9/fJ1ViTTiGYm/g/zu6UGw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-riscv64": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.80.4.tgz", + "integrity": "sha512-iJM2kqmWrOeE1aUyTp3uMAG86hyAqbpbOEV7tv828fUsMRDM4uHsHtmyp2n8P2Y0Y2FnLzJpvIm3SwDXGDzT1Q==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-x64": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.80.4.tgz", + "integrity": "sha512-vd8VrLvUoHeTcsDoIJesXLbQYZH26a8lAzXy6u4+vEuAwikF4WiXBDFrpqiv38QeD3faLeoPtksRsFbAdQqJAA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-darwin-arm64": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.80.4.tgz", + "integrity": "sha512-SJz7EM1i4NXa7CT/njIWMNYJ6CvbHljDIzUAZEe3V3u1KWl/eNO3pbWAnnDN62tBppwgWx/UdDUbAKowsT6Z8w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-darwin-x64": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.80.4.tgz", + "integrity": "sha512-J/QlBVO66DLtgALgCmM8rZ5zG0dBCIYW1eXIAnnDwC7vGkbAXMtO60M0O/2WNrAfmFfJz1hvKDLjlsxB2XGBLg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-arm": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.80.4.tgz", + "integrity": "sha512-vuaWhc4ebnaY1AgIWNvFv1snxmkWfvlCU7vnQf4qkn3R2Yyd2J+sjkO8o0NgMX8n5XRUSkAaYUJFCH+Nim6KgQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-arm64": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.80.4.tgz", + "integrity": "sha512-hI6zQyrR6qJbvyEHfj8UGXNB8VyUa72jel46406AuxUnViA0RyZDSqXUF8vwVw/Hjv1LkA5ihK9dBmWNbLz1zQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-ia32": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-ia32/-/sass-embedded-linux-ia32-1.80.4.tgz", + "integrity": "sha512-wcPExI8UbYrrJvGvo4v2Q+RktbCp44i3qZQ18hglPcVZOC1IzT9NPqZn0XmrqD4hmNbgsYR+picODkvqGw7iDA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-arm": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.80.4.tgz", + "integrity": "sha512-HWo0G/9tuhj/uSEwte9KiDK2Xezrfh7nhdEH69ZIfOAqP5byTXL7o08TYagbvMAoljR43Vfna6MelV7NUX4WCw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-arm64": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.80.4.tgz", + "integrity": "sha512-y8slzQ8Jjkl+53mUDkp3zxcDrTXVVxzpa+6nKh5Ue8l1YU2KdVZG1v2PoDXxE6o99B5I2TVBG8i02IsdYoL8jQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-ia32": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-ia32/-/sass-embedded-linux-musl-ia32-1.80.4.tgz", + "integrity": "sha512-A2WSwnomho491iCeHh3c0YRympfAoJOKr+IyxalTcRH/pjENOWZWZUt00WE2q0tTpEd2V+goWvgS5pmUGewgmg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-riscv64": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.80.4.tgz", + "integrity": "sha512-tYQsAHZLr2mnlJQBJ8Z/n/ySIFJ9JWpsUsoLe9fYgGDaBUfItdzUnj15CChRWld8vFe/I84hb7fbCtYXrI60Jg==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-x64": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.80.4.tgz", + "integrity": "sha512-NZnr+SYbWlmXx0IaSQ8oF0jYkOULp9qKWMmmZQ1mxuGQ3z7tJqFhpH3M+hYkrFNeOq+GaH+nhHGOD4ZNBxeRkg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-riscv64": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.80.4.tgz", + "integrity": "sha512-h/BmU7QONa7ScvQztFp4Th4aSo3X+Olu3I+RYsaH9s7P683WT3f2w5zr+wwP1V4roM5eyKDCRJBuefT3Fkkkgw==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-x64": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.80.4.tgz", + "integrity": "sha512-aZbZFs/X9bEmzDiBEiV4IAsKEA0zrCM+s/u2OzvrX4GRvZFJ+/XRTTvf+RTm7mgvTFgfPwCkNGVECQZ1eHh+6A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-arm64": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.80.4.tgz", + "integrity": "sha512-8JiatFi2VVFqCdJzKNDteaPC4KPmh8/giaVh7TyMcDhKjnvRLeu3v5V1egTMiwwpnQHuwzU3uqBlm/llVNR2Pw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-ia32": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-ia32/-/sass-embedded-win32-ia32-1.80.4.tgz", + "integrity": "sha512-SodmTD6mjxEgoq44jWMibmBQvWkCfENK/70zp4qsztcBSOggg3nYUzwG0YpraClAMXpB1xOvzrArWu9/9fguAg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-x64": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.80.4.tgz", + "integrity": "sha512-7+oRRwCCcnOmw152qDiC7x7SphYBo1eLB4KdyThO+7+rYRO8AftXO+kqBPTVSkM8kGp4wxCMF9auPpYBZbjsow==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dependencies": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "bin": { - "sass": "sass.js" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/sass-loader": { - "version": "13.3.3", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.3.tgz", - "integrity": "sha512-mt5YN2F1MOZr3d/wBRcZxeFgwgkH44wVc2zohO2YF6JiOMkiXe4BYRZpSu2sO1g71mo/j16txzUhsKZlqjVGzA==", + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.2.tgz", + "integrity": "sha512-Ll6iXZ1EYwYT19SqW4mSBb76vSSi8JgzElmzIerhEGgzB5hRjDQIWsPmuk1UrAXkR16KJHqVY0eH+5/uw9Tmfw==", "dependencies": { "neo-async": "^2.6.2" }, "engines": { - "node": ">= 14.15.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "fibers": ">= 3.1.0", + "@rspack/core": "0.x || 1.x", "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", "sass": "^1.3.0", "sass-embedded": "*", "webpack": "^5.0.0" }, "peerDependenciesMeta": { - "fibers": { + "@rspack/core": { "optional": true }, "node-sass": { @@ -14985,9 +15711,42 @@ }, "sass-embedded": { "optional": true + }, + "webpack": { + "optional": true } } }, + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sass/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -15270,25 +16029,41 @@ "integrity": "sha512-pfVOw8QZIXpMbhBWvzBISicvToTiM5WBF1EeAUZDDSb5Dt29yl4AYbyywbJFSEsRUMr7gJaxqCdr4L3tQf9wVg==" }, "node_modules/sharp": { - "version": "0.32.6", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", - "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", "hasInstallScript": true, "dependencies": { "color": "^4.2.3", - "detect-libc": "^2.0.2", - "node-addon-api": "^6.1.0", - "prebuild-install": "^7.1.1", - "semver": "^7.5.4", - "simple-get": "^4.0.1", - "tar-fs": "^3.0.4", - "tunnel-agent": "^0.6.0" + "detect-libc": "^2.0.3", + "semver": "^7.6.3" }, "engines": { - "node": ">=14.15.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" } }, "node_modules/sharp/node_modules/semver": { @@ -15351,49 +16126,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -15626,6 +16358,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dev": true, "dependencies": { "internal-slot": "^1.0.4" }, @@ -15675,19 +16408,6 @@ "node": ">= 4.0.0" } }, - "node_modules/streamx": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", - "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", - "dependencies": { - "fast-fifo": "^1.3.2", - "queue-tick": "^1.0.1", - "text-decoder": "^1.1.0" - }, - "optionalDependencies": { - "bare-events": "^2.2.0" - } - }, "node_modules/strict-uri-encode": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", @@ -15754,6 +16474,19 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/string.prototype.matchall": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", @@ -15779,6 +16512,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "node_modules/string.prototype.trim": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", @@ -15876,18 +16618,18 @@ } }, "node_modules/style-loader": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", - "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz", + "integrity": "sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA==", "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^5.0.0" + "webpack": "^5.27.0" } }, "node_modules/stylehacks": { @@ -16102,29 +16844,6 @@ "node": ">=6" } }, - "node_modules/tar-fs": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", - "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", - "dependencies": { - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - }, - "optionalDependencies": { - "bare-fs": "^2.1.1", - "bare-path": "^2.1.0" - } - }, - "node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "node_modules/terser": { "version": "5.34.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.34.0.tgz", @@ -16254,39 +16973,22 @@ "node": ">=8" } }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/text-decoder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.0.tgz", - "integrity": "sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg==", - "dependencies": { - "b4a": "^1.6.4" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, + "node_modules/thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -16416,6 +17118,21 @@ "node": ">=12" } }, + "node_modules/tree-dump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", + "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", @@ -16457,36 +17174,6 @@ "node": ">=10" } }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "engines": { - "node": ">=4" - } - }, "node_modules/tslib": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", @@ -16500,17 +17187,6 @@ "node": ">=0.6.x" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -16623,9 +17299,9 @@ } }, "node_modules/typescript": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -16634,6 +17310,28 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.11.0.tgz", + "integrity": "sha512-cBRGnW3FSlxaYwU8KfAewxFK5uzeOAp0l2KebIlPDOT5olVi65KDG/yjBooPBG0kGW/HLkoz1c/iuBFehcS3IA==", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.11.0", + "@typescript-eslint/parser": "8.11.0", + "@typescript-eslint/utils": "8.11.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", @@ -16935,16 +17633,15 @@ } }, "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.2.tgz", + "integrity": "sha512-14FfcOJmqdjbBPdDjFQyk/SdT4NySW4eM0zcG+HqbHP5jzuH56xO3J1DGhgs/cEMCfwYi3HQI1gnTO62iaG+tQ==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], - "peer": true, "bin": { - "uuid": "dist/bin/uuid" + "uuid": "dist/esm/bin/uuid" } }, "node_modules/v8-to-istanbul": { @@ -16965,6 +17662,11 @@ "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" }, + "node_modules/varint": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", + "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==" + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -17189,75 +17891,97 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", "dependencies": { "colorette": "^2.0.10", - "memfs": "^3.4.3", + "memfs": "^4.6.0", "mime-types": "^2.1.31", + "on-finished": "^2.4.1", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware/node_modules/memfs": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.14.0.tgz", + "integrity": "sha512-JUeY0F/fQZgIod31Ja1eJgiSxLn7BfQlCnqhwXFBzFHEw63OdLK7VJUJ7bnzNsWgCyoUP5tEp1VRY8rDaYzqOA==", + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.3.0", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" } }, "node_modules/webpack-dev-server": { - "version": "4.15.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", - "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.1.0.tgz", + "integrity": "sha512-aQpaN81X6tXie1FoOB7xlMfCsN19pSvRAeYUHOdFWOlhpQ/LlbfTqYwwmEDFV0h8GGuqmCmKmT+pxcUV/Nt2gQ==", + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", "colorette": "^2.0.10", "compression": "^1.7.4", "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", + "express": "^4.19.2", "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", + "html-entities": "^2.4.0", "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.4", - "ws": "^8.13.0" + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" }, "bin": { "webpack-dev-server": "bin/webpack-dev-server.js" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" + "webpack": "^5.0.0" }, "peerDependenciesMeta": { "webpack": { @@ -17268,6 +17992,17 @@ } } }, + "node_modules/webpack-dev-server/node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/webpack-dev-server/node_modules/ipaddr.js": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", @@ -17276,19 +18011,35 @@ "node": ">= 10" } }, - "node_modules/webpack-dev-server/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", + "node_modules/webpack-dev-server/node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", "dependencies": { - "glob": "^7.1.3" + "is-inside-container": "^1.0.0" }, - "bin": { - "rimraf": "bin.js" + "engines": { + "node": ">=16" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webpack-dev-server/node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/webpack-merge": { @@ -17476,6 +18227,31 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-builtin-type": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", + "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", + "dependencies": { + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/which-collection": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", @@ -17556,9 +18332,9 @@ } }, "node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "engines": { "node": ">=10.0.0" }, diff --git a/package.json b/package.json index 7a23dbf6..0ba3066e 100644 --- a/package.json +++ b/package.json @@ -25,12 +25,13 @@ "clean": "rm -rf dist", "docs": "jsdoc -c jsdoc.json", "docs:watch": "nodemon -w runtime -w docs/template -w README.md -e js,jsx,ts,tsx --exec npm run docs", - "lint": "eslint .", + "lint": "eslint .; npm run lint:tools; npm --prefix ./test-project run lint", + "lint:tools": "cd ./tools && eslint . && cd ..", "test": "npm run test:tools && npm run test:app && npm run test:runtime && npm run test:shell", "test:app": "npm --prefix ./test-project i; npm --prefix ./test-project run build", "test:tools": "jest tools --config tools/jest.config.js --no-cache", "test:runtime": "jest runtime --config runtime/jest.config.js --no-cache", - "test:shell": "jest shell --config shell/jest.config.js --no-cache" + "test:shell": "jest shell --config shell/jest.config.js --no-cache --passWithNoTests" }, "repository": { "type": "git", @@ -52,50 +53,47 @@ "@babel/preset-env": "^7.24.8", "@babel/preset-react": "^7.24.7", "@babel/preset-typescript": "^7.24.7", - "@cospired/i18n-iso-languages": "^4.2.0", "@edx/new-relic-source-map-webpack-plugin": "2.1.0", + "@eslint/compat": "^1.2.1", + "@eslint/js": "^9.13.0", "@formatjs/cli": "^6.0.3", - "@formatjs/intl-pluralrules": "^4.3.3", - "@formatjs/intl-relativetimeformat": "^10.0.1", "@formatjs/ts-transformer": "^3.13.14", - "@module-federation/enhanced": "^0.4.0", - "@module-federation/runtime": "^0.2.6", - "@pmmmwh/react-refresh-webpack-plugin": "0.5.15", + "@module-federation/enhanced": "^0.6.12", + "@module-federation/runtime": "^0.6.12", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.15", + "@stylistic/eslint-plugin": "^2.9.0", + "@types/eslint__js": "^8.42.3", "@types/gradient-string": "^1.1.6", - "@typescript-eslint/eslint-plugin": "^6.21.0", - "@typescript-eslint/parser": "^6.21.0", - "autoprefixer": "10.4.19", + "autoprefixer": "^10.4.20", "axios": "^1.7.7", "axios-cache-interceptor": "^1.6.0", "babel-jest": "^29.7.0", "babel-plugin-formatjs": "^10.5.16", - "chalk": "4.1.2", + "chalk": "^4.1.2", "classnames": "^2.5.1", - "clean-webpack-plugin": "4.0.0", + "clean-webpack-plugin": "^4.0.0", "compression": "^1.7.4", - "css-loader": "5.2.7", - "cssnano": "6.0.3", - "eslint": "8.44.0", - "eslint-config-airbnb": "19.0.4", - "eslint-config-airbnb-typescript": "^17.0.0", - "eslint-plugin-formatjs": "^4.12.2", - "eslint-plugin-import": "2.27.5", - "eslint-plugin-jsx-a11y": "6.7.1", - "eslint-plugin-react": "7.32.2", - "eslint-plugin-react-hooks": "4.6.0", + "css-loader": "^7.1.2", + "cssnano": "^6.1.2", + "eslint": "^9.13.0", + "eslint-plugin-formatjs": "^5.1.3", + "eslint-plugin-jest": "^28.8.3", + "eslint-plugin-jsx-a11y": "^6.10.1", + "eslint-plugin-react": "^7.37.2", + "eslint-plugin-react-hooks": "^5.0.0", "express": "^4.18.2", "file-loader": "6.2.0", "fork-ts-checker-webpack-plugin": "^9.0.2", "form-urlencoded": "^6.1.5", "glob": "^7.2.3", + "globals": "^15.11.0", "gradient-string": "^2.0.2", "history": "^4.10.1", "html-webpack-plugin": "5.6.0", - "i18n-iso-countries": "^4.3.1", "identity-obj-proxy": "3.0.0", "image-minimizer-webpack-plugin": "3.8.3", - "jest": "29.6.1", - "jest-environment-jsdom": "29.6.1", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", "jwt-decode": "^3.1.2", "localforage": "^1.10.0", "localforage-memoryStorageDriver": "^0.9.2", @@ -105,12 +103,11 @@ "lodash.snakecase": "^4.1.1", "mini-css-extract-plugin": "1.6.2", "parse5": "7.1.2", - "postcss": "8.4.40", + "postcss": "^8.4.47", "postcss-custom-media": "10.0.8", "postcss-loader": "7.3.4", - "postcss-rtlcss": "5.1.2", + "postcss-rtlcss": "^5.5.0", "prop-types": "^15.8.1", - "pubsub-js": "^1.9.4", "react-dev-utils": "12.0.1", "react-focus-on": "^3.9.4", "react-intl": "^6.6.6", @@ -118,20 +115,22 @@ "react-refresh-typescript": "^2.0.9", "react-responsive": "^10.0.0", "react-transition-group": "^4.4.5", - "resolve-url-loader": "5.0.0", - "sass": "1.69.7", - "sass-loader": "13.3.3", - "sharp": "0.32.6", + "resolve-url-loader": "^5.0.0", + "sass-embedded": "^1.80.4", + "sass-loader": "^16.0.2", + "sharp": "^0.33.5", "source-map-loader": "4.0.2", - "style-loader": "3.3.4", + "style-loader": "^4.0.0", "ts-loader": "^9.5.1", - "typescript": "^5.5.3", + "typescript": "^5.6.3", + "typescript-eslint": "^8.11.0", "universal-cookie": "^4.0.4", - "url-loader": "4.1.1", - "webpack": "^5.89.0", + "url-loader": "^4.1.1", + "uuid": "^11.0.2", + "webpack": "^5.95.0", "webpack-bundle-analyzer": "^4.10.1", "webpack-cli": "^5.1.4", - "webpack-dev-server": "^4.15.1", + "webpack-dev-server": "^5.1.0", "webpack-merge": "^5.10.0", "webpack-remove-empty-scripts": "1.0.4" }, @@ -143,7 +142,7 @@ "@testing-library/user-event": "^14.5.2", "@tsconfig/node18": "^18.2.4", "@types/compression": "^1.7.5", - "@types/jest": "^29.5.12", + "@types/jest": "^29.5.14", "@types/lodash.camelcase": "^4.3.9", "@types/lodash.merge": "^4.6.9", "@types/node": "^18.19.43", diff --git a/runtime/analytics/SegmentAnalyticsService.js b/runtime/analytics/SegmentAnalyticsService.js index 579a24e9..6cdb1938 100644 --- a/runtime/analytics/SegmentAnalyticsService.js +++ b/runtime/analytics/SegmentAnalyticsService.js @@ -70,11 +70,11 @@ class SegmentAnalyticsService { // for methods in Analytics.js so that you never have to wait // for it to load to actually record data. The `method` is // stored as the first argument, so we can replay the data. - analytics.factory = method => ((...args) => { + analytics.factory = method => (...args) => { args.unshift(method); analytics.push(args); return analytics; - }); + }; // For each of our methods, generate a queueing stub. analytics.methods.forEach((key) => { @@ -98,7 +98,7 @@ class SegmentAnalyticsService { // Insert our script next to the first script element. const first = document.getElementsByTagName('script')[0]; first.parentNode.insertBefore(script, first); - analytics._loadOptions = options; // eslint-disable-line no-underscore-dangle + analytics._loadOptions = options; this.segmentInitialized = true; }; @@ -201,7 +201,7 @@ class SegmentAnalyticsService { // This is added to handle the google analytics blocked case which is injected into // the DOM by segment.min.js. setTimeout(() => { - if (!global.ga || !global.ga.create || !global.google_tag_manager) { + if (!global.ga?.create || !global.google_tag_manager) { this.segmentInitialized = false; resolve(); } diff --git a/runtime/analytics/index.js b/runtime/analytics/index.ts similarity index 100% rename from runtime/analytics/index.js rename to runtime/analytics/index.ts diff --git a/runtime/auth/AxiosJwtAuthService.js b/runtime/auth/AxiosJwtAuthService.js index a6311bf3..3af8f32a 100644 --- a/runtime/auth/AxiosJwtAuthService.js +++ b/runtime/auth/AxiosJwtAuthService.js @@ -1,13 +1,13 @@ import axios from 'axios'; import PropTypes from 'prop-types'; -import { logFrontendAuthError } from './utils'; import { camelCaseObject } from '../utils'; -import createJwtTokenProviderInterceptor from './interceptors/createJwtTokenProviderInterceptor'; +import AxiosCsrfTokenService from './AxiosCsrfTokenService'; +import AxiosJwtTokenService from './AxiosJwtTokenService'; import createCsrfTokenProviderInterceptor from './interceptors/createCsrfTokenProviderInterceptor'; +import createJwtTokenProviderInterceptor from './interceptors/createJwtTokenProviderInterceptor'; import createProcessAxiosRequestErrorInterceptor from './interceptors/createProcessAxiosRequestErrorInterceptor'; -import AxiosJwtTokenService from './AxiosJwtTokenService'; -import AxiosCsrfTokenService from './AxiosCsrfTokenService'; import configureCache from './LocalForageCache'; +import { logFrontendAuthError } from './utils'; const optionsPropTypes = { config: PropTypes.shape({ @@ -258,8 +258,7 @@ class AxiosJwtAuthService { await this.fetchAuthenticatedUser(); if (this.getAuthenticatedUser() === null) { - const isRedirectFromLoginPage = global.document.referrer - && global.document.referrer.startsWith(this.config.LOGIN_URL); + const isRedirectFromLoginPage = global.document.referrer?.startsWith(this.config.LOGIN_URL); if (isRedirectFromLoginPage) { const redirectLoopError = new Error('Redirect from login page. Rejecting to avoid infinite redirect loop.'); diff --git a/runtime/auth/AxiosJwtTokenService.js b/runtime/auth/AxiosJwtTokenService.js index 9b28ed2e..69227275 100644 --- a/runtime/auth/AxiosJwtTokenService.js +++ b/runtime/auth/AxiosJwtTokenService.js @@ -61,8 +61,7 @@ export default class AxiosJwtTokenService { try { try { axiosResponse = await this.httpClient.post(`${this.tokenRefreshBaseUrl}${this.tokenRefreshPath}`); - // eslint-disable-next-line max-len - if (axiosResponse.data && axiosResponse.data.response_epoch_seconds) { + if (axiosResponse.data?.response_epoch_seconds) { responseServerEpochSeconds = axiosResponse.data.response_epoch_seconds; } } catch (error) { @@ -125,8 +124,6 @@ export default class AxiosJwtTokenService { } try { - // Eslint is incorrect - refresh() DOES return a promise. - // eslint-disable-next-line @typescript-eslint/return-await return await this.refresh(); } catch (e) { // TODO: Fix these. They're still using loggingService as a singleton. diff --git a/runtime/auth/LocalForageCache.js b/runtime/auth/LocalForageCache.js index 0b9416b2..596033da 100644 --- a/runtime/auth/LocalForageCache.js +++ b/runtime/auth/LocalForageCache.js @@ -1,13 +1,12 @@ -/* eslint-disable no-underscore-dangle */ -import localforage from 'localforage'; -import memoryDriver from 'localforage-memoryStorageDriver'; +import axios from 'axios'; import { - setupCache, - defaultKeyGenerator, - defaultHeaderInterpreter, buildStorage, + defaultHeaderInterpreter, + defaultKeyGenerator, + setupCache, } from 'axios-cache-interceptor'; -import axios from 'axios'; +import localforage from 'localforage'; +import memoryDriver from 'localforage-memoryStorageDriver'; /** * Async function to configure localforage and setup the cache @@ -71,7 +70,6 @@ export default async function configureCache() { // // https://axios-cache-interceptor.js.org/#/pages/development-mode // https://axios-cache-interceptor.js.org/#/pages/global-configuration?id=debug - // eslint-disable-next-line no-console debug: console.log, }, ); diff --git a/runtime/auth/index.js b/runtime/auth/index.ts similarity index 100% rename from runtime/auth/index.js rename to runtime/auth/index.ts diff --git a/runtime/auth/interceptors/createCsrfTokenProviderInterceptor.js b/runtime/auth/interceptors/createCsrfTokenProviderInterceptor.js index bdff94d9..68311f70 100644 --- a/runtime/auth/interceptors/createCsrfTokenProviderInterceptor.js +++ b/runtime/auth/interceptors/createCsrfTokenProviderInterceptor.js @@ -26,7 +26,6 @@ const createCsrfTokenProviderInterceptor = (options) => { } const CSRF_HEADER_NAME = 'X-CSRFToken'; - // eslint-disable-next-line no-param-reassign axiosRequestConfig.headers[CSRF_HEADER_NAME] = csrfToken; return axiosRequestConfig; }; diff --git a/runtime/auth/interceptors/createJwtTokenProviderInterceptor.js b/runtime/auth/interceptors/createJwtTokenProviderInterceptor.js index ae4279e5..b9f57953 100644 --- a/runtime/auth/interceptors/createJwtTokenProviderInterceptor.js +++ b/runtime/auth/interceptors/createJwtTokenProviderInterceptor.js @@ -27,7 +27,6 @@ const createJwtTokenProviderInterceptor = (options) => { } // Add the proper headers to tell the server to look for the jwt cookie - // eslint-disable-next-line no-param-reassign axiosRequestConfig.headers['USE-JWT-COOKIE'] = true; return axiosRequestConfig; }; diff --git a/runtime/auth/interceptors/createRetryInterceptor.js b/runtime/auth/interceptors/createRetryInterceptor.js index 65360e18..55cfef4c 100644 --- a/runtime/auth/interceptors/createRetryInterceptor.js +++ b/runtime/auth/interceptors/createRetryInterceptor.js @@ -52,7 +52,9 @@ const createRetryInterceptor = (options = {}) => { try { const backoffDelay = getBackoffMilliseconds(nthRetry); // Delay (wrapped in a promise so we can await the setTimeout) - await new Promise(resolve => { setTimeout(resolve, backoffDelay); }); + await new Promise(resolve => { + setTimeout(resolve, backoffDelay); + }); // Make retry request retryResponse = await httpClient.request(config); } catch (e) { diff --git a/runtime/auth/interface.js b/runtime/auth/interface.js index ecf85231..42f24122 100644 --- a/runtime/auth/interface.js +++ b/runtime/auth/interface.js @@ -35,6 +35,7 @@ * @module Auth */ import PropTypes from 'prop-types'; +import { publish } from '../subscriptions'; /** * @constant @@ -206,7 +207,7 @@ export function getAuthenticatedUser() { */ export function setAuthenticatedUser(authUser) { service.setAuthenticatedUser(authUser); - global.PubSub.publish(AUTHENTICATED_USER_CHANGED); + publish(AUTHENTICATED_USER_CHANGED); } /** @@ -247,7 +248,7 @@ export async function ensureAuthenticatedUser(redirectUrl) { */ export async function hydrateAuthenticatedUser() { await service.hydrateAuthenticatedUser(); - global.PubSub.publish(AUTHENTICATED_USER_CHANGED); + publish(AUTHENTICATED_USER_CHANGED); } /** diff --git a/runtime/auth/utils.js b/runtime/auth/utils.js index 92c174e5..b9aca0f2 100644 --- a/runtime/auth/utils.js +++ b/runtime/auth/utils.js @@ -101,5 +101,5 @@ export { getUrlParts, logFrontendAuthError, processAxiosError, - processAxiosErrorAndThrow, + processAxiosErrorAndThrow }; diff --git a/runtime/config.ts b/runtime/config/index.ts similarity index 91% rename from runtime/config.ts rename to runtime/config/index.ts index f1ac6ebf..092a20f5 100644 --- a/runtime/config.ts +++ b/runtime/config/index.ts @@ -101,11 +101,14 @@ */ import merge from 'lodash.merge'; -import 'pubsub-js'; import { - AppConfigTypes, ApplicationModuleConfig, ConfigurableAppConfig, EnvironmentTypes, SiteConfig -} from '../types'; -import { CONFIG_CHANGED } from './constants'; + App, + EnvironmentTypes, + RequiredSiteConfig, + SiteConfig +} from '../../types'; +import { APPS_CHANGED, CONFIG_CHANGED } from '../constants'; +import { publish } from '../subscriptions'; let config: SiteConfig = { ACCESS_TOKEN_COOKIE_NAME: 'edx-jwt-cookie-header-payload', @@ -134,7 +137,11 @@ let config: SiteConfig = { ECOMMERCE_BASE_URL: null, PUBLISHER_BASE_URL: null, - apps: {}, + apps: [], + remotes: [], + federatedApps: [], + externalRoutes: [], + pluginSlots: {}, custom: {}, @@ -199,7 +206,7 @@ export function getConfig() { */ export function setConfig(newConfig: SiteConfig) { config = newConfig; - global.PubSub.publish(CONFIG_CHANGED); + publish(CONFIG_CHANGED); } /** @@ -218,19 +225,14 @@ export function setConfig(newConfig: SiteConfig) { * * @param {Object} newConfig */ -export function mergeConfig(newConfig: Partial) { +export function mergeConfig(newConfig: RequiredSiteConfig) { config = merge(config, newConfig); - global.PubSub.publish(CONFIG_CHANGED); + publish(CONFIG_CHANGED); } -export function patchAppModuleConfig(appId: string, appModuleConfig: ApplicationModuleConfig) { - if (config.apps[appId] !== undefined) { - const app = config.apps[appId]; - if (app.type === AppConfigTypes.INTERNAL || app.type === AppConfigTypes.FEDERATED) { - const configurableApp = app as ConfigurableAppConfig; - configurableApp.config = appModuleConfig; - } - } +export function patchApp(app: App) { + config.apps.push(app); + publish(APPS_CHANGED); } /** diff --git a/runtime/constants.js b/runtime/constants.ts similarity index 95% rename from runtime/constants.js rename to runtime/constants.ts index 99bddd83..967490ac 100644 --- a/runtime/constants.js +++ b/runtime/constants.ts @@ -64,3 +64,7 @@ export const APP_INIT_ERROR = `${APP_TOPIC}.INIT_ERROR`; export const CONFIG_TOPIC = 'CONFIG'; export const CONFIG_CHANGED = `${CONFIG_TOPIC}.CHANGED`; + +export const APPS_TOPIC = 'APPS'; + +export const APPS_CHANGED = `${APPS_TOPIC}.CHANGED`; diff --git a/runtime/i18n/countries.js b/runtime/i18n/countries.js deleted file mode 100644 index 8acad645..00000000 --- a/runtime/i18n/countries.js +++ /dev/null @@ -1,71 +0,0 @@ -/* eslint-disable import/extensions */ -import COUNTRIES, { langs as countryLangs } from 'i18n-iso-countries'; - -import arLocale from 'i18n-iso-countries/langs/ar.json'; -import enLocale from 'i18n-iso-countries/langs/en.json'; -import esLocale from 'i18n-iso-countries/langs/es.json'; -import frLocale from 'i18n-iso-countries/langs/fr.json'; -import zhLocale from 'i18n-iso-countries/langs/zh.json'; -import caLocale from 'i18n-iso-countries/langs/ca.json'; -import heLocale from 'i18n-iso-countries/langs/he.json'; -import idLocale from 'i18n-iso-countries/langs/id.json'; -import koLocale from 'i18n-iso-countries/langs/ko.json'; -import plLocale from 'i18n-iso-countries/langs/pl.json'; -import ptLocale from 'i18n-iso-countries/langs/pt.json'; -import ruLocale from 'i18n-iso-countries/langs/ru.json'; -import ukLocale from 'i18n-iso-countries/langs/uk.json'; - -import { getPrimaryLanguageSubtag } from './lib'; - -/* - * COUNTRY LISTS - * - * Lists of country names localized in supported languages. - * - * TODO: When we start dynamically loading translations only for the current locale, change this. - */ - -COUNTRIES.registerLocale(arLocale); -COUNTRIES.registerLocale(enLocale); -COUNTRIES.registerLocale(esLocale); -COUNTRIES.registerLocale(frLocale); -COUNTRIES.registerLocale(zhLocale); -COUNTRIES.registerLocale(caLocale); -COUNTRIES.registerLocale(heLocale); -COUNTRIES.registerLocale(idLocale); -COUNTRIES.registerLocale(koLocale); -COUNTRIES.registerLocale(plLocale); -COUNTRIES.registerLocale(ptLocale); -COUNTRIES.registerLocale(ruLocale); -// COUNTRIES.registerLocale(thLocale); // Doesn't exist in lib. -COUNTRIES.registerLocale(ukLocale); - -/** - * Provides a lookup table of country IDs to country names for the current locale. - * - * @memberof module:I18n - */ -export function getCountryMessages(locale) { - const primaryLanguageSubtag = getPrimaryLanguageSubtag(locale); - const languageCode = countryLangs().includes(primaryLanguageSubtag) ? primaryLanguageSubtag : 'en'; - - return COUNTRIES.getNames(languageCode); -} - -/** - * Provides a list of countries represented as objects of the following shape: - * - * { - * key, // The ID of the country - * name // The localized name of the country - * } - * - * TODO: ARCH-878: The list should be sorted alphabetically in the current locale. - * This is useful for populating dropdowns. - * - * @memberof module:I18n - */ -export function getCountryList(locale) { - const countryMessages = getCountryMessages(locale); - return Object.entries(countryMessages).map(([code, name]) => ({ code, name })); -} diff --git a/runtime/i18n/index.js b/runtime/i18n/index.js index 6d439f6f..a96730a6 100644 --- a/runtime/i18n/index.js +++ b/runtime/i18n/index.js @@ -84,41 +84,34 @@ */ export { - createIntl, FormattedDate, - FormattedTime, - FormattedRelativeTime, + FormattedMessage, FormattedNumber, FormattedPlural, - FormattedMessage, - defineMessages, + FormattedRelativeTime, + FormattedTime, IntlProvider, - useIntl, + createIntl, + defineMessages, + useIntl } from 'react-intl'; export { - intlShape, + LOCALE_CHANGED, + LOCALE_TOPIC, configure, - getPrimaryLanguageSubtag, getLocale, + getLocalizedLanguageName, getMessages, - isRtl, + getPrimaryLanguageSubtag, + getSupportedLanguageList, handleRtl, - mergeMessages, - LOCALE_CHANGED, - LOCALE_TOPIC, + intlShape, + isRtl, + patchMessages, + updateLocale } from './lib'; export { - default as injectIntl, + default as injectIntl } from './injectIntlWithShim'; - -export { - getCountryList, - getCountryMessages, -} from './countries'; - -export { - getLanguageList, - getLanguageMessages, -} from './languages'; diff --git a/runtime/i18n/injectIntlWithShim.jsx b/runtime/i18n/injectIntlWithShim.jsx index 1141b494..b842d4db 100644 --- a/runtime/i18n/injectIntlWithShim.jsx +++ b/runtime/i18n/injectIntlWithShim.jsx @@ -2,7 +2,8 @@ import React from 'react'; import { injectIntl } from 'react-intl'; import { EnvironmentTypes } from '../../types'; import { getConfig } from '../config'; -import { getLoggingService, intlShape } from './lib'; +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 diff --git a/runtime/i18n/languages.js b/runtime/i18n/languages.js deleted file mode 100644 index 6ddd3858..00000000 --- a/runtime/i18n/languages.js +++ /dev/null @@ -1,75 +0,0 @@ -/* eslint-disable import/extensions */ -import LANGUAGES, { langs as languageLangs } from '@cospired/i18n-iso-languages'; - -// import arLocale from '@cospired/i18n-iso-languages/langs/ar.json'; -import enLocale from '@cospired/i18n-iso-languages/langs/en.json'; -import esLocale from '@cospired/i18n-iso-languages/langs/es.json'; -import frLocale from '@cospired/i18n-iso-languages/langs/fr.json'; -// import zhLocale from '@cospired/i18n-iso-languages/langs/zh.json'; -// import caLocale from '@cospired/i18n-iso-languages/langs/ca.json'; -// import heLocale from '@cospired/i18n-iso-languages/langs/he.json'; -// import idLocale from '@cospired/i18n-iso-languages/langs/id.json'; -// import koLocale from '@cospired/i18n-iso-languages/langs/ko.json'; -import plLocale from '@cospired/i18n-iso-languages/langs/pl.json'; -import ptLocale from '@cospired/i18n-iso-languages/langs/pt.json'; -// import ruLocale from '@cospired/i18n-iso-languages/langs/ru.json'; -// import thLocale from '@cospired/i18n-iso-languages/langs/th.json'; -// import ukLocale from '@cospired/i18n-iso-languages/langs/uk.json'; - -import { getPrimaryLanguageSubtag } from './lib'; - -/* - * LANGUAGE LISTS - * - * Lists of language names localized in supported languages. - * - * TODO: When we start dynamically loading translations only for the current locale, change this. - * TODO: Also note that a bunch of languages are missing here. They're present but commented out - * for reference. That's because they're not implemented in this library. If you read this and it's - * been a while, go check and see if that's changed! - */ - -// LANGUAGES.registerLocale(arLocale); -LANGUAGES.registerLocale(enLocale); -LANGUAGES.registerLocale(esLocale); -LANGUAGES.registerLocale(frLocale); -// LANGUAGES.registerLocale(zhLocale); -// LANGUAGES.registerLocale(caLocale); -// LANGUAGES.registerLocale(heLocale); -// LANGUAGES.registerLocale(idLocale); -// LANGUAGES.registerLocale(koLocale); -LANGUAGES.registerLocale(plLocale); -LANGUAGES.registerLocale(ptLocale); -// LANGUAGES.registerLocale(ruLocale); -// LANGUAGES.registerLocale(thLocale); -// LANGUAGES.registerLocale(ukLocale); - -/** - * Provides a lookup table of language IDs to language names for the current locale. - * - * @memberof I18n - */ -export const getLanguageMessages = (locale) => { - const primaryLanguageSubtag = getPrimaryLanguageSubtag(locale); - const languageCode = languageLangs().includes(primaryLanguageSubtag) ? primaryLanguageSubtag : 'en'; - - return LANGUAGES.getNames(languageCode); -}; - -/** - * Provides a list of languages represented as objects of the following shape: - * - * { - * key, // The ID of the language - * name // The localized name of the language - * } - * - * TODO: ARCH-878: The list should be sorted alphabetically in the current locale. - * This is useful for populating dropdowns. - * - * @memberof I18n - */ -export const getLanguageList = (locale) => { - const languageMessages = getLanguageMessages(locale); - return Object.entries(languageMessages).map(([code, name]) => ({ code, name })); -}; diff --git a/runtime/i18n/lib.test.js b/runtime/i18n/lib.test.js index fe5ef545..79a4319f 100644 --- a/runtime/i18n/lib.test.js +++ b/runtime/i18n/lib.test.js @@ -1,5 +1,3 @@ -/* eslint-disable no-console */ -import { EnvironmentTypes } from '../../types'; import { configure, getCookies, @@ -8,96 +6,12 @@ import { getPrimaryLanguageSubtag, handleRtl, isRtl, - mergeMessages, + patchMessages, } from './lib'; jest.mock('universal-cookie'); describe('lib', () => { - describe('configure', () => { - let originalWarn = null; - - beforeEach(() => { - originalWarn = console.warn; - console.warn = jest.fn(); - }); - - afterEach(() => { - console.warn = originalWarn; - }); - - it('should not call console.warn in production', () => { - configure({ - loggingService: { logError: jest.fn() }, - config: { - ENVIRONMENT: EnvironmentTypes.PRODUCTION, - LANGUAGE_PREFERENCE_COOKIE_NAME: 'yum', - }, - messages: { - 'es-419': {}, - de: {}, - 'en-us': {}, - }, - }); - - expect(console.warn).not.toHaveBeenCalled(); - }); - - it('should warn about unexpected locales', () => { - configure({ - loggingService: { logError: jest.fn() }, - config: { - ENVIRONMENT: EnvironmentTypes.DEVELOPMENT, // turn on warnings! - LANGUAGE_PREFERENCE_COOKIE_NAME: 'yum', - }, - messages: { - ar: {}, - 'es-419': {}, - fr: {}, - 'zh-cn': {}, - ca: {}, - he: {}, - id: {}, - 'ko-kr': {}, - pl: {}, - 'pt-br': {}, - ru: {}, - th: {}, - uk: {}, - uhoh: {}, // invalid locale - }, - }); - - expect(console.warn).toHaveBeenCalledWith('Unexpected locale: uhoh'); - }); - - it('should warn about missing locales', () => { - configure({ - loggingService: { logError: jest.fn() }, - config: { - ENVIRONMENT: EnvironmentTypes.DEVELOPMENT, // turn on warnings! - LANGUAGE_PREFERENCE_COOKIE_NAME: 'yum', - }, - messages: {}, - }); - - expect(console.warn).toHaveBeenCalledTimes(15); - expect(console.warn).toHaveBeenCalledWith('Missing locale: ar'); - expect(console.warn).toHaveBeenCalledWith('Missing locale: es-419'); - expect(console.warn).toHaveBeenCalledWith('Missing locale: fr'); - expect(console.warn).toHaveBeenCalledWith('Missing locale: zh-cn'); - expect(console.warn).toHaveBeenCalledWith('Missing locale: ca'); - expect(console.warn).toHaveBeenCalledWith('Missing locale: he'); - expect(console.warn).toHaveBeenCalledWith('Missing locale: id'); - expect(console.warn).toHaveBeenCalledWith('Missing locale: ko-kr'); - expect(console.warn).toHaveBeenCalledWith('Missing locale: pl'); - expect(console.warn).toHaveBeenCalledWith('Missing locale: pt-br'); - expect(console.warn).toHaveBeenCalledWith('Missing locale: ru'); - expect(console.warn).toHaveBeenCalledWith('Missing locale: th'); - expect(console.warn).toHaveBeenCalledWith('Missing locale: uk'); - }); - }); - describe('getPrimaryLanguageSubtag', () => { it('should work for primary language subtags', () => { expect(getPrimaryLanguageSubtag('en')).toEqual('en'); @@ -115,11 +29,6 @@ describe('lib', () => { describe('getLocale', () => { beforeEach(() => { configure({ - loggingService: { logError: jest.fn() }, - config: { - ENVIRONMENT: EnvironmentTypes.PRODUCTION, - LANGUAGE_PREFERENCE_COOKIE_NAME: 'yum', - }, messages: { 'es-419': {}, de: {}, @@ -160,11 +69,6 @@ describe('lib', () => { describe('getMessages', () => { beforeEach(() => { configure({ - loggingService: { logError: jest.fn() }, - config: { - ENVIRONMENT: EnvironmentTypes.PRODUCTION, - LANGUAGE_PREFERENCE_COOKIE_NAME: 'yum', - }, messages: { 'es-419': { message: 'es-hah' }, de: { message: 'de-hah' }, @@ -217,11 +121,6 @@ describe('lib', () => { it('should do the right thing for non-RTL languages', () => { getCookies().get = jest.fn(() => 'es-419'); configure({ - loggingService: { logError: jest.fn() }, - config: { - ENVIRONMENT: EnvironmentTypes.PRODUCTION, - LANGUAGE_PREFERENCE_COOKIE_NAME: 'yum', - }, messages: { 'es-419': { message: 'es-hah' }, }, @@ -234,11 +133,6 @@ describe('lib', () => { it('should do the right thing for RTL languages', () => { getCookies().get = jest.fn(() => 'ar'); configure({ - loggingService: { logError: jest.fn() }, - config: { - ENVIRONMENT: EnvironmentTypes.PRODUCTION, - LANGUAGE_PREFERENCE_COOKIE_NAME: 'yum', - }, messages: { ar: { message: 'ar-hah' }, }, @@ -250,19 +144,14 @@ describe('lib', () => { }); }); -describe('mergeMessages', () => { +describe('patchMessages', () => { it('should merge objects', () => { configure({ - loggingService: { logError: jest.fn() }, - config: { - ENVIRONMENT: EnvironmentTypes.PRODUCTION, - LANGUAGE_PREFERENCE_COOKIE_NAME: 'yum', - }, messages: { ar: { message: 'ar-hah' }, }, }); - const result = mergeMessages({ en: { foo: 'bar' }, de: { buh: 'baz' }, jp: { gah: 'wut' } }); + const result = patchMessages({ en: { foo: 'bar' }, de: { buh: 'baz' }, jp: { gah: 'wut' } }); expect(result).toEqual({ ar: { message: 'ar-hah' }, en: { foo: 'bar' }, @@ -273,16 +162,11 @@ describe('mergeMessages', () => { it('should merge objects from an array', () => { configure({ - loggingService: { logError: jest.fn() }, - config: { - ENVIRONMENT: EnvironmentTypes.PRODUCTION, - LANGUAGE_PREFERENCE_COOKIE_NAME: 'yum', - }, messages: { ar: { message: 'ar-hah' }, }, }); - const result = mergeMessages([{ foo: 'bar' }, { buh: 'baz' }, { gah: 'wut' }]); + const result = patchMessages([{ foo: 'bar' }, { buh: 'baz' }, { gah: 'wut' }]); expect(result).toEqual({ ar: { message: 'ar-hah' }, foo: 'bar', @@ -293,11 +177,6 @@ describe('mergeMessages', () => { it('should merge nested objects from an array', () => { configure({ - loggingService: { logError: jest.fn() }, - config: { - ENVIRONMENT: EnvironmentTypes.PRODUCTION, - LANGUAGE_PREFERENCE_COOKIE_NAME: 'yum', - }, messages: { en: { init: 'initial' }, es: { init: 'inicial' }, @@ -314,7 +193,7 @@ describe('mergeMessages', () => { }, ]; - const result = mergeMessages(messages); + const result = patchMessages(messages); expect(result).toEqual({ en: { init: 'initial', @@ -331,31 +210,21 @@ describe('mergeMessages', () => { it('should return an empty object if no messages', () => { configure({ - loggingService: { logError: jest.fn() }, - config: { - ENVIRONMENT: EnvironmentTypes.PRODUCTION, - LANGUAGE_PREFERENCE_COOKIE_NAME: 'yum', - }, messages: {}, }); - expect(mergeMessages(undefined)).toEqual({}); - expect(mergeMessages(null)).toEqual({}); - expect(mergeMessages([])).toEqual({}); - expect(mergeMessages({})).toEqual({}); + expect(patchMessages(undefined)).toEqual({}); + expect(patchMessages(null)).toEqual({}); + expect(patchMessages([])).toEqual({}); + expect(patchMessages({})).toEqual({}); }); it('should return the original object if no messages', () => { configure({ - loggingService: { logError: jest.fn() }, - config: { - ENVIRONMENT: EnvironmentTypes.PRODUCTION, - LANGUAGE_PREFERENCE_COOKIE_NAME: 'yum', - }, messages: { en: { hello: 'world ' } }, }); - expect(mergeMessages(undefined)).toEqual({ en: { hello: 'world ' } }); - expect(mergeMessages(null)).toEqual({ en: { hello: 'world ' } }); - expect(mergeMessages([])).toEqual({ en: { hello: 'world ' } }); - expect(mergeMessages({})).toEqual({ en: { hello: 'world ' } }); + expect(patchMessages(undefined)).toEqual({ en: { hello: 'world ' } }); + expect(patchMessages(null)).toEqual({ en: { hello: 'world ' } }); + expect(patchMessages([])).toEqual({ en: { hello: 'world ' } }); + expect(patchMessages({})).toEqual({ en: { hello: 'world ' } }); }); }); diff --git a/runtime/i18n/lib.ts b/runtime/i18n/lib.ts index fdf8752a..07e95787 100644 --- a/runtime/i18n/lib.ts +++ b/runtime/i18n/lib.ts @@ -3,72 +3,53 @@ import PropTypes from 'prop-types'; import { MessageFormatElement } from 'react-intl'; import Cookies from 'universal-cookie'; -import '@formatjs/intl-pluralrules/polyfill'; -import '@formatjs/intl-relativetimeformat/polyfill'; - -import '@formatjs/intl-pluralrules/locale-data/ar'; -import '@formatjs/intl-pluralrules/locale-data/ca'; -import '@formatjs/intl-pluralrules/locale-data/en'; -import '@formatjs/intl-pluralrules/locale-data/es'; -import '@formatjs/intl-pluralrules/locale-data/fr'; -import '@formatjs/intl-pluralrules/locale-data/he'; -import '@formatjs/intl-pluralrules/locale-data/id'; -import '@formatjs/intl-pluralrules/locale-data/ko'; -import '@formatjs/intl-pluralrules/locale-data/pl'; -import '@formatjs/intl-pluralrules/locale-data/pt'; -import '@formatjs/intl-pluralrules/locale-data/ru'; -import '@formatjs/intl-pluralrules/locale-data/th'; -import '@formatjs/intl-pluralrules/locale-data/uk'; -import '@formatjs/intl-pluralrules/locale-data/zh'; - -import '@formatjs/intl-relativetimeformat/locale-data/ar'; -import '@formatjs/intl-relativetimeformat/locale-data/ca'; -import '@formatjs/intl-relativetimeformat/locale-data/en'; -import '@formatjs/intl-relativetimeformat/locale-data/es'; -import '@formatjs/intl-relativetimeformat/locale-data/fr'; -import '@formatjs/intl-relativetimeformat/locale-data/he'; -import '@formatjs/intl-relativetimeformat/locale-data/id'; -import '@formatjs/intl-relativetimeformat/locale-data/ko'; -import '@formatjs/intl-relativetimeformat/locale-data/pl'; -import '@formatjs/intl-relativetimeformat/locale-data/pt'; -import '@formatjs/intl-relativetimeformat/locale-data/ru'; -import '@formatjs/intl-relativetimeformat/locale-data/th'; -import '@formatjs/intl-relativetimeformat/locale-data/uk'; -import '@formatjs/intl-relativetimeformat/locale-data/zh'; - -import { EnvironmentTypes, SiteConfig } from '../../types'; -import { LoggingService } from '../logging/types'; +import { LocalizedMessages } from '../../types'; +import { getConfig } from '../config'; +import { publish } from '../subscriptions'; const cookies = new Cookies(); -const supportedLocales = [ - 'ar', // Arabic - // NOTE: 'en' is not included in this list intentionally, since it's the fallback. - 'es-419', // Spanish, Latin American - 'fa', // Farsi - 'fa-ir', // Farsi, Iran - 'fr', // French - 'zh-cn', // Chinese, Simplified - 'ca', // Catalan - 'he', // Hebrew - 'id', // Indonesian - 'ko-kr', // Korean (Korea) - 'pl', // Polish - 'pt-br', // Portuguese (Brazil) - 'ru', // Russian - 'th', // Thai - 'uk', // Ukrainian -]; + +// This list is based on https://help.smartling.com/hc/en-us/articles/1260802028830-Right-to-left-RTL-Languages +// There are very few resources available online outlining the locale codes for RTL languages; +// If this list is inaccurate, we should change it. const rtlLocales = [ - 'ar', // Arabic - 'he', // Hebrew - 'fa', // Farsi (not currently supported) - 'fa-ir', // Farsi Iran - 'ur', // Urdu (not currently supported) + 'ar', // Arabic (International) + 'ar-ae', // Arabic (United Arab Emirates) + 'ar-bh', // Arabic (Bahrain) + 'ar-dj', // Arabic (Djibouti) + 'ar-dz', // Arabic (Algeria) + 'ar-eg', // Arabic (Egypt) + 'ar-iq', // Arabic (Iraq) + 'ar-jo', // Arabic (Jordan) + 'ar-kw', // Arabic (Kuwait) + 'ar-lb', // Arabic (Lebanon) + 'ar-ly', // Arabic (Libya) + 'ar-ma', // Arabic (Morocco) + 'ar-om', // Arabic (Oman) + 'ar-qa', // Arabic (Qatar) + 'ar-sa', // Arabic (Saudi Arabia) + 'ar-sd', // Arabic (Sudan) + 'ar-sy', // Arabic (Syria) + 'ar-tn', // Arabic (Tunisia) + 'ar-ye', // Arabic (Yemen) + 'fa', // Persian + 'fa-af', // Dari/Persian (Afghanistan) + 'fa-ir', // Persian (Iran) + 'he', // Hebrew (he) + 'he-il', // Hebrew + 'iw', // Hebrew (iw) + 'kd', // Kurdish (Sorani) RTL + 'pk-pk', // Panjabi-Shahmuki (Pakistan) + 'ps', // Pushto; Pashto + 'ug', // Uighur; Uyghur + 'ur', // Urdu + 'ur-in', // Urdu (India) + 'ur-pk', // Urdu (Pakistan) + 'yi', // Yiddish + 'yi-us', // Yiddish (United States) ]; -let config: SiteConfig | null = null; -let loggingService: LoggingService | null = null; -let messages: { [locale: string]: Record | Record | undefined }; +let messages: Record | Record | undefined>; /** * @memberof module:Internationalization @@ -82,13 +63,6 @@ let messages: { [locale: string]: Record | Record loggingService; - /** * @memberof module:Internationalization */ @@ -159,7 +133,7 @@ export function findSupportedLocale(locale) { * @memberof module:Internationalization */ export function getLocale(locale?: string) { - if (messages === null || config === null) { + if (messages === null) { throw new Error('getLocale called before configuring i18n. Call configure with messages first.'); } @@ -168,8 +142,8 @@ export function getLocale(locale?: string) { return findSupportedLocale(locale); } // 2. User setting in cookie - const cookieLangPref = cookies - .get(config.LANGUAGE_PREFERENCE_COOKIE_NAME); + + const cookieLangPref = cookies.get(getConfig().LANGUAGE_PREFERENCE_COOKIE_NAME); if (cookieLangPref) { return findSupportedLocale(cookieLangPref.toLowerCase()); } @@ -180,6 +154,32 @@ export function getLocale(locale?: string) { return findSupportedLocale(globalThis.navigator.language.toLowerCase()); } +export function getLocalizedLanguageName(locale) { + const localizedName = (new Intl.DisplayNames([locale], { type: 'language' })).of(locale); + + if (localizedName === undefined) { + throw new Error(`Unsupported locale: ${locale}`); + } + + return `${localizedName.charAt(0).toLocaleUpperCase(locale)}${localizedName.slice(1)}`; +} + +export function getSupportedLanguageList() { + const locales = Object.keys(messages); + locales.push('en'); // 'en' is not in the messages object because it's the default. + locales.sort(); + + return locales.map((locale) => ({ + code: locale, + name: getLocalizedLanguageName(locale), + })); +} + +export function updateLocale() { + handleRtl(); + publish(LOCALE_CHANGED); +} + /** * Returns messages for the provided locale, or the user's preferred locale if no argument is * provided. @@ -219,34 +219,6 @@ export function handleRtl() { } } -const messagesShape = { - ar: PropTypes.objectOf(PropTypes.string), // Arabic - en: PropTypes.objectOf(PropTypes.string), - 'es-419': PropTypes.objectOf(PropTypes.string), // Spanish, Latin American - fr: PropTypes.objectOf(PropTypes.string), // French - 'zh-cn': PropTypes.objectOf(PropTypes.string), // Chinese, Simplified - ca: PropTypes.objectOf(PropTypes.string), // Catalan - he: PropTypes.objectOf(PropTypes.string), // Hebrew - id: PropTypes.objectOf(PropTypes.string), // Indonesian - 'ko-kr': PropTypes.objectOf(PropTypes.string), // Korean (Korea) - pl: PropTypes.objectOf(PropTypes.string), // Polish - 'pt-br': PropTypes.objectOf(PropTypes.string), // Portuguese (Brazil) - ru: PropTypes.objectOf(PropTypes.string), // Russian - th: PropTypes.objectOf(PropTypes.string), // Thai - uk: PropTypes.objectOf(PropTypes.string), // Ukrainian -}; - -const optionsShape = { - config: PropTypes.object.isRequired, - loggingService: PropTypes.shape({ - logError: PropTypes.func.isRequired, - }).isRequired, - messages: PropTypes.oneOfType([ - PropTypes.shape(messagesShape), - PropTypes.arrayOf(PropTypes.shape(messagesShape)), - ]).isRequired, -}; - /** * * @@ -254,7 +226,7 @@ const optionsShape = { * @returns {Object} * @memberof module:Internationalization */ -export function mergeMessages(newMessages) { +export function patchMessages(newMessages = {}) { const msgs = Array.isArray(newMessages) ? merge({}, ...newMessages) : newMessages; messages = merge(messages, msgs); @@ -262,9 +234,7 @@ export function mergeMessages(newMessages) { } interface ConfigureI18nOptions { - loggingService: LoggingService, - messages: Array<{ [locale: string]: { [key: string]: string } }> | { [locale: string]: { [key: string]: string } }, - config: SiteConfig, + messages: LocalizedMessages[] | LocalizedMessages, } /** @@ -274,32 +244,11 @@ interface ConfigureI18nOptions { * above), or if an expected locale is not provided. * * @param {Object} options - * @param {LoggingService} options.loggingService - * @param {Object} options.config * @param {Object} options.messages * @memberof module:Internationalization */ export function configure(options: ConfigureI18nOptions) { - PropTypes.checkPropTypes(optionsShape, options, 'property', 'i18n'); - // eslint-disable-next-line prefer-destructuring - loggingService = options.loggingService; - // eslint-disable-next-line prefer-destructuring - config = options.config; messages = Array.isArray(options.messages) ? merge({}, ...options.messages) : options.messages; - if (config.ENVIRONMENT === EnvironmentTypes.DEVELOPMENT && messages !== undefined) { - Object.keys(messages).forEach((key) => { - if (supportedLocales.indexOf(key) < 0) { - console.warn(`Unexpected locale: ${key}`); // eslint-disable-line no-console - } - }); - - supportedLocales.forEach((key) => { - if (messages === undefined || messages[key] === undefined) { - console.warn(`Missing locale: ${key}`); // eslint-disable-line no-console - } - }); - } - handleRtl(); } diff --git a/runtime/index.ts b/runtime/index.ts index a729d56c..d6cc2a11 100644 --- a/runtime/index.ts +++ b/runtime/index.ts @@ -64,18 +64,17 @@ export { configure as configureI18n, createIntl, defineMessages, - getCountryList, - getCountryMessages, - getLanguageList, - getLanguageMessages, getLocale, + getLocalizedLanguageName, getMessages, getPrimaryLanguageSubtag, + getSupportedLanguageList, handleRtl, injectIntl, intlShape, isRtl, - mergeMessages, + patchMessages, + updateLocale, useIntl } from './i18n'; @@ -102,12 +101,6 @@ export { PluginSlot } from './plugins'; -export { - publish, - subscribe, - unsubscribe -} from './pubSub'; - export { AppContext, AppProvider, @@ -122,6 +115,13 @@ export { useConfig } from './react'; +export { + clearAllSubscriptions, + publish, + subscribe, + unsubscribe +} from './subscriptions'; + export { initializeMockApp, mockMessages diff --git a/runtime/initialize.async.function.config.test.js b/runtime/initialize.async.function.config.test.js index 323bf1cc..e8bb479d 100644 --- a/runtime/initialize.async.function.config.test.js +++ b/runtime/initialize.async.function.config.test.js @@ -1,15 +1,14 @@ -import 'pubsub-js'; -import { initialize } from './initialize'; - import { ensureAuthenticatedUser, fetchAuthenticatedUser, hydrateAuthenticatedUser, } from './auth'; import { getConfig } from './config'; +import { initialize } from './initialize'; import { logError, } from './logging'; +import { clearAllSubscriptions } from './subscriptions'; jest.mock('./logging'); jest.mock('./auth'); @@ -32,7 +31,7 @@ describe('initialize with async function js file config', () => { ensureAuthenticatedUser.mockReset(); hydrateAuthenticatedUser.mockReset(); logError.mockReset(); - global.PubSub.clearAllSubscriptions(); + clearAllSubscriptions(); }); it('should initialize the app with async function javascript file configuration', async () => { diff --git a/runtime/initialize.const.config.test.js b/runtime/initialize.const.config.test.js index 3f30c90c..ec0d7fbe 100644 --- a/runtime/initialize.const.config.test.js +++ b/runtime/initialize.const.config.test.js @@ -1,15 +1,14 @@ -import 'pubsub-js'; -import { initialize } from './initialize'; - import { ensureAuthenticatedUser, fetchAuthenticatedUser, hydrateAuthenticatedUser, } from './auth'; import { getConfig } from './config'; +import { initialize } from './initialize'; import { logError, } from './logging'; +import { clearAllSubscriptions } from './subscriptions'; jest.mock('./logging'); jest.mock('./auth'); @@ -30,7 +29,7 @@ describe('initialize with constant js file config', () => { ensureAuthenticatedUser.mockReset(); hydrateAuthenticatedUser.mockReset(); logError.mockReset(); - global.PubSub.clearAllSubscriptions(); + clearAllSubscriptions(); }); it('should initialize the app with javascript file configuration', async () => { diff --git a/runtime/initialize.function.config.test.js b/runtime/initialize.function.config.test.js index 4683754e..d1a65587 100644 --- a/runtime/initialize.function.config.test.js +++ b/runtime/initialize.function.config.test.js @@ -1,5 +1,3 @@ -import 'pubsub-js'; - import { ensureAuthenticatedUser, fetchAuthenticatedUser, @@ -10,6 +8,7 @@ import { initialize } from './initialize'; import { logError, } from './logging'; +import { clearAllSubscriptions } from './subscriptions'; jest.mock('./logging'); jest.mock('./auth'); @@ -30,7 +29,7 @@ describe('initialize with function js file config', () => { ensureAuthenticatedUser.mockReset(); hydrateAuthenticatedUser.mockReset(); logError.mockReset(); - global.PubSub.clearAllSubscriptions(); + clearAllSubscriptions(); }); it('should initialize the app with javascript file configuration', async () => { diff --git a/runtime/initialize.js b/runtime/initialize.js index 96e6f6b9..053b542f 100644 --- a/runtime/initialize.js +++ b/runtime/initialize.js @@ -56,8 +56,6 @@ This 'site.config' package is a special 'magic' alias in our webpack configurati folder. It points at an `site.config.tsx` file in the root of an project's repository. */ import siteConfig from 'site.config'; -import { getPath } from './utils'; -// eslint-disable-next-line import/no-cycle import { configure as configureAnalytics, identifyAnonymousUser, @@ -95,6 +93,8 @@ import { NewRelicLoggingService, } from './logging'; import { GoogleAnalyticsLoader } from './scripts'; +import { publish } from './subscriptions'; +import { getPath } from './utils'; /** * A browser history or memory history object created by the [history](https://github.com/ReactTraining/history) @@ -198,7 +198,6 @@ async function runtimeConfig() { mergeConfig(data); } } catch (error) { - // eslint-disable-next-line no-console console.error('Error with config API', error.message); } } @@ -220,7 +219,7 @@ export function loadExternalScripts(externalScripts, data) { */ export async function analytics() { const authenticatedUser = getAuthenticatedUser(); - if (authenticatedUser && authenticatedUser.userId) { + if (authenticatedUser?.userId) { identifyAuthenticatedUser(authenticatedUser.userId); } else { await identifyAnonymousUser(); @@ -305,13 +304,13 @@ export async function initialize({ try { // Pub/Sub await handlers.pubSub(); - global.PubSub.publish(APP_PUBSUB_INITIALIZED); + publish(APP_PUBSUB_INITIALIZED); // Configuration await fileConfig(); await handlers.config(); await runtimeConfig(); - global.PubSub.publish(APP_CONFIG_INITIALIZED); + publish(APP_CONFIG_INITIALIZED); loadExternalScripts(externalScripts, { config: getConfig(), @@ -331,16 +330,14 @@ export async function initialize({ config: getConfig(), }); await handlers.logging(); - global.PubSub.publish(APP_LOGGING_INITIALIZED); + publish(APP_LOGGING_INITIALIZED); // Internationalization configureI18n({ messages, - config: getConfig(), - loggingService: getLoggingService(), }); await handlers.i18n(); - global.PubSub.publish(APP_I18N_INITIALIZED); + publish(APP_I18N_INITIALIZED); // Authentication configureAuth(authServiceImpl, { @@ -350,7 +347,7 @@ export async function initialize({ }); await handlers.auth(requireUser, hydrateUser); - global.PubSub.publish(APP_AUTH_INITIALIZED); + publish(APP_AUTH_INITIALIZED); // Analytics configureAnalytics(analyticsServiceImpl, { @@ -359,16 +356,16 @@ export async function initialize({ httpClient: getAuthenticatedHttpClient(), }); await handlers.analytics(); - global.PubSub.publish(APP_ANALYTICS_INITIALIZED); + publish(APP_ANALYTICS_INITIALIZED); // Application Ready await handlers.ready(); - global.PubSub.publish(APP_READY); + publish(APP_READY); } catch (error) { if (!error.isRedirecting) { // Initialization Error await handlers.initError(error); - global.PubSub.publish(APP_INIT_ERROR, error); + publish(APP_INIT_ERROR, error); } } } diff --git a/runtime/initialize.test.js b/runtime/initialize.test.js index bae7a535..c6f8d66d 100644 --- a/runtime/initialize.test.js +++ b/runtime/initialize.test.js @@ -1,5 +1,5 @@ import { createBrowserHistory } from 'history'; -import 'pubsub-js'; + import { APP_ANALYTICS_INITIALIZED, APP_AUTH_INITIALIZED, @@ -31,6 +31,7 @@ import { logError, NewRelicLoggingService, } from './logging'; +import { clearAllSubscriptions, subscribe } from './subscriptions'; jest.mock('./logging'); jest.mock('./auth'); @@ -83,7 +84,7 @@ describe('initialize', () => { ensureAuthenticatedUser.mockReset(); hydrateAuthenticatedUser.mockReset(); logError.mockReset(); - global.PubSub.clearAllSubscriptions(); + clearAllSubscriptions(); }); it('should call default handlers in the absence of overrides', async () => { @@ -106,13 +107,13 @@ describe('initialize', () => { } } - global.PubSub.subscribe(APP_PUBSUB_INITIALIZED, checkDispatchedDone); - global.PubSub.subscribe(APP_CONFIG_INITIALIZED, checkDispatchedDone); - global.PubSub.subscribe(APP_LOGGING_INITIALIZED, checkDispatchedDone); - global.PubSub.subscribe(APP_AUTH_INITIALIZED, checkDispatchedDone); - global.PubSub.subscribe(APP_ANALYTICS_INITIALIZED, checkDispatchedDone); - global.PubSub.subscribe(APP_I18N_INITIALIZED, checkDispatchedDone); - global.PubSub.subscribe(APP_READY, checkDispatchedDone); + subscribe(APP_PUBSUB_INITIALIZED, checkDispatchedDone); + subscribe(APP_CONFIG_INITIALIZED, checkDispatchedDone); + subscribe(APP_LOGGING_INITIALIZED, checkDispatchedDone); + subscribe(APP_AUTH_INITIALIZED, checkDispatchedDone); + subscribe(APP_ANALYTICS_INITIALIZED, checkDispatchedDone); + subscribe(APP_I18N_INITIALIZED, checkDispatchedDone); + subscribe(APP_READY, checkDispatchedDone); const messages = { i_am: 'a message' }; await initialize({ messages }); @@ -130,8 +131,6 @@ describe('initialize', () => { }); expect(configureI18n).toHaveBeenCalledWith({ messages, - config, - loggingService: getLoggingService(), }); expect(fetchAuthenticatedUser).toHaveBeenCalled(); expect(ensureAuthenticatedUser).not.toHaveBeenCalled(); @@ -222,7 +221,7 @@ describe('initialize', () => { expect(data).toEqual(new Error('uhoh!')); } - global.PubSub.subscribe(APP_INIT_ERROR, errorHandler); + subscribe(APP_INIT_ERROR, errorHandler); await initialize({ messages: null, @@ -258,7 +257,7 @@ describe('initialize', () => { expect(data).toEqual(new Error('uhoh!')); } - global.PubSub.subscribe(APP_INIT_ERROR, errorHandler); + subscribe(APP_INIT_ERROR, errorHandler); await initialize({ messages: null, @@ -311,8 +310,6 @@ describe('initialize', () => { }); expect(configureI18n).toHaveBeenCalledWith({ messages, - config, - loggingService: getLoggingService(), }); expect(fetchAuthenticatedUser).toHaveBeenCalled(); @@ -364,8 +361,6 @@ describe('initialize', () => { }); expect(configureI18n).toHaveBeenCalledWith({ messages, - config, - loggingService: getLoggingService(), }); expect(fetchAuthenticatedUser).toHaveBeenCalled(); expect(ensureAuthenticatedUser).not.toHaveBeenCalled(); diff --git a/runtime/logging/NewRelicLoggingService.js b/runtime/logging/NewRelicLoggingService.js index d52c75fe..051dbd45 100644 --- a/runtime/logging/NewRelicLoggingService.js +++ b/runtime/logging/NewRelicLoggingService.js @@ -26,7 +26,7 @@ const pageActionNameIgnoredError = 'IGNORED_ERROR'; function sendPageAction(actionName, message, customAttributes) { if (getConfig().ENVIRONMENT === EnvironmentTypes.DEVELOPMENT) { - console.log(actionName, message, customAttributes); // eslint-disable-line + console.log(actionName, message, customAttributes); } if (window && typeof window.newrelic !== 'undefined') { // https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/addpageaction/ @@ -36,7 +36,7 @@ function sendPageAction(actionName, message, customAttributes) { function sendError(error, customAttributes) { if (getConfig().ENVIRONMENT === EnvironmentTypes.DEVELOPMENT) { - console.error(error, customAttributes); // eslint-disable-line + console.error(error, customAttributes); } if (window && typeof window.newrelic !== 'undefined') { // https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/noticeerror/ @@ -46,7 +46,7 @@ function sendError(error, customAttributes) { function setCustomAttribute(name, value) { if (getConfig().ENVIRONMENT === EnvironmentTypes.DEVELOPMENT) { - console.log(name, value); // eslint-disable-line + console.log(name, value); } if (window && typeof window.newrelic !== 'undefined') { // https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/setcustomattribute/ diff --git a/runtime/logging/index.js b/runtime/logging/index.ts similarity index 100% rename from runtime/logging/index.js rename to runtime/logging/index.ts diff --git a/runtime/plugins/Plugin.messages.jsx b/runtime/plugins/Plugin.messages.tsx similarity index 100% rename from runtime/plugins/Plugin.messages.jsx rename to runtime/plugins/Plugin.messages.tsx diff --git a/runtime/plugins/Plugin.test.jsx b/runtime/plugins/Plugin.test.tsx similarity index 67% rename from runtime/plugins/Plugin.test.jsx rename to runtime/plugins/Plugin.test.tsx index 147467b2..dbae875a 100644 --- a/runtime/plugins/Plugin.test.jsx +++ b/runtime/plugins/Plugin.test.tsx @@ -1,6 +1,3 @@ -/* eslint-disable react/jsx-no-bind */ -/* eslint react/prop-types: off */ - import { fireEvent } from '@testing-library/dom'; import '@testing-library/jest-dom'; import { render } from '@testing-library/react'; @@ -11,6 +8,7 @@ import { } from '../i18n'; import { initializeMockApp } from '../testing'; +import { FunctionComponent } from 'react'; import { PluginTypes } from '../../types'; import { PLUGIN_MOUNTED, PLUGIN_READY, PLUGIN_RESIZE @@ -30,7 +28,7 @@ const iframeConfig = { const directConfig = { id: 'direct_plugin', type: PluginTypes.DIRECT, - RenderWidget: ({ id, content }) => (
{content.text}
), + RenderWidget: ({ id, content }: { id: string, content: Record }) => (
{content.text}
), priority: 2, content: { text: 'This is a direct plugin.' }, }; @@ -39,20 +37,10 @@ const directConfig = { global.ResizeObserver = jest.fn(function mockResizeObserver() { this.observe = jest.fn(); this.disconnect = jest.fn(); + return this; }); describe('PluginContainer', () => { - it('should return a blank page with a null plugin configuration', () => { - // the URL will be empty and an empty div tag will exist where the iFrame should be - // the iFrame will still take up the space assigned by the host MFE - const component = ( - - ); - - const { container } = render(component); - expect(container.firstChild).toBeNull(); - }); - it('should render a Plugin iFrame Container when given an iFrame config', async () => { const component = ( Loading} /> @@ -66,25 +54,34 @@ describe('PluginContainer', () => { expect(iframeElement).toBeInTheDocument(); expect(fallbackElement).toBeInTheDocument(); - expect(fallbackElement.innerHTML).toEqual('Loading'); + expect(fallbackElement?.innerHTML).toEqual('Loading'); // Ensure the iframe has the proper attributes - expect(iframeElement.attributes.getNamedItem('allow').value).toEqual(IFRAME_FEATURE_POLICY); - expect(iframeElement.attributes.getNamedItem('src').value).toEqual(iframeConfig.url); - expect(iframeElement.attributes.getNamedItem('title').value).toEqual(iframeConfig.title); + expect(iframeElement?.attributes.getNamedItem('allow')?.value).toEqual(IFRAME_FEATURE_POLICY); + expect(iframeElement?.attributes.getNamedItem('src')?.value).toEqual(iframeConfig.url); + expect(iframeElement?.attributes.getNamedItem('title')?.value).toEqual(iframeConfig.title); // The component isn't ready, since the class has 'd-none' - expect(iframeElement.attributes.getNamedItem('class').value).toEqual('border border-0 w-100 d-none'); + expect(iframeElement?.attributes.getNamedItem('class')?.value).toEqual('border border-0 w-100 d-none'); + + if (iframeElement === null) { + fail('iframeElement was null.'); + } + if (iframeElement?.contentWindow === null) { + fail('contentWindow was null.'); + } jest.spyOn(iframeElement.contentWindow, 'postMessage'); expect(iframeElement.contentWindow.postMessage).not.toHaveBeenCalled(); // Dispatch a 'mounted' event manually. - const mountedEvent = new Event('message'); - mountedEvent.data = { - type: PLUGIN_MOUNTED, - }; - mountedEvent.source = iframeElement.contentWindow; + const mountedEvent = new MessageEvent('message', { + data: { + type: PLUGIN_MOUNTED, + }, + source: iframeElement?.contentWindow + }); + fireEvent(window, mountedEvent); expect(iframeElement.contentWindow.postMessage).toHaveBeenCalledWith( @@ -99,14 +96,14 @@ describe('PluginContainer', () => { ); // Dispatch a 'ready' event manually. - const readyEvent = new Event('message'); - readyEvent.data = { - type: PLUGIN_READY, - }; - readyEvent.source = iframeElement.contentWindow; + const readyEvent = new MessageEvent('message', { + data: { type: PLUGIN_READY }, + source: iframeElement.contentWindow, + }); + fireEvent(window, readyEvent); - expect(iframeElement.attributes.getNamedItem('class').value).toEqual('border border-0 w-100'); + expect(iframeElement.attributes.getNamedItem('class')?.value).toEqual('border border-0 w-100'); }); it('should render a Plugin Direct Container when given a Direct config', async () => { @@ -123,25 +120,19 @@ describe('PluginContainer', () => { describe('Plugin', () => { let logError = jest.fn(); - const error = ( - - ); + const error = 'There was an error'; beforeEach(async () => { // This is a gross hack to suppress error logs in the invalid parentSelector test jest.spyOn(console, 'error'); - global.console.error.mockImplementation(() => {}); + (global.console.error as jest.Mock).mockImplementation(() => {}); const { loggingService } = initializeMockApp(); logError = loggingService.logError; }); afterEach(() => { - global.console.error.mockRestore(); + (global.console.error as jest.Mock).mockRestore(); jest.clearAllMocks(); }); @@ -173,20 +164,23 @@ describe('Plugin', () => { ); const PluginPageWrapper = ({ - params, FallbackComponent, ChildComponent, - }) => ( - - - - - - ); + fallbackComponent, childComponent, + }: { fallbackComponent?: FunctionComponent, childComponent: FunctionComponent }) => { + const ChildComponent = childComponent; + return ( + + + + + + ); + }; it('should render children if no error', () => { const component = ( ); const { container } = render(component); @@ -196,9 +190,8 @@ describe('Plugin', () => { it('should throw an error if the child component fails', () => { const component = ( ); @@ -217,7 +210,7 @@ describe('Plugin', () => { it('should render the default fallback component when one is not passed into the Plugin', () => { const component = ( ); diff --git a/runtime/plugins/Plugin.jsx b/runtime/plugins/Plugin.tsx similarity index 51% rename from runtime/plugins/Plugin.jsx rename to runtime/plugins/Plugin.tsx index 84372994..ff6136f3 100644 --- a/runtime/plugins/Plugin.jsx +++ b/runtime/plugins/Plugin.tsx @@ -1,15 +1,17 @@ -'use client'; - -import PropTypes from 'prop-types'; import { + FunctionComponent, + ReactNode, useEffect, useMemo, useState, } from 'react'; + import { useIntl } from '../i18n'; import { ErrorBoundary } from '../react'; - import { PLUGIN_RESIZE } from './data/constants'; import { - dispatchMountedEvent, dispatchReadyEvent, dispatchUnmountedEvent, useHostEvent, + dispatchMountedEvent, + dispatchReadyEvent, + dispatchUnmountedEvent, + useHostEvent, } from './data/hooks'; import messages from './Plugin.messages'; @@ -24,12 +26,20 @@ const ErrorFallbackDefault = () => { ); }; -const Plugin = ({ - children, className, style, ready, ErrorFallbackComponent, -}) => { +interface PluginProps { + children: ReactNode, + className?: string, + style?: Record, + ready?: boolean, + errorFallbackComponent?: FunctionComponent, +} + +export default function Plugin({ + children, className, style = {}, ready = true, errorFallbackComponent, +}: PluginProps) { const [dimensions, setDimensions] = useState({ - width: null, - height: null, + width: 0, + height: 0, }); const finalStyle = useMemo(() => ({ @@ -39,7 +49,7 @@ const Plugin = ({ // Need to confirm: When an error is caught here, the logging will be sent to the child MFE's logging service - const ErrorFallback = ErrorFallbackComponent || ErrorFallbackDefault; + const ErrorFallback = errorFallbackComponent ?? ErrorFallbackDefault; useHostEvent(PLUGIN_RESIZE, ({ payload }) => { setDimensions({ @@ -57,8 +67,8 @@ const Plugin = ({ }, []); useEffect(() => { - /** Ready defaults to true, but can be used to defer rendering the Plugin until certain processes have - * occurred or conditions have been met */ + // Ready defaults to true, but can be used to defer rendering the Plugin until certain processes + // have occurred or conditions have been met if (ready) { dispatchReadyEvent(); } @@ -66,33 +76,9 @@ const Plugin = ({ return (
- } - > + }> {children}
); }; - -export default Plugin; - -Plugin.propTypes = { - /** The content for the Plugin */ - children: PropTypes.node.isRequired, - /** Classes to apply to the Plugin wrapper component */ - className: PropTypes.string, - /** Custom error fallback component */ - ErrorFallbackComponent: PropTypes.func, - /** If ready is true, it will render the Plugin */ - ready: PropTypes.bool, - /** Styles to apply to the Plugin wrapper component */ - style: PropTypes.shape({}), -}; - -Plugin.defaultProps = { - className: undefined, - ErrorFallbackComponent: null, - style: {}, - ready: true, -}; diff --git a/runtime/plugins/PluginContainer.jsx b/runtime/plugins/PluginContainer.jsx deleted file mode 100644 index 7c244133..00000000 --- a/runtime/plugins/PluginContainer.jsx +++ /dev/null @@ -1,55 +0,0 @@ -'use client'; - -import PropTypes from 'prop-types'; - -import PluginContainerDirect from './PluginContainerDirect'; -import PluginContainerIframe from './PluginContainerIframe'; - -import { PluginTypes } from '../../types'; -import { pluginConfigShape, slotOptionsShape } from './data/shapes'; - -function PluginContainer({ config, slotOptions, ...props }) { - if (!config) { - return null; - } - - // this will allow for future plugin types to be inserted in the PluginErrorBoundary - let renderer = null; - switch (config.type) { - case PluginTypes.IFRAME: - renderer = ( - - ); - break; - case PluginTypes.DIRECT: - renderer = ( - - ); - break; - default: - break; - } - - return renderer; -} - -export default PluginContainer; - -PluginContainer.propTypes = { - /** Configuration for the Plugin in this container — i.e pluginSlot[id].example_plugin */ - config: PropTypes.shape(pluginConfigShape), - /** Options passed to the PluginSlot */ - slotOptions: PropTypes.shape(slotOptionsShape), -}; - -PluginContainer.defaultProps = { - config: null, - slotOptions: {}, -}; diff --git a/runtime/plugins/PluginContainer.tsx b/runtime/plugins/PluginContainer.tsx new file mode 100644 index 00000000..bf5352b8 --- /dev/null +++ b/runtime/plugins/PluginContainer.tsx @@ -0,0 +1,39 @@ +import PluginContainerDirect from './PluginContainerDirect'; +import PluginContainerIframe from './PluginContainerIframe'; + +import { ReactNode } from 'react'; +import { isPluginContainerDirectConfig, isPluginContainerIframeConfig } from './data/utils'; +import { PluginContainerConfig } from '../../types'; + +interface PluginContainerProps { + config: PluginContainerConfig, + loadingFallback: NonNullable | null, + slotOptions?: { + mergeProps: boolean, + }, +} + +export default function PluginContainer({ config, slotOptions = { mergeProps: false }, loadingFallback, ...props }: PluginContainerProps) { + if (isPluginContainerDirectConfig(config)) { + return ( + + ); + } + + if (isPluginContainerIframeConfig(config)) { + return ( + + ); + } + + return null; +} diff --git a/runtime/plugins/PluginContainerDirect.jsx b/runtime/plugins/PluginContainerDirect.jsx deleted file mode 100644 index 23127407..00000000 --- a/runtime/plugins/PluginContainerDirect.jsx +++ /dev/null @@ -1,40 +0,0 @@ -import React, { Suspense } from 'react'; -import PropTypes from 'prop-types'; - -import { directPluginConfigShape, slotOptionsShape } from './data/shapes'; -import { mergeRenderWidgetPropsWithPluginContent } from './data/utils'; - -function PluginContainerDirect({ - config, slotOptions, loadingFallback, ...props -}) { - const { RenderWidget, id } = config; - - // When applicable, merge base RenderWidget props with custom plugin content, if any. - const propsForRenderWidget = mergeRenderWidgetPropsWithPluginContent({ - pluginSlotOptions: slotOptions, - pluginConfig: config, - renderWidgetProps: props, - }); - - return ( - - - - ); -} - -PluginContainerDirect.propTypes = { - /** Configuration for the Plugin in this container (i.e. pluginSlot[id].example_plugin) */ - config: PropTypes.shape(directPluginConfigShape).isRequired, - /** Custom fallback component used when component is not ready (i.e. "loading") */ - loadingFallback: PropTypes.node, - /** Options passed to the PluginSlot */ - slotOptions: PropTypes.shape(slotOptionsShape), -}; - -PluginContainerDirect.defaultProps = { - loadingFallback: null, - slotOptions: {}, -}; - -export default PluginContainerDirect; diff --git a/runtime/plugins/PluginContainerDirect.tsx b/runtime/plugins/PluginContainerDirect.tsx new file mode 100644 index 00000000..51f63253 --- /dev/null +++ b/runtime/plugins/PluginContainerDirect.tsx @@ -0,0 +1,31 @@ +import { ReactNode, Suspense } from 'react'; + +import { PluginContainerDirectConfig } from '../../types'; +import { mergeRenderWidgetPropsWithPluginContent } from './data/utils'; + +interface PluginContainerDirectProps { + config: PluginContainerDirectConfig, + loadingFallback: NonNullable | null, + slotOptions: { + mergeProps: boolean, + }, +} + +export default function PluginContainerDirect({ + config, slotOptions, loadingFallback, ...props +}: PluginContainerDirectProps) { + const { RenderWidget, id } = config; + + // When applicable, merge base RenderWidget props with custom plugin content, if any. + const propsForRenderWidget = mergeRenderWidgetPropsWithPluginContent({ + pluginSlotOptions: slotOptions, + pluginConfig: config, + renderWidgetProps: props, + }); + + return ( + + + + ); +} diff --git a/runtime/plugins/PluginContainerIframe.jsx b/runtime/plugins/PluginContainerIframe.tsx similarity index 68% rename from runtime/plugins/PluginContainerIframe.jsx rename to runtime/plugins/PluginContainerIframe.tsx index 22aa0795..3db17c0e 100644 --- a/runtime/plugins/PluginContainerIframe.jsx +++ b/runtime/plugins/PluginContainerIframe.tsx @@ -1,10 +1,10 @@ -import React, { +import classNames from 'classnames'; +import { + ReactNode, useEffect, useState, } from 'react'; -import PropTypes from 'prop-types'; -// eslint-disable-next-line import/no-extraneous-dependencies -import classNames from 'classnames'; +import { PluginTypes } from '../../types'; import { PLUGIN_MOUNTED, PLUGIN_READY, @@ -15,7 +15,6 @@ import { useElementSize, usePluginEvent, } from './data/hooks'; -import { iframePluginConfigShape } from './data/shapes'; /** * Feature policy for iframe, allowing access to certain courseware-related media. @@ -31,18 +30,30 @@ export const IFRAME_FEATURE_POLICY = ( 'fullscreen; microphone *; camera *; midi *; geolocation *; encrypted-media *' ); -function PluginContainerIframe({ +interface PluginContainerIframeProps { + config: { + id: string, + type: PluginTypes, + priority: number, + url: string, + title: string, + }, + loadingFallback: NonNullable | null, + className?: string, +} + +export default function PluginContainerIframe({ config, loadingFallback, className, ...props -}) { +}: PluginContainerIframeProps) { const { url, title } = config; const [mounted, setMounted] = useState(false); const [ready, setReady] = useState(false); - const [iframeRef, iframeElement, width, height] = useElementSize(); + const { ref: iframeRef, element: iframeElement, width, height } = useElementSize(); useEffect(() => { if (mounted) { - dispatchPluginEvent(iframeElement, { + dispatchPluginEvent(iframeElement as HTMLIFrameElement, { type: PLUGIN_RESIZE, payload: { width, @@ -79,19 +90,3 @@ function PluginContainerIframe({ ); } - -export default PluginContainerIframe; - -PluginContainerIframe.propTypes = { - /** Configuration for the Plugin in this container (i.e. pluginSlot[id].example_plugin) */ - config: PropTypes.shape(iframePluginConfigShape).isRequired, - /** Custom fallback component used when component is not ready (i.e. "loading") */ - loadingFallback: PropTypes.node, - /** Classes to apply to the iframe */ - className: PropTypes.string, -}; - -PluginContainerIframe.defaultProps = { - loadingFallback: null, - className: undefined, -}; diff --git a/runtime/plugins/PluginSlot.test.jsx b/runtime/plugins/PluginSlot.test.tsx similarity index 80% rename from runtime/plugins/PluginSlot.test.jsx rename to runtime/plugins/PluginSlot.test.tsx index 0c5ffb02..05917461 100644 --- a/runtime/plugins/PluginSlot.test.jsx +++ b/runtime/plugins/PluginSlot.test.tsx @@ -4,15 +4,16 @@ import '@testing-library/jest-dom'; import { fireEvent, render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import classNames from 'classnames'; +import { ReactElement, ReactNode } from 'react'; -import { PluginOperations, PluginTypes } from '../../types'; +import { PluginOperationTypes, PluginTypes } from '../../types'; import { IntlProvider } from '../i18n'; -import { logError } from '../logging'; import PluginSlot from './PluginSlot'; +import { PLUGIN_READY } from './data/constants'; import { usePluginSlot } from './data/hooks'; const iframePluginConfig = { - op: PluginOperations.INSERT, + op: PluginOperationTypes.INSERT, widget: { id: 'iframe_config', url: 'http://localhost/plugin1', @@ -47,6 +48,7 @@ jest.mock('../logging', () => ({ global.ResizeObserver = jest.fn(function mockResizeObserver() { this.observe = jest.fn(); this.disconnect = jest.fn(); + return this; }); // Mock callback functions @@ -55,7 +57,7 @@ const defaultContentsOnClick = jest.fn(); const mockOnClick = jest.fn(); const content = { text: 'This is a widget.' }; -function DefaultContents({ className, onClick, ...rest }) { +function DefaultContents({ className, onClick, ...rest }: { className?: string, onClick?: (event) => void }) { const handleOnClick = (e) => { defaultContentsOnClick(e); onClick?.(e); @@ -76,7 +78,7 @@ function DefaultContents({ className, onClick, ...rest }) { ); } -function PluginSlotWrapper({ slotOptions, children }) { +function PluginSlotWrapper({ slotOptions, children }: { slotOptions: { mergeProps: boolean }, children: ReactNode }) { return ( = { className: 'other-classname', style: { background: 'gray' }, }; @@ -107,7 +110,7 @@ function TestPluginSlot({ } if (hasChildren && hasChildrenElement && hasMultipleChildren) { return ( - + @@ -115,41 +118,45 @@ function TestPluginSlot({ } if (hasChildren) { return ( - + {hasChildrenElement ? : content.text} ); } - return ; + return ( + + <> + + ); } const defaultSlotOptions = { mergeProps: true, }; -function TestPluginSlotWithSlotOptions({ slotOptions: slotOptionsOverride, ...rest }) { - const slotOptions = { +function TestPluginSlotWithSlotOptions({ slotOptions = {}, ...rest }) { + const finalSlotOptions = { ...defaultSlotOptions, - ...slotOptionsOverride, + ...slotOptions, }; - return ; + return ; } describe('PluginSlot', () => { beforeEach(() => { - usePluginSlot.mockReturnValue(defaultSlotConfig); + (usePluginSlot as jest.Mock).mockReturnValue(defaultSlotConfig); console.error = jest.fn(); }); afterEach(() => { jest.clearAllMocks(); - console.error.mockRestore(); + (console.error as jest.Mock).mockRestore(); }); it('should render multiple types of Plugin in a single slot config', () => { - const { container, getByTestId } = render(); + const { container, getByTestId } = render(); const iframeElement = container.querySelector('iframe'); const defaultContent = getByTestId('default_contents'); const pluginSlot = getByTestId('test-slot-id'); @@ -159,28 +166,38 @@ describe('PluginSlot', () => { }); it('should order each Plugin by priority', () => { - const { container, getByTestId } = render(); + const { container, getByTestId } = render(); const iframeElement = container.querySelector('iframe'); const defaultContent = getByTestId('default_contents'); const pluginSlot = getByTestId('test-slot-id'); + if (iframeElement === null) { + fail('iframeElement was null.'); + } + if (iframeElement?.contentWindow === null) { + fail('contentWindow was null.'); + } + // Dispatch a 'ready' event manually. - const readyEvent = new Event('message'); - readyEvent.data = { - type: 'PLUGIN_READY', - }; - readyEvent.source = iframeElement.contentWindow; + const readyEvent = new MessageEvent('message', { + data: { + type: PLUGIN_READY, + }, + source: iframeElement.contentWindow, + }); + fireEvent(window, readyEvent); expect(pluginSlot.children[0]).toEqual(iframeElement); expect(pluginSlot.children[1]).toEqual(defaultContent); + expect(pluginSlot.children.length).toBe(2); // This ensures that the spinner isn't showing too. }); it('should wrap a Plugin when using the "wrap" operation', () => { - usePluginSlot.mockReturnValueOnce({ + (usePluginSlot as jest.Mock).mockReturnValueOnce({ plugins: [ { - op: PluginOperations.WRAP, + op: PluginOperationTypes.WRAP, widgetId: 'default_contents', wrapper: ({ component }) => (
@@ -192,49 +209,31 @@ describe('PluginSlot', () => { keepDefault: true, }); - const { getByTestId } = render(); + const { getByTestId } = render(); const customWrapper = getByTestId('custom-wrapper'); const defaultContent = getByTestId('default_contents'); expect(customWrapper).toContainElement(defaultContent); }); it('should not render a widget if the Hide operation is applied to it', () => { - usePluginSlot.mockReturnValueOnce({ + (usePluginSlot as jest.Mock).mockReturnValueOnce({ plugins: [ iframePluginConfig, { - op: PluginOperations.HIDE, + op: PluginOperationTypes.HIDE, widgetId: 'iframe_config', }, ], keepDefault: true, }); - const { container } = render(); + const { container } = render(); const iframeElement = container.querySelector('iframe'); expect(iframeElement).toBeNull(); }); - it('should throw an error for invalid config type', () => { - usePluginSlot.mockReturnValueOnce({ - plugins: [ - { - op: PluginOperations.INSERT, - widget: { - id: 'invalid_config', - type: 'INVALID_TYPE', - }, - }, - ], - keepDefault: true, - }); - render(); - - expect(logError).toHaveBeenCalledWith('the insert operation config is invalid for widget id: invalid_config'); - }); - it('should handle multiple children', () => { - const { queryAllByTestId } = render(); + const { queryAllByTestId } = render(); const defaultContentsWidgets = queryAllByTestId('default_contents'); expect(defaultContentsWidgets).toHaveLength(2); defaultContentsWidgets.forEach((widget) => { @@ -243,15 +242,15 @@ describe('PluginSlot', () => { }); it('should handle empty children', () => { - const { getByTestId } = render(); + const { getByTestId } = render(); expect(getByTestId('test-slot-id')).toBeInTheDocument(); }); it('should handle keepDefault=false', () => { - usePluginSlot.mockReturnValueOnce({ + (usePluginSlot as jest.Mock).mockReturnValueOnce({ plugins: [ { - op: PluginOperations.INSERT, + op: PluginOperationTypes.INSERT, widget: { id: 'inserted_direct_plugin', type: PluginTypes.DIRECT, @@ -262,7 +261,7 @@ describe('PluginSlot', () => { ], keepDefault: false, }); - const { container, queryByTestId, getByTestId } = render(); + const { container, queryByTestId, getByTestId } = render(); const defaultContent = queryByTestId('default_contents'); expect(container).not.toContainElement(defaultContent); @@ -389,11 +388,17 @@ describe('PluginSlot', () => { hasMockOnClick, pluginContent, includedAttributes, + }: { + MockPluginSlot: ReactElement, + hasPluginSlotChildElement: boolean, + hasMockOnClick: boolean, + pluginContent?: Record | null, + includedAttributes: string[], }) => { - usePluginSlot.mockReturnValueOnce({ + (usePluginSlot as jest.Mock).mockReturnValueOnce({ plugins: [ { - op: PluginOperations.MODIFY, + op: PluginOperationTypes.MODIFY, widgetId: 'default_contents', fn: (widget) => ({ ...widget, @@ -414,7 +419,7 @@ describe('PluginSlot', () => { expect(defaultContents).toHaveClass('other-classname'); expect(defaultContents).toHaveStyle({ background: 'gray' }); - await userEvent.click(defaultContents); + await userEvent.click(defaultContents as Element); const expectedEventObject = expect.objectContaining({ type: 'click', target: expect.any(Element) }); expect(defaultContentsOnClick).toHaveBeenCalledTimes(1); expect(defaultContentsOnClick).toHaveBeenCalledWith(expectedEventObject); @@ -423,7 +428,9 @@ describe('PluginSlot', () => { expect(mockOnClick).toHaveBeenCalledWith(expectedEventObject); } - if (!pluginContent) { return; } + if (!pluginContent) { + return; + } Object.entries(pluginContent).forEach(([key, value]) => { const expectedValue = !value ? '' : value; diff --git a/runtime/plugins/PluginSlot.tsx b/runtime/plugins/PluginSlot.tsx index db1e589b..17626d76 100644 --- a/runtime/plugins/PluginSlot.tsx +++ b/runtime/plugins/PluginSlot.tsx @@ -2,12 +2,17 @@ import { Spinner } from '@openedx/paragon'; import classNames from 'classnames'; import React, { ElementType, ReactNode } from 'react'; +import { DefaultContentsPluginContainerConfig, PluginTypes } from '../../types'; import { useIntl } from '../i18n'; - import messages from './Plugin.messages'; import PluginContainer from './PluginContainer'; import { usePluginSlot } from './data/hooks'; -import { mergeRenderWidgetPropsWithPluginContent, organizePlugins, wrapComponent } from './data/utils'; +import { + isDefaultPluginContainerConfig, + mergeRenderWidgetPropsWithPluginContent, + organizePlugins, + wrapComponent +} from './data/utils'; interface PluginSlotProps { /** Element type for the PluginSlot wrapper component */ @@ -17,13 +22,11 @@ interface PluginSlotProps { /** ID of the PluginSlot configuration */ id: string, /** Props that are passed down to each Plugin in the Slot */ - pluginProps?: { - [prop: string]: any, - }, + pluginProps?: Record, slotOptions?: { - mergeProps?: boolean, + mergeProps: boolean, }, - ref?: React.ForwardedRef + ref?: React.ForwardedRef, } export default function PluginSlot({ @@ -31,18 +34,20 @@ export default function PluginSlot({ children, id, pluginProps = {}, - slotOptions = {}, + slotOptions = { + mergeProps: false, + }, ref, ...props }: PluginSlotProps) { - /** the plugins below are obtained by the id passed into PluginSlot by the Host MFE. See example/src/PluginsPage.jsx - for an example of how PluginSlot is populated, and example/src/index.jsx for a dummy JS config that holds all plugins - */ + // The plugins below are obtained by the id passed into PluginSlot by the Host MFE. + // See test-project's PluginPage component for an example of how PluginSlot is populated, and + // test-project's site config for a complete plugin configuration. const { keepDefault, plugins } = usePluginSlot(id); const { formatMessage } = useIntl(); - const defaultContents = React.useMemo(() => { + const defaultContents: DefaultContentsPluginContainerConfig[] = React.useMemo(() => { if (!keepDefault) { return []; } @@ -50,6 +55,7 @@ export default function PluginSlot({ id: 'default_contents', priority: 50, RenderWidget: children, + type: PluginTypes.DIRECT, }]); }, [children, keepDefault]); @@ -67,7 +73,7 @@ export default function PluginSlot({ ? loadingFallback : defaultLoadingFallback; - const finalChildren: Array = []; + const finalChildren: ReactNode[] = []; if (finalPlugins.length > 0) { finalPlugins.forEach((pluginConfig) => { // If hidden, don't push to finalChildren @@ -75,7 +81,7 @@ export default function PluginSlot({ let container; // If default content, render children (merging any custom defined props from // pluginConfig.content with any existing props on `RenderWidget`). - if (pluginConfig.id === 'default_contents') { + if (isDefaultPluginContainerConfig(pluginConfig)) { const propsForRenderWidget = (pluginConfig.RenderWidget && React.isValidElement(pluginConfig.RenderWidget)) ? pluginConfig.RenderWidget.props : {}; diff --git a/runtime/plugins/data/constants.js b/runtime/plugins/data/constants.js deleted file mode 100644 index cffb6864..00000000 --- a/runtime/plugins/data/constants.js +++ /dev/null @@ -1,33 +0,0 @@ -// Plugin lifecycle events -export const PLUGIN_MOUNTED = 'PLUGIN_MOUNTED'; -export const PLUGIN_READY = 'PLUGIN_READY'; -export const PLUGIN_UNMOUNTED = 'PLUGIN_UNMOUNTED'; -export const PLUGIN_RESIZE = 'PLUGIN_RESIZE'; - -export const requiredPluginTypes = { - insert: { - base: { - id: 'string', - priority: 'number', - type: 'string', - }, - direct_plugin: { - RenderWidget: 'function', - }, - iframe_plugin: { - title: 'string', - url: 'string', - }, - }, - hide: { - widgetId: 'string', - }, - modify: { - widgetId: 'string', - fn: 'function', - }, - wrap: { - widgetId: 'string', - wrapper: 'function', - }, -}; diff --git a/runtime/plugins/data/constants.ts b/runtime/plugins/data/constants.ts new file mode 100644 index 00000000..4b40c887 --- /dev/null +++ b/runtime/plugins/data/constants.ts @@ -0,0 +1,5 @@ +// Plugin lifecycle events +export const PLUGIN_MOUNTED = 'PLUGIN_MOUNTED'; +export const PLUGIN_READY = 'PLUGIN_READY'; +export const PLUGIN_UNMOUNTED = 'PLUGIN_UNMOUNTED'; +export const PLUGIN_RESIZE = 'PLUGIN_RESIZE'; diff --git a/runtime/plugins/data/hooks.test.jsx b/runtime/plugins/data/hooks.test.tsx similarity index 84% rename from runtime/plugins/data/hooks.test.jsx rename to runtime/plugins/data/hooks.test.tsx index ed1190c0..98cea7e8 100644 --- a/runtime/plugins/data/hooks.test.jsx +++ b/runtime/plugins/data/hooks.test.tsx @@ -2,12 +2,12 @@ import '@testing-library/jest-dom'; import { getConfig } from '../../config'; -import { PluginOperations, PluginTypes } from '../../../types'; +import { PluginOperationTypes, PluginTypes } from '../../../types'; import { usePluginSlot } from './hooks'; const mockSlotChanges = [ { - op: PluginOperations.INSERT, + op: PluginOperationTypes.INSERT, widget: { id: 'login', priority: 50, @@ -26,7 +26,7 @@ describe('usePluginSlots', () => { }); describe('when the plugin slot is defined', () => { it('returns keepDefault and plugin changes', () => { - getConfig.mockImplementation(() => ( + (getConfig as jest.Mock).mockImplementation(() => ( { pluginSlots: { example_plugin_slot: { @@ -45,7 +45,7 @@ describe('usePluginSlots', () => { describe('when the plugin slot is not defined', () => { it('returns true for keepDefault and no plugin changes', () => { - getConfig.mockImplementation(() => {}); + (getConfig as jest.Mock).mockImplementation(() => {}); const slotConfig = usePluginSlot('example_plugin_slot'); diff --git a/runtime/plugins/data/hooks.js b/runtime/plugins/data/hooks.ts similarity index 67% rename from runtime/plugins/data/hooks.js rename to runtime/plugins/data/hooks.ts index df115874..a2db7660 100644 --- a/runtime/plugins/data/hooks.js +++ b/runtime/plugins/data/hooks.ts @@ -3,18 +3,25 @@ */ import { - useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, + LegacyRef, + useCallback, + useEffect, + useLayoutEffect, + useMemo, + useRef, + useState } from 'react'; -import { getConfigSlots } from './utils'; +import { MessageEventCallback } from '../../../types'; import { PLUGIN_MOUNTED, PLUGIN_READY, PLUGIN_UNMOUNTED } from './constants'; +import { getConfigSlots } from './utils'; /** * Called by PluginSlot to extract a list of plugins from the JS configuration * - * @param {String} id - Name of PluginSlot - * @returns {Object} - JS configuration for the PluginSlot + * @param id - Name of PluginSlot + * @returns {PluginSlotConfig} - JS configuration for the PluginSlot */ -export function usePluginSlot(id) { +export function usePluginSlot(id: string) { const configSlots = getConfigSlots()?.[id]; if (configSlots) { return configSlots; @@ -28,16 +35,12 @@ export function usePluginSlot(id) { * Dynamically add an event listener to the provided source window. * The source window can be the global parent (ie. the "window" object in the browser) * or it can be the content window of an individual element (ie. iFrame plugin container) - * - * @param {Object} srcWindow - Window object that the event originates from - * @param {String} type - Event name (eg. PLUGIN_RESIZE) - * @param {Function} callback - Called when the event is triggered */ -export function useMessageEvent(srcWindow, type, callback) { +export function useMessageEvent(srcWindow: Window | null, type: string, callback: MessageEventCallback) { // useLayoutEffect is called before the browser repaints the screen useLayoutEffect(() => { // Create a listener callback function - const listener = (event) => { + const listener = (event: MessageEvent<{ type: string, payload: any }>) => { // Filter messages to those from our source window. // NOTE: the "srcWindow" is determined by the below useHostEvent and usePluginEvent functions if (event.source === srcWindow) { @@ -60,22 +63,19 @@ export function useMessageEvent(srcWindow, type, callback) { /** * Called by the Plugin component to use events that were listened to (ie. PLUGIN_RESIZE) - * - * @param {String} type - Event name (eg. PLUGIN_RESIZE) - * @param {Function} callback - Called when the event is triggered */ -export function useHostEvent(type, callback) { +export function useHostEvent(type: string, callback: MessageEventCallback) { useMessageEvent(global.parent, type, callback); } /** * Used to listen for events from a wrapped Plugin element (eg. PluginContainerIframe) * - * @param {Object} element - Plugin element (eg.