diff --git a/.eslintrc b/.eslintrc index 23175c317..296ab9c7d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -15,6 +15,7 @@ "react" ], "settings": { + "import/external-module-folders": ["public"], "jsdoc": { "preferredTypes": { "delete": "delete", @@ -37,6 +38,11 @@ "plugin:jest/recommended", "plugin:jsdoc/recommended" ], + "globals": { + "mockHook": "readonly", + "mountHookComponent": "readonly", + "mockWindowLocation": "readonly" + }, "rules": { "arrow-parens": [ "error", @@ -81,6 +87,14 @@ "jsdoc/require-param-description": 0, "jsdoc/require-property-description": 0, "jsdoc/require-returns-description": 0, + "jsdoc/tag-lines": [ + "warn", + "always", + { + "count": 0, + "noEndLines": true + } + ], "max-len": [ "error", { diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e9437ac2c..4a0030711 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -71,13 +71,13 @@ Curiosity makes use of the branches `master`, `stage`, `qa`, and `ci`. - `stage` branch is a protected representation of production environments - Adding commits, or a PR, into `stage` should generate a `prod-beta` branch within the deploy repository [curiosity-frontend-build](https://github.com/RedHatInsights/curiosity-frontend-build) - The `prod-beta` branch is manually deployed through coordination with the operations team. -- `qa` branch is a representation of `qa-stable`, and `ci-stable`. +- `qa` branch is a representation of `ci-stable`, `qa-stable` and `stage-stable`. - Adding commits, or a PR, into `ci-stable` should generate `ci-*` and `qa-*` branches within the deploy repository [curiosity-frontend-build](https://github.com/RedHatInsights/curiosity-frontend-build) - - The `ci-*` and `qa-*` branches are automatically deployed within an averaged time for both `https://ci.*.redhat.com` and `https://qa.*.redhat.com` + - The `ci-*` and `qa-*` branches are automatically deployed within an averaged time for `https://ci.*.redhat.com`, `https://qa.*.redhat.com` and `https://*.stage.redhat.com` - In the future, once the API is fully deployed to QA, this will be a representation of `qa-beta` and `qa-stable` -- `ci` branch is a representation of `ci-beta`, and `qa-beta`. +- `ci` branch is a representation of `ci-beta`, `qa-beta` and `stage-beta`. - Adding commits, or a PR, into `ci-beta` should generate `ci-*` and `qa-*` branches within the deploy repository [curiosity-frontend-build](https://github.com/RedHatInsights/curiosity-frontend-build) - - The `ci-*` and `qa-*` branches are automatically deployed within an averaged time for both `https://ci.*.redhat.com` and `https://qa.*.redhat.com` + - The `ci-*` and `qa-*` branches are automatically deployed within an averaged time for `https://ci.*.redhat.com`, `https://qa.*.redhat.com` and `https://*.stage.redhat.com` - In the future, once the API is fully deployed to QA, this will be a representation of `ci-beta` and `ci-stable` #### Branching and Pull Request Workflow diff --git a/package.json b/package.json index 4a534837b..00b048f6d 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "!src/index.js", "!src/setupTests.js", "!src/components/app.js", + "!src/components/**/index.js", "!src/common/index.js", "!src/redux/index.js", "!src/redux/store.js", @@ -113,31 +114,30 @@ "test:local": "react-scripts test --env=jsdom --roots=./src" }, "dependencies": { - "@patternfly/patternfly": "4.102.2", - "@patternfly/react-charts": "6.14.17", - "@patternfly/react-core": "4.115.2", - "@patternfly/react-icons": "4.10.2", - "@patternfly/react-styles": "4.10.2", - "@patternfly/react-table": "4.26.7", - "@patternfly/react-tokens": "4.11.3", - "@redhat-cloud-services/frontend-components": "3.1.11", - "@redhat-cloud-services/frontend-components-notifications": "3.1.0", - "@redhat-cloud-services/frontend-components-utilities": "3.1.2", + "@patternfly/patternfly": "4.108.2", + "@patternfly/react-charts": "6.14.29", + "@patternfly/react-core": "4.128.2", + "@patternfly/react-icons": "4.10.11", + "@patternfly/react-styles": "4.10.11", + "@patternfly/react-table": "4.27.24", + "@patternfly/react-tokens": "4.11.12", + "@redhat-cloud-services/frontend-components": "3.2.5", + "@redhat-cloud-services/frontend-components-notifications": "3.2.2", + "@redhat-cloud-services/frontend-components-utilities": "3.2.2", "axios": "^0.21.1", "classnames": "^2.3.1", - "i18next": "^20.2.2", + "i18next": "^20.3.1", "i18next-xhr-backend": "^3.2.2", "js-cookie": "^2.2.1", "locale-code": "^2.0.2", "lodash": "^4.17.21", "lru-cache": "^6.0.0", "moment": "^2.29.1", - "node-sass": "^4.14.1", "numbro": "^2.3.2", "prop-types": "^15.7.2", "react": "^17.0.2", "react-dom": "^17.0.2", - "react-i18next": "^11.8.15", + "react-i18next": "^11.10.0", "react-redux": "^7.2.4", "react-router": "^5.2.0", "react-router-dom": "^5.2.0", @@ -148,23 +148,24 @@ "redux-promise-middleware": "^6.1.2", "redux-thunk": "^2.3.0", "reselect": "^4.0.0", - "victory-create-container": "^35.5.1" + "sass": "^1.34.1", + "victory-create-container": "^35.8.5" }, "devDependencies": { "@wojtekmaj/enzyme-adapter-react-17": "^0.6.1", - "apidoc-mock": "^3.0.4", - "cspell": "^5.4.0", + "apidoc-mock": "^4.0.0", + "cspell": "^5.6.1", "enzyme": "^3.11.0", "enzyme-to-json": "^3.6.2", "eslint-config-airbnb": "^18.2.1", "eslint-config-prettier": "^8.3.0", - "eslint-plugin-import": "^2.22.1", + "eslint-plugin-import": "^2.23.4", "eslint-plugin-jest": "^24.3.6", - "eslint-plugin-jsdoc": "^33.3.0", + "eslint-plugin-jsdoc": "^35.1.3", "eslint-plugin-json": "^3.0.0", "eslint-plugin-jsx-a11y": "^6.4.1", "eslint-plugin-prettier": "^3.4.0", - "eslint-plugin-react": "^7.23.2", + "eslint-plugin-react": "^7.24.0", "eslint-plugin-react-hooks": "^4.2.0", "express": "^4.17.1", "glob": "^7.1.7", diff --git a/src/components/app.js b/src/components/app.js index b6e1af3cd..5d076c148 100644 --- a/src/components/app.js +++ b/src/components/app.js @@ -4,7 +4,7 @@ import { NotificationsPortal } from '@redhat-cloud-services/frontend-components- import { connectRouter, reduxActions } from '../redux'; import { helpers } from '../common/helpers'; import { I18n } from './i18n/i18n'; -import { Router } from './router/router'; +import { Router } from './router'; import Authentication from './authentication/authentication'; /** diff --git a/src/components/authentication/__tests__/__snapshots__/authentication.test.js.snap b/src/components/authentication/__tests__/__snapshots__/authentication.test.js.snap index 18f0ea5b3..16b408c3e 100644 --- a/src/components/authentication/__tests__/__snapshots__/authentication.test.js.snap +++ b/src/components/authentication/__tests__/__snapshots__/authentication.test.js.snap @@ -286,7 +286,126 @@ exports[`Authentication Component should return a message on 401 error: 401 erro `; -exports[`Authentication Component should return a redirect on 418 error: 418 error 1`] = `"418 redirect"`; +exports[`Authentication Component should return a redirect on 418 error: 418 error 1`] = ` + +`; exports[`Authentication Component should return a redirect on a specific 403 error and error code: 403 error 1`] = ` `; -exports[`Authentication Component should return a redirect on a specific 403 error and error code: 403 redirect error 1`] = `"403 redirect"`; +exports[`Authentication Component should return a redirect on a specific 403 error and error code: 403 redirect error 1`] = ` + +`; diff --git a/src/components/authentication/__tests__/authentication.test.js b/src/components/authentication/__tests__/authentication.test.js index 3e01ef313..eae540244 100644 --- a/src/components/authentication/__tests__/authentication.test.js +++ b/src/components/authentication/__tests__/authentication.test.js @@ -64,7 +64,7 @@ describe('Authentication Component', () => { ); - expect(component.html()).toMatchSnapshot('418 error'); + expect(component).toMatchSnapshot('418 error'); }); it('should return a redirect on a specific 403 error and error code', () => { @@ -88,7 +88,7 @@ describe('Authentication Component', () => { ); - expect(component.html()).toMatchSnapshot('403 redirect error'); + expect(component).toMatchSnapshot('403 redirect error'); component.setProps({ session: { diff --git a/src/components/authentication/authentication.js b/src/components/authentication/authentication.js index 1609ae647..3205f4c3d 100644 --- a/src/components/authentication/authentication.js +++ b/src/components/authentication/authentication.js @@ -6,7 +6,7 @@ import { NotAuthorized } from '@redhat-cloud-services/frontend-components/NotAut import { connectRouter, reduxActions, reduxSelectors } from '../../redux'; import { rhsmApiTypes } from '../../types'; import { helpers } from '../../common'; -import { Redirect, routerHelpers, routerConfig } from '../router/router'; +import { routerHelpers, Redirect } from '../router'; import MessageView from '../messageView/messageView'; import { translate } from '../i18n/i18n'; @@ -16,7 +16,7 @@ import { translate } from '../i18n/i18n'; * @augments React.Component */ class Authentication extends Component { - appName = routerConfig.appName; + appName = routerHelpers.appName; removeListeners = helpers.noop; @@ -42,7 +42,7 @@ class Authentication extends Component { hideGlobalFilter(); const appNav = onNavigation(event => { - const { routeHref } = routerHelpers.getNavRouteDetail({ id: event.navId }); + const { routeHref } = routerHelpers.getRouteConfig({ id: event.navId }); history.push(routeHref); }); @@ -85,10 +85,7 @@ class Authentication extends Component { (session.errorCodes && session.errorCodes.includes(rhsmApiTypes.RHSM_API_RESPONSE_ERROR_DATA_CODE_TYPES.OPTIN)) || session.status === 418 ) { - if (helpers.TEST_MODE) { - return {session.status} redirect; - } - return ; + return ; } return ( @@ -119,7 +116,7 @@ Authentication.propTypes = { setAppName: PropTypes.func, session: PropTypes.shape({ authorized: PropTypes.shape({ - [routerConfig.appName]: PropTypes.bool + [routerHelpers.appName]: PropTypes.bool }), errorCodes: PropTypes.arrayOf(PropTypes.string), pending: PropTypes.bool, diff --git a/src/components/form/__tests__/__snapshots__/select.test.js.snap b/src/components/form/__tests__/__snapshots__/select.test.js.snap index 500ebe088..ff0ab3dca 100644 --- a/src/components/form/__tests__/__snapshots__/select.test.js.snap +++ b/src/components/form/__tests__/__snapshots__/select.test.js.snap @@ -111,6 +111,7 @@ exports[`Select Component should allow alternate direction and position options: isCreatable={false} isDisabled={false} isGrouped={false} + isInputValuePersisted={false} isOpen={false} isPlain={false} maxHeight={null} @@ -145,6 +146,8 @@ exports[`Select Component should allow alternate direction and position options: isChecked={false} isDisabled={false} isFavorite={null} + isLoad={false} + isLoading={false} isNoResultsOption={false} isPlaceholder={false} isSelected={false} @@ -165,6 +168,8 @@ exports[`Select Component should allow alternate direction and position options: isChecked={false} isDisabled={false} isFavorite={null} + isLoad={false} + isLoading={false} isNoResultsOption={false} isPlaceholder={false} isSelected={false} @@ -198,6 +203,7 @@ exports[`Select Component should allow alternate direction and position options: isCreatable={false} isDisabled={false} isGrouped={false} + isInputValuePersisted={false} isOpen={false} isPlain={false} maxHeight={null} @@ -232,6 +238,8 @@ exports[`Select Component should allow alternate direction and position options: isChecked={false} isDisabled={false} isFavorite={null} + isLoad={false} + isLoading={false} isNoResultsOption={false} isPlaceholder={false} isSelected={false} @@ -252,6 +260,8 @@ exports[`Select Component should allow alternate direction and position options: isChecked={false} isDisabled={false} isFavorite={null} + isLoad={false} + isLoading={false} isNoResultsOption={false} isPlaceholder={false} isSelected={false} @@ -285,6 +295,7 @@ exports[`Select Component should allow being disabled with missing options: no o isCreatable={false} isDisabled={true} isGrouped={false} + isInputValuePersisted={false} isOpen={false} isPlain={false} maxHeight={null} @@ -331,6 +342,7 @@ exports[`Select Component should allow being disabled with missing options: opti isCreatable={false} isDisabled={true} isGrouped={false} + isInputValuePersisted={false} isOpen={false} isPlain={false} maxHeight={null} @@ -365,6 +377,8 @@ exports[`Select Component should allow being disabled with missing options: opti isChecked={false} isDisabled={false} isFavorite={null} + isLoad={false} + isLoading={false} isNoResultsOption={false} isPlaceholder={false} isSelected={false} @@ -385,6 +399,8 @@ exports[`Select Component should allow being disabled with missing options: opti isChecked={false} isDisabled={false} isFavorite={null} + isLoad={false} + isLoading={false} isNoResultsOption={false} isPlaceholder={false} isSelected={false} @@ -405,6 +421,8 @@ exports[`Select Component should allow being disabled with missing options: opti isChecked={false} isDisabled={false} isFavorite={null} + isLoad={false} + isLoading={false} isNoResultsOption={false} isPlaceholder={false} isSelected={false} @@ -425,6 +443,8 @@ exports[`Select Component should allow being disabled with missing options: opti isChecked={false} isDisabled={false} isFavorite={null} + isLoad={false} + isLoading={false} isNoResultsOption={false} isPlaceholder={false} isSelected={false} @@ -458,6 +478,7 @@ exports[`Select Component should allow being disabled with missing options: opti isCreatable={false} isDisabled={true} isGrouped={false} + isInputValuePersisted={false} isOpen={false} isPlain={false} maxHeight={null} @@ -483,6 +504,28 @@ exports[`Select Component should allow being disabled with missing options: opti /> `; +exports[`Select Component should allow data- props: data- attributes 1`] = ` +Object { + "ariaLabel": "Select option", + "className": "", + "data-dolor-sit": "dolor sit", + "data-lorem": "ipsum", + "direction": "down", + "id": "generatedid-", + "isDisabled": false, + "isToggleText": true, + "maxHeight": null, + "name": null, + "onSelect": [Function], + "options": Array [], + "placeholder": "Select option", + "position": "left", + "selectedOptions": null, + "toggleIcon": null, + "variant": "single", +} +`; + exports[`Select Component should allow plain objects as values, and be able to select options based on values within the object: select when option values are objects 1`] = ` `; -exports[`Select Component should render a expanded select: expanded 1`] = ` +exports[`Select Component should render an expanded select: expanded 1`] = ` { component.instance().onSelect({}, 'world'); }); - it('should render a expanded select', () => { + it('should render an expanded select', () => { const props = { id: 'test', options: ['lorem', 'ipsum', 'hello', 'world'] @@ -163,4 +163,14 @@ describe('Select Component', () => { expect(component).toMatchSnapshot('options, but disabled'); }); + + it('should allow data- props', () => { + const props = { + 'data-lorem': 'ipsum', + 'data-dolor-sit': 'dolor sit' + }; + + const component = mount(); + expect(component.props()).toMatchSnapshot('data- attributes'); + }); }); diff --git a/src/components/form/select.js b/src/components/form/select.js index b7a48d2a1..8ee309743 100644 --- a/src/components/form/select.js +++ b/src/components/form/select.js @@ -37,6 +37,8 @@ const SelectPosition = DropdownPosition; class Select extends React.Component { state = { isExpanded: false, options: null, selected: null }; + selectField = React.createRef(); + componentDidMount() { const { options } = this.state; @@ -135,13 +137,16 @@ class Select extends React.Component { }); }; + // FixMe: attributes filtered on PF select component. allow data- attributes /** * Format options into a consumable array of objects format. */ formatOptions() { + const { current: domElement = {} } = this.selectField; const { options, selectedOptions, variant } = this.props; + const dataAttributes = Object.entries(this.props).filter(([key]) => /^data-/i.test(key)); const updatedOptions = _isPlainObject(options) - ? Object.keys(options).map(key => ({ ...options[key], title: key, value: options[key] })) + ? Object.entries(options).map(([key, value]) => ({ ...value, title: key, value })) : _cloneDeep(options); const activateOptions = @@ -197,6 +202,10 @@ class Select extends React.Component { updateSelected = updatedOptions.filter(opt => opt.selected === true).map(opt => opt.title); } + if (domElement?.parentRef?.current) { + dataAttributes.forEach(([key, value]) => domElement?.parentRef?.current.setAttribute(key, value)); + } + this.setState({ options: updatedOptions, selected: updateSelected @@ -257,6 +266,7 @@ class Select extends React.Component { isOpen={isExpanded} toggleIcon={toggleIcon} placeholderText={placeholder} + ref={this.selectField} {...pfSelectOptions} > {(options && diff --git a/src/components/graphCard/__tests__/graphCard.test.js b/src/components/graphCard/__tests__/graphCard.test.js index 59df35a8c..e134881ab 100644 --- a/src/components/graphCard/__tests__/graphCard.test.js +++ b/src/components/graphCard/__tests__/graphCard.test.js @@ -179,4 +179,20 @@ describe('GraphCard Component', () => { expect(component).toMatchSnapshot('disabled component'); }); + + it('should allow a custom display for card actions', () => { + const actionDisplay = jest.fn(); + const props = { + query: { + [RHSM_API_QUERY_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY, + [RHSM_API_QUERY_TYPES.END_DATE]: '2021-02-24T23:59:59.999Z', + [RHSM_API_QUERY_TYPES.START_DATE]: '2021-01-25T00:00:00.000Z' + }, + productId: 'lorem', + settings: { actionDisplay } + }; + + shallow(); + expect(actionDisplay).toHaveBeenCalledTimes(1); + }); }); diff --git a/src/components/graphCard/graphCard.js b/src/components/graphCard/graphCard.js index 3871a4334..ed2a21511 100644 --- a/src/components/graphCard/graphCard.js +++ b/src/components/graphCard/graphCard.js @@ -142,7 +142,7 @@ class GraphCard extends React.Component { * @returns {Node} */ render() { - const { cardTitle, children, error, graphData, isDisabled, pending, settings } = this.props; + const { cardTitle, children, error, graphData, meta, isDisabled, pending, settings } = this.props; if (isDisabled) { return null; @@ -152,7 +152,7 @@ class GraphCard extends React.Component { // Apply actionDisplay callback, return node if (typeof settings?.actionDisplay === 'function') { - actionDisplay = settings.actionDisplay({ ...graphData }); + actionDisplay = settings.actionDisplay({ data: { ...graphData }, meta: { ...meta } }); } return ( @@ -188,7 +188,8 @@ class GraphCard extends React.Component { * * @type {{productLabel: string, settings: object, productId: string, query: object, pending: boolean, * error: boolean, cardTitle: Node, filterGraphData: Array, getGraphReportsCapacity: Function, - * viewId: string, t: Function, children: Node, graphData: object, isDisabled: boolean}} + * viewId: string, t: Function, children: Node, graphData: object, isDisabled: boolean, + * meta: object}} */ GraphCard.propTypes = { cardTitle: PropTypes.node, @@ -203,6 +204,7 @@ GraphCard.propTypes = { ), getGraphReportsCapacity: PropTypes.func, graphData: PropTypes.object, + meta: PropTypes.object, query: PropTypes.shape({ [RHSM_API_QUERY_TYPES.GRANULARITY]: PropTypes.oneOf([...Object.values(GRANULARITY_TYPES)]).isRequired, [RHSM_API_QUERY_TYPES.START_DATE]: PropTypes.string.isRequired, @@ -222,9 +224,9 @@ GraphCard.propTypes = { /** * Default props. * - * @type {{getGraphReportsCapacity: Function, productLabel: string, settings: object, viewId: string, - * t: translate, children: Node, pending: boolean, graphData: object, isDisabled: boolean, - * error: boolean, cardTitle: Node, filterGraphData: Array}} + * @type {{productLabel: string, settings: object, pending: boolean, error: boolean, cardTitle: Node, + * filterGraphData: Array, getGraphReportsCapacity: Function, viewId: string, t: translate, + * children: Node, graphData: object, isDisabled: boolean, meta: object}} */ GraphCard.defaultProps = { cardTitle: null, @@ -233,6 +235,7 @@ GraphCard.defaultProps = { filterGraphData: [], getGraphReportsCapacity: helpers.noop, graphData: {}, + meta: {}, isDisabled: helpers.UI_DISABLED_GRAPH, pending: false, productLabel: '', diff --git a/src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap b/src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap index a0c396b3a..4ecf5b3b4 100644 --- a/src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap +++ b/src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap @@ -5,6 +5,7 @@ exports[`I18n Component should attempt to perform a component translate: transla exports[`I18n Component should attempt to perform a string replace: translate 1`] = ` Object { "localeKey": "t(lorem.ipsum)", + "multiContext": "t(lorem.ipsum, {\\"context\\":\\"hello_world\\"})", "placeholder": "t(lorem.ipsum, hello world)", } `; @@ -266,11 +267,11 @@ Array [ }, Object { "key": "curiosity-view.title", - "match": "t('curiosity-view.title', { appName: helpers.UI_DISPLAY_NAME, context: product.pathParameter })", + "match": "t('curiosity-view.title', { appName: helpers.UI_DISPLAY_NAME, context: (Array.isArray(product.pathParameter)", }, Object { "key": "curiosity-view.description", - "match": "t('curiosity-view.description', { appName: helpers.UI_DISPLAY_NAME, context: product.productParameter })", + "match": "t('curiosity-view.description', { appName: helpers.UI_DISPLAY_NAME, context: (Array.isArray(product.productParameter)", }, ], }, @@ -315,7 +316,7 @@ Array [ }, Object { "key": "curiosity-graph.card-action-total", - "match": "translate('curiosity-graph.card-action-total', { context: 'coreHours', total: numbro(total)", + "match": "translate('curiosity-graph.card-action-total', { context: 'coreHours', total: numbro(totalCoreHours)", }, Object { "key": "curiosity-inventory.label", @@ -328,7 +329,7 @@ Array [ "keys": Array [ Object { "key": "curiosity-graph.card-action-total", - "match": "translate('curiosity-graph.card-action-total', { context: 'coreHours', total: numbro(total)", + "match": "translate('curiosity-graph.card-action-total', { context: 'coreHours', total: numbro(totalCoreHours)", }, Object { "key": "curiosity-inventory.label", diff --git a/src/components/i18n/__tests__/i18n.test.js b/src/components/i18n/__tests__/i18n.test.js index f5d5cd01f..38117c097 100644 --- a/src/components/i18n/__tests__/i18n.test.js +++ b/src/components/i18n/__tests__/i18n.test.js @@ -1,12 +1,11 @@ import { readFileSync } from 'fs'; import glob from 'glob'; import React from 'react'; -import { act } from 'react-dom/test-utils'; import PropTypes from 'prop-types'; -import { mount, shallow } from 'enzyme'; +import { shallow } from 'enzyme'; import _get from 'lodash/get'; -import { I18n, translate, translateComponent } from '../i18n'; import enLocales from '../../../../public/locales/en-US'; +import { I18n, translate, translateComponent } from '../i18n'; /** * Get translation keys. @@ -53,38 +52,25 @@ const getTranslationKeys = ({ files = './src/**/!(*.test|*.spec).@(js|jsx)', lis describe('I18n Component', () => { const getKeys = getTranslationKeys({}); - const loadHookComponent = async callback => { - let component = null; - await act(async () => { - component = callback(); - }); - component?.update(); - return component; - }; - it('should render a basic component', async () => { const props = { locale: 'es' }; - const component = await loadHookComponent(() => - mount( - - lorem ipsum - - ) + const component = await mountHookComponent( + + lorem ipsum + ); expect(component).toMatchSnapshot('basic'); }); it('should pass children', async () => { - const component = await loadHookComponent(() => - mount( - - lorem ipsum - - ) + const component = await mountHookComponent( + + lorem ipsum + ); expect(component.html()).toMatchSnapshot('children'); @@ -121,10 +107,12 @@ describe('I18n Component', () => { it('should attempt to perform a string replace', () => { const localeKey = translate('lorem.ipsum'); const placeholder = translate('lorem.ipsum', 'hello world'); + const multiContext = translate('lorem.ipsum', { context: ['hello', 'world'] }); expect({ localeKey, - placeholder + placeholder, + multiContext }).toMatchSnapshot('translate'); }); diff --git a/src/components/i18n/i18n.js b/src/components/i18n/i18n.js index a4b7d81ba..9b967f9d5 100644 --- a/src/components/i18n/i18n.js +++ b/src/components/i18n/i18n.js @@ -16,19 +16,25 @@ import { helpers } from '../../common/helpers'; * @returns {string|Node} */ const translate = (translateKey, values = null, components) => { + const updatedValues = values; + + if (Array.isArray(updatedValues?.context)) { + updatedValues.context = updatedValues.context.join('_'); + } + if (helpers.TEST_MODE) { - return helpers.noopTranslate(translateKey, values, components); + return helpers.noopTranslate(translateKey, updatedValues, components); } if (components) { return ( - (i18next.store && ) || ( + (i18next.store && ) || ( t({translateKey}) ) ); } - return (i18next.store && i18next.t(translateKey, values)) || `t(${translateKey})`; + return (i18next.store && i18next.t(translateKey, updatedValues)) || `t(${translateKey})`; }; /** diff --git a/src/components/productView/__tests__/__snapshots__/productViewMissing.test.js.snap b/src/components/productView/__tests__/__snapshots__/productViewMissing.test.js.snap index faada656b..515ed00ef 100644 --- a/src/components/productView/__tests__/__snapshots__/productViewMissing.test.js.snap +++ b/src/components/productView/__tests__/__snapshots__/productViewMissing.test.js.snap @@ -1,5 +1,21 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`ProductViewMissing Component should redirect when there are limited product cards: redirect action 1`] = ` +Array [ + Array [ + Object { + "meta": Object { + "appName": undefined, + "id": "rhel", + "secondaryNav": undefined, + }, + "payload": Promise {}, + "type": "PLATFORM_SET_NAV", + }, + ], +] +`; + exports[`ProductViewMissing Component should render a non-connected component: non-connected 1`] = ` @@ -55,7 +71,7 @@ exports[`ProductViewMissing Component should render a non-connected component: n @@ -91,7 +107,7 @@ exports[`ProductViewMissing Component should render a non-connected component: n @@ -149,7 +165,7 @@ exports[`ProductViewMissing Component should render a predictable set of product > @@ -157,13 +173,13 @@ exports[`ProductViewMissing Component should render a predictable set of product headingLevel="h2" size="lg" > - t(curiosity-view.title, {"appName":"Subscriptions"}) + t(curiosity-view.title, {"appName":"Subscriptions","context":"OpenShift Container Platform"}) - t(curiosity-view.description, {"appName":"Subscriptions","context":"loremIpsum"}) + t(curiosity-view.description, {"appName":"Subscriptions","context":"OpenShift Container Platform"}) @@ -193,13 +209,13 @@ exports[`ProductViewMissing Component should render a predictable set of product headingLevel="h2" size="lg" > - t(curiosity-view.title, {"appName":"Subscriptions"}) + t(curiosity-view.title, {"appName":"Subscriptions","context":"OpenShift-dedicated-metrics"}) - t(curiosity-view.description, {"appName":"Subscriptions","context":"dolorSit"}) + t(curiosity-view.description, {"appName":"Subscriptions","context":"OpenShift-dedicated-metrics"}) { + const useDispatchMock = jest.spyOn(reactRedux, 'useDispatch'); + + afterEach(() => { + useDispatchMock.mockClear(); + }); + it('should render a non-connected component', () => { - const props = {}; + useDispatchMock.mockReturnValue(jest.fn()); + + const props = { + availableProductsRedirect: 1 + }; const component = shallow(); expect(component).toMatchSnapshot('non-connected'); }); it('should render a predictable set of product cards', () => { const props = { - basePath: '/loremIpsum/dolorSit/', - products: [ - { - id: 'test 001', - isSearchable: true, - path: '/loremIpsum', - productParameter: 'loremIpsum' - }, - { - id: 'test 002', - isSearchable: true, - path: '/dolorSit', - productParameter: 'dolorSit' - }, - { - id: 'test 003', - isSearchable: false, - path: '/test003', - productParameter: 'test003' - } - ] + availableProductsRedirect: 1 }; - const component = shallow(); - expect(component).toMatchSnapshot('non-connected'); + + mockWindowLocation( + () => { + const component = shallow(); + expect(component).toMatchSnapshot('non-connected'); + }, + { + url: 'https://ci.foo.redhat.com/openshift/subscriptions/' + } + ); + }); + + it('should redirect when there are limited product cards', async () => { + const mockDispatch = jest.fn(); + useDispatchMock.mockReturnValue(action => action(mockDispatch)); + + const props = {}; + + await mountHookComponent(); + expect(mockDispatch.mock.calls).toMatchSnapshot('redirect action'); }); }); diff --git a/src/components/productView/__tests__/productViewOpenShiftContainer.test.js b/src/components/productView/__tests__/productViewOpenShiftContainer.test.js index c5c069ce6..fa179669a 100644 --- a/src/components/productView/__tests__/productViewOpenShiftContainer.test.js +++ b/src/components/productView/__tests__/productViewOpenShiftContainer.test.js @@ -96,68 +96,88 @@ describe('ProductViewOpenShiftContainer Component', () => { expect({ productOneActionDisplay: undefined, productTwoActionDisplay: productTwo.initialGraphSettings.actionDisplay({ - coreHours: [ - { - y: 0 - }, - { - y: 400 - }, - { - y: 100 - } - ] + data: { + coreHours: [ + { + y: 0 + }, + { + y: 400 + }, + { + y: 100 + } + ] + }, + meta: { + totalCoreHours: 500 + } }) }).toMatchSnapshot('product action display should display a total value below 1000'); expect({ productOneActionDisplay: undefined, productTwoActionDisplay: productTwo.initialGraphSettings.actionDisplay({ - coreHours: [ - { - y: 0 - }, - { - y: 800000 - }, - { - y: 100000 - } - ] + data: { + coreHours: [ + { + y: 0 + }, + { + y: 800000 + }, + { + y: 100000 + } + ] + }, + meta: { + totalCoreHours: 900000 + } }) }).toMatchSnapshot('product action display should display a total value below 1000000'); expect({ productOneActionDisplay: undefined, productTwoActionDisplay: productTwo.initialGraphSettings.actionDisplay({ - coreHours: [ - { - y: 0 - }, - { - y: 1000 - }, - { - y: 100 - } - ] + data: { + coreHours: [ + { + y: 0 + }, + { + y: 1000 + }, + { + y: 100 + } + ] + }, + meta: { + totalCoreHours: 1100 + } }) }).toMatchSnapshot('product action display should display a total value'); expect({ productOneActionDisplay: undefined, productTwoActionDisplay: productTwo.initialGraphSettings.actionDisplay({ - loremIpsum: [ - { - y: 0 - }, - { - y: 1000 - }, - { - y: 100 - } - ] + data: { + loremIpsum: [ + { + y: 0 + }, + { + y: 1000 + }, + { + y: 100 + } + ] + }, + meta: { + totalCoreHours: undefined + } }) }).toMatchSnapshot('product action display should NOT display a total value'); }); diff --git a/src/components/productView/__tests__/productViewOpenShiftDedicated.test.js b/src/components/productView/__tests__/productViewOpenShiftDedicated.test.js index 70c312e02..58b3a7681 100644 --- a/src/components/productView/__tests__/productViewOpenShiftDedicated.test.js +++ b/src/components/productView/__tests__/productViewOpenShiftDedicated.test.js @@ -68,17 +68,22 @@ describe('ProductViewOpenShiftDedicated Component', () => { expect({ productActionDisplay: ProductViewOpenShiftDedicated.defaultProps.productConfig.initialGraphSettings.actionDisplay( { - coreHours: [ - { - y: 0 - }, - { - y: 400 - }, - { - y: 100 - } - ] + data: { + coreHours: [ + { + y: 0 + }, + { + y: 400 + }, + { + y: 100 + } + ] + }, + meta: { + totalCoreHours: 500 + } } ) }).toMatchSnapshot('product action display should display a total value below 1000'); @@ -86,17 +91,22 @@ describe('ProductViewOpenShiftDedicated Component', () => { expect({ productActionDisplay: ProductViewOpenShiftDedicated.defaultProps.productConfig.initialGraphSettings.actionDisplay( { - coreHours: [ - { - y: 0 - }, - { - y: 800000 - }, - { - y: 100000 - } - ] + data: { + coreHours: [ + { + y: 0 + }, + { + y: 800000 + }, + { + y: 100000 + } + ] + }, + meta: { + totalCoreHours: 900000 + } } ) }).toMatchSnapshot('product action display should display a total value below 1000000'); @@ -104,17 +114,22 @@ describe('ProductViewOpenShiftDedicated Component', () => { expect({ productActionDisplay: ProductViewOpenShiftDedicated.defaultProps.productConfig.initialGraphSettings.actionDisplay( { - coreHours: [ - { - y: 0 - }, - { - y: 1000 - }, - { - y: 100 - } - ] + data: { + coreHours: [ + { + y: 0 + }, + { + y: 1000 + }, + { + y: 100 + } + ] + }, + meta: { + totalCoreHours: 1100 + } } ) }).toMatchSnapshot('product action display should display a total value'); @@ -123,17 +138,22 @@ describe('ProductViewOpenShiftDedicated Component', () => { productOneActionDisplay: undefined, productTwoActionDisplay: ProductViewOpenShiftDedicated.defaultProps.productConfig.initialGraphSettings.actionDisplay( { - loremIpsum: [ - { - y: 0 - }, - { - y: 1000 - }, - { - y: 100 - } - ] + data: { + loremIpsum: [ + { + y: 0 + }, + { + y: 1000 + }, + { + y: 100 + } + ] + }, + meta: { + totalCoreHours: undefined + } } ) }).toMatchSnapshot('product action display should NOT display a total value'); diff --git a/src/components/productView/productViewMissing.js b/src/components/productView/productViewMissing.js index b016b38ac..986628a54 100644 --- a/src/components/productView/productViewMissing.js +++ b/src/components/productView/productViewMissing.js @@ -2,66 +2,50 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Button, Card, CardBody, CardFooter, CardTitle, Gallery, Title, PageSection } from '@patternfly/react-core'; import { ArrowRightIcon } from '@patternfly/react-icons'; -import { useHistory } from 'react-router-dom'; +import { useMount } from 'react-use'; import { PageLayout, PageHeader } from '../pageLayout/pageLayout'; -import { routerConfig, routerHelpers } from '../router/router'; +import { routerHelpers } from '../router'; import { helpers } from '../../common'; import { translate } from '../i18n/i18n'; +import { useHistory } from '../../hooks/useRouter'; + +/** + * Return a list of available products. + * + * @returns {Array} + */ +const filterAvailableProducts = () => { + const { configs, allConfigs } = routerHelpers.getRouteConfigByPath(); + return (configs.length && configs) || allConfigs.filter(({ isSearchable }) => isSearchable === true); +}; /** * Render a missing product view. * - * @fires onClick + * @fires onNavigate * @param {object} props - * @param {string} props.basePath - * @param {Array} props.products + * @param {number} props.availableProductsRedirect * @param {Function} props.t * @returns {Node} */ -const ProductViewMissing = ({ basePath, products, t }) => { +const ProductViewMissing = ({ availableProductsRedirect, t }) => { const history = useHistory(); + const availableProducts = filterAvailableProducts(); - /** - * Return a list of available products. - * - * @returns {Array} - */ - const filterAvailableProducts = () => { - const basePathDirs = basePath.split('/'); - const updatedProducts = {}; - - basePathDirs.forEach(dir => { - if (dir) { - products.forEach(({ id, productParameter, isSearchable, ...navItem }) => { - if (isSearchable && new RegExp(dir, 'i').test(productParameter)) { - updatedProducts[id] = { - id, - productParameter, - isSearchable, - ...navItem - }; - } - }); - } - }); - - const filteredProducts = Object.values(updatedProducts); - return ( - (filteredProducts.length && filteredProducts) || - routerConfig.navigation.filter( - ({ isSearchable, productParameter }) => (isSearchable && productParameter) || false - ) - ); - }; + useMount(() => { + if (availableProducts.length <= availableProductsRedirect) { + history.push(availableProducts[0].path); + } + }); /** * On click, update history. * - * @event onUpdateHistory - * @param {string} path + * @event onNavigate + * @param {string} id * @returns {void} */ - const onClick = path => history.push(path); + const onNavigate = id => history.push(id); return ( @@ -70,24 +54,30 @@ const ProductViewMissing = ({ basePath, products, t }) => { - {filterAvailableProducts().map(product => ( - onClick(product.path)}> + {availableProducts.map(product => ( + onNavigate(product.id)}> - {t('curiosity-view.title', { appName: helpers.UI_DISPLAY_NAME, context: product.pathParameter })} + {t('curiosity-view.title', { + appName: helpers.UI_DISPLAY_NAME, + context: + (Array.isArray(product.pathParameter) && product.pathParameter?.[0]) || product.pathParameter + })} {t('curiosity-view.description', { appName: helpers.UI_DISPLAY_NAME, - context: product.productParameter + context: + (Array.isArray(product.productParameter) && product.productParameter?.[0]) || + product.productParameter })} onClick(product.path)} + onClick={() => onNavigate(product.id)} icon={} iconPosition="right" > @@ -105,30 +95,20 @@ const ProductViewMissing = ({ basePath, products, t }) => { /** * Prop types. * - * @type {{t: Function}} + * @type {{availableProductsRedirect: number, t: Function}} */ ProductViewMissing.propTypes = { - basePath: PropTypes.string, - products: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - isSearchable: PropTypes.bool.isRequired, - path: PropTypes.string.isRequired, - pathParameter: PropTypes.string, - productParameter: PropTypes.string - }) - ), + availableProductsRedirect: PropTypes.number, t: PropTypes.func }; /** * Default props. * - * @type {{t: translate}} + * @type {{availableProductsRedirect: number, t: translate}} */ ProductViewMissing.defaultProps = { - basePath: routerHelpers.basePath, - products: routerConfig.navigation, + availableProductsRedirect: 3, t: translate }; diff --git a/src/components/productView/productViewOpenShiftContainer.js b/src/components/productView/productViewOpenShiftContainer.js index b0b4ef3ca..1d1974c65 100644 --- a/src/components/productView/productViewOpenShiftContainer.js +++ b/src/components/productView/productViewOpenShiftContainer.js @@ -441,19 +441,15 @@ ProductViewOpenShiftContainer.defaultProps = { ], initialGraphSettings: { actionDisplay: data => { - const { coreHours } = data; + const { + meta: { totalCoreHours } + } = data; let displayContent; - if (coreHours) { - let total = 0; - - coreHours.forEach(({ y }) => { - total += y ?? 0; - }); - + if (totalCoreHours) { displayContent = translate('curiosity-graph.card-action-total', { context: 'coreHours', - total: numbro(total) + total: numbro(totalCoreHours) .format({ average: true, mantissa: 2, trimMantissa: true, lowPrecision: false }) .toUpperCase() }); diff --git a/src/components/productView/productViewOpenShiftDedicated.js b/src/components/productView/productViewOpenShiftDedicated.js index 2c62831f6..e0dd982c5 100644 --- a/src/components/productView/productViewOpenShiftDedicated.js +++ b/src/components/productView/productViewOpenShiftDedicated.js @@ -85,19 +85,15 @@ ProductViewOpenShiftDedicated.defaultProps = { ], initialGraphSettings: { actionDisplay: data => { - const { coreHours } = data; + const { + meta: { totalCoreHours } + } = data; let displayContent; - if (coreHours) { - let total = 0; - - coreHours.forEach(({ y }) => { - total += y ?? 0; - }); - + if (totalCoreHours) { displayContent = translate('curiosity-graph.card-action-total', { context: 'coreHours', - total: numbro(total) + total: numbro(totalCoreHours) .format({ average: true, mantissa: 2, trimMantissa: true, lowPrecision: false }) .toUpperCase() }); diff --git a/src/components/router/__tests__/__snapshots__/redirect.test.js.snap b/src/components/router/__tests__/__snapshots__/redirect.test.js.snap index e4eea36d6..d2939ac41 100644 --- a/src/components/router/__tests__/__snapshots__/redirect.test.js.snap +++ b/src/components/router/__tests__/__snapshots__/redirect.test.js.snap @@ -1,86 +1,180 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Redirect Component should handle a redirect with a url: redirect url 1`] = ` +exports[`Redirect Component should handle a forced redirect: forced route 1`] = ` Redirected towards - //lorem/ipsum?dolor=sit + /dolor `; -exports[`Redirect Component should handle existing routes with and without withRouter: existing route: outside of withRouter 1`] = ` +exports[`Redirect Component should handle a forced redirect: forced route, replace 1`] = ` +Array [ + Array [ + "/dolor?dolor=sit", + ], +] +`; + +exports[`Redirect Component should handle a redirect with a url: redirect url 1`] = ` Redirected towards - /openshift-sw + //lorem/ipsum?dolor=sit `; -exports[`Redirect Component should handle existing routes with and without withRouter: existing route: routed redirect route 1`] = ` - - - +exports[`Redirect Component should handle existing routes: existing route 1`] = ` +Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewOpenShiftContainer", + "default": false, + "disabled": false, + "id": "openshift-container", + "isSearchable": true, + "path": "*", + "pathParameter": "OpenShift Container Platform", + "productParameter": "OpenShift Container Platform", + "redirect": null, + "routeHref": "/openshift-container", + "viewParameter": "viewOpenShift Container Platform", +} `; -exports[`Redirect Component should handle missing routes with and without withRouter: missing route: outside of withRouter 1`] = ` +exports[`Redirect Component should handle missing routes: missing route, component 1`] = ` Redirected towards /lorem-ipsum `; -exports[`Redirect Component should handle missing routes with and without withRouter: missing route: routed redirect route 1`] = ` +exports[`Redirect Component should render a basic component: basic 1`] = ` - - +/> `; - -exports[`Redirect Component should render a basic component: basic 1`] = `null`; - -exports[`Redirect Component should render a routed component: routed 1`] = `null`; diff --git a/src/components/router/__tests__/__snapshots__/router.test.js.snap b/src/components/router/__tests__/__snapshots__/router.test.js.snap index 1d5bb870f..840be1336 100644 --- a/src/components/router/__tests__/__snapshots__/router.test.js.snap +++ b/src/components/router/__tests__/__snapshots__/router.test.js.snap @@ -16,79 +16,26 @@ exports[`Router Component should handle unique route settings: settings 1`] = ` routes={ Array [ Object { - "component": [Function], + "component": "loremComponent", "disabled": false, "exact": false, + "path": "/lorem", "redirect": "/loremIpsum", - "render": false, - "title": "Lorem", - "to": "/lorem", }, Object { "activateOnError": true, - "component": [Function], + "component": "ipsumComponent", "disabled": false, "exact": false, - "render": false, - "title": "Ipsum", - "to": "/ipsum", + "path": "/ipsum", }, ] } > - - - - - + `; -exports[`Router Component should pass customized props to routed components: routeDetail and location parsedSearch props 1`] = ` -Object { - "locationParsedSearch": Object { - "dolor": "", - "ipsum": "1 2", - }, - "routeDetail": Object { - "baseName": "/", - "errorRoute": undefined, - "routeItem": Object { - "component": [Function], - "disabled": false, - "exact": false, - "redirect": "/loremIpsum", - "render": true, - "title": "Lorem", - "to": "/lorem", - }, - "routes": Array [ - Object { - "component": [Function], - "disabled": false, - "exact": false, - "redirect": "/loremIpsum", - "render": true, - "title": "Lorem", - "to": "/lorem", - }, - ], - }, -} -`; - exports[`Router Component should render a basic component: basic 1`] = ` - - - - - - - - - + `; diff --git a/src/components/router/__tests__/__snapshots__/routerConfig.test.js.snap b/src/components/router/__tests__/__snapshots__/routerConfig.test.js.snap deleted file mode 100644 index ec51c574c..000000000 --- a/src/components/router/__tests__/__snapshots__/routerConfig.test.js.snap +++ /dev/null @@ -1,226 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`RouterConfig should return specific properties: appName 1`] = `"subscriptions"`; - -exports[`RouterConfig should return specific properties: navigation 1`] = ` -Array [ - Object { - "id": "rhel", - "isSearchable": true, - "path": "/rhel", - "pathParameter": "RHEL", - "productParameter": "RHEL", - "viewParameter": "viewRHEL", - }, - Object { - "id": "rhel-arm", - "isSearchable": false, - "path": "/rhel-arm", - "pathParameter": "RHEL for ARM", - "productParameter": "RHEL", - "viewParameter": "viewRHEL", - }, - Object { - "id": "rhel-ibmpower", - "isSearchable": false, - "path": "/rhel-ibmpower", - "pathParameter": "RHEL for IBM Power", - "productParameter": "RHEL", - "viewParameter": "viewRHEL", - }, - Object { - "id": "rhel-ibmz", - "isSearchable": false, - "path": "/rhel-ibmz", - "pathParameter": "RHEL for IBM z", - "productParameter": "RHEL", - "viewParameter": "viewRHEL", - }, - Object { - "id": "rhel-x86", - "isSearchable": false, - "path": "/rhel-x86", - "pathParameter": "RHEL for x86", - "productParameter": "RHEL", - "viewParameter": "viewRHEL", - }, - Object { - "id": "openshift-container", - "isSearchable": true, - "path": "/openshift-container", - "pathParameter": "OpenShift Container Platform", - "productParameter": "OpenShift Container Platform", - "viewParameter": "viewOpenShift Container Platform", - }, - Object { - "id": "openshift-dedicated", - "isSearchable": true, - "path": "/openshift-dedicated", - "pathParameter": "OpenShift-dedicated-metrics", - "productParameter": "OpenShift-dedicated-metrics", - "viewParameter": "viewOpenShift-dedicated-metrics", - }, - Object { - "id": "satellite", - "isSearchable": false, - "path": "/satellite", - "pathParameter": "Satellite", - "productParameter": "Satellite", - "viewParameter": "viewSatellite", - }, - Object { - "id": "satellite-capsule", - "isSearchable": false, - "path": "/satellite-capsule", - "pathParameter": "Satellite Capsule", - "productParameter": "Satellite", - "viewParameter": "viewSatellite", - }, - Object { - "id": "satellite-server", - "isSearchable": false, - "path": "/satellite-server", - "pathParameter": "Satellite Server", - "productParameter": "Satellite", - "viewParameter": "viewSatellite", - }, - Object { - "id": "optin", - "isSearchable": false, - "path": "/optin", - "pathParameter": null, - "productParameter": null, - "viewParameter": null, - }, - Object { - "default": true, - "id": "missing", - "isSearchable": false, - "path": "/", - "pathParameter": null, - "productParameter": null, - "viewParameter": null, - }, -] -`; - -exports[`RouterConfig should return specific properties: platformLandingRedirect 1`] = `"/"`; - -exports[`RouterConfig should return specific properties: platformModalRedirect 1`] = `"/?not_entitled=subscriptions"`; - -exports[`RouterConfig should return specific properties: productGroups 1`] = ` -Object { - "viewOpenShift": Array [ - "OpenShift Container Platform", - ], - "viewOpenShift-dedicated-metrics": Array [ - "OpenShift-dedicated-metrics", - ], - "viewOpenShiftMetric": Array [ - "OpenShift-metrics", - ], - "viewRHEL": Array [ - "RHEL", - "RHEL for ARM", - "RHEL for IBM Power", - "RHEL for IBM z", - "RHEL for x86", - ], - "viewSatellite": Array [ - "Satellite", - "Satellite Capsule", - "Satellite Server", - ], -} -`; - -exports[`RouterConfig should return specific properties: routes 1`] = ` -Array [ - Object { - "component": Object { - "$$typeof": Symbol(react.lazy), - "_init": [Function], - "_payload": Object { - "_result": [Function], - "_status": -1, - }, - }, - "disabled": false, - "exact": true, - "render": true, - "to": "/:variant(rhel|rhel-arm|rhel-ibmpower|rhel-ibmz|rhel-x86)", - }, - Object { - "component": Object { - "$$typeof": Symbol(react.lazy), - "_init": [Function], - "_payload": Object { - "_result": [Function], - "_status": -1, - }, - }, - "disabled": false, - "exact": true, - "render": true, - "to": "/openshift-container", - }, - Object { - "component": Object { - "$$typeof": Symbol(react.lazy), - "_init": [Function], - "_payload": Object { - "_result": [Function], - "_status": -1, - }, - }, - "disabled": false, - "exact": true, - "render": true, - "to": "/openshift-dedicated", - }, - Object { - "component": Object { - "$$typeof": Symbol(react.lazy), - "_init": [Function], - "_payload": Object { - "_result": [Function], - "_status": -1, - }, - }, - "disabled": false, - "exact": true, - "render": true, - "to": "/:variant(satellite|satellite-capsule|satellite-server)", - }, - Object { - "activateOnError": true, - "component": Object { - "$$typeof": Symbol(react.lazy), - "_init": [Function], - "_payload": Object { - "_result": [Function], - "_status": -1, - }, - }, - "disabled": false, - "exact": true, - "render": true, - "to": "/optin", - }, - Object { - "component": Object { - "$$typeof": Symbol(react.lazy), - "_init": [Function], - "_payload": Object { - "_result": [Function], - "_status": -1, - }, - }, - "disabled": false, - "exact": true, - "redirect": "/", - "render": true, - "to": "/", - }, -] -`; diff --git a/src/components/router/__tests__/__snapshots__/routerHelpers.test.js.snap b/src/components/router/__tests__/__snapshots__/routerHelpers.test.js.snap index c18fb5760..41c3584c5 100644 --- a/src/components/router/__tests__/__snapshots__/routerHelpers.test.js.snap +++ b/src/components/router/__tests__/__snapshots__/routerHelpers.test.js.snap @@ -40,246 +40,993 @@ exports[`RouterHelpers should return a generated baseName using an insights path exports[`RouterHelpers should return a generated baseName using an insights path prefix: insights, beta app lorem route name 1`] = `"/beta/insights/appName"`; +exports[`RouterHelpers should return a generated basePath: insights, app base path 1`] = `"/insights/"`; + +exports[`RouterHelpers should return a generated basePath: insights, app lorem route name base path 1`] = `"/insights/"`; + +exports[`RouterHelpers should return a generated basePath: insights, beta app base path 1`] = `"/beta/insights/"`; + +exports[`RouterHelpers should return a generated basePath: insights, beta app lorem route name base path 1`] = `"/beta/insights/"`; + exports[`RouterHelpers should return an error route: error route 1`] = ` Object { "activateOnError": true, - "component": Object { - "$$typeof": Symbol(react.lazy), - "_init": [Function], - "_payload": Object { - "_result": [Function], - "_status": -1, - }, - }, + "component": "optinView/optinView", "disabled": false, "exact": true, - "render": true, - "to": "/optin", + "id": "optin", + "path": "/optin", + "redirect": null, } `; -exports[`RouterHelpers should return navigation and route details that align to location: detail: match specific path navigation 1`] = ` +exports[`RouterHelpers should return default navigation and route details: detail: defaults 1`] = ` Object { - "nav": Object { - "id": "rhel", - "isSearchable": true, - "path": "/rhel", - "pathParameter": "RHEL", - "productParameter": "RHEL", - "routeHref": "/rhel", - "viewParameter": "viewRHEL", - }, "navRoute": Object { - "component": Object { - "$$typeof": Symbol(react.lazy), - "_init": [Function], - "_payload": Object { - "_result": [Function], - "_status": -1, + "allConfigs": Array [ + Object { + "activateOnError": false, + "aliases": Array [ + "insights", + ], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel", + "isSearchable": true, + "path": "/rhel", + "pathParameter": Array [ + "RHEL", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-arm", + "isSearchable": false, + "path": "/rhel-arm", + "pathParameter": "RHEL for ARM", + "productParameter": "RHEL", + "redirect": null, + "routeHref": "/rhel-arm", + "viewParameter": "viewRHEL", + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-ibmpower", + "isSearchable": false, + "path": "/rhel-ibmpower", + "pathParameter": Array [ + "RHEL for IBM Power", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-ibmz", + "isSearchable": false, + "path": "/rhel-ibmz", + "pathParameter": Array [ + "RHEL for IBM z", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-x86", + "isSearchable": false, + "path": "/rhel-x86", + "pathParameter": Array [ + "RHEL for x86", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewOpenShiftContainer", + "default": false, + "disabled": false, + "id": "openshift-container", + "isSearchable": true, + "path": "/openshift-container", + "pathParameter": Array [ + "OpenShift Container Platform", + "OpenShift-metrics", + ], + "productParameter": Array [ + "OpenShift Container Platform", + "OpenShift-metrics", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewOpenShiftDedicated", + "default": false, + "disabled": false, + "id": "openshift-dedicated", + "isSearchable": true, + "path": "/openshift-dedicated", + "pathParameter": Array [ + "OpenShift-dedicated-metrics", + ], + "productParameter": Array [ + "OpenShift-dedicated-metrics", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewSatellite", + "default": false, + "disabled": false, + "id": "satellite", + "isSearchable": false, + "path": "/satellite", + "pathParameter": Array [ + "Satellite", + ], + "productParameter": Array [ + "Satellite", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewSatellite", + "default": false, + "disabled": false, + "id": "satellite-capsule", + "isSearchable": false, + "path": "/satellite-capsule", + "pathParameter": Array [ + "Satellite Capsule", + ], + "productParameter": Array [ + "Satellite", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewSatellite", + "default": false, + "disabled": false, + "id": "satellite-server", + "isSearchable": false, + "path": "/satellite-server", + "pathParameter": Array [ + "Satellite Server", + ], + "productParameter": Array [ + "Satellite", + ], + "redirect": null, + }, + Object { + "activateOnError": true, + "aliases": Array [], + "component": "optinView/optinView", + "default": false, + "disabled": false, + "id": "optin", + "isSearchable": false, + "path": "/optin", + "pathParameter": null, + "productParameter": null, + "redirect": null, + "routeHref": "/optin", + "viewParameter": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewMissing", + "default": true, + "disabled": false, + "id": "missing", + "isSearchable": false, + "path": "/", + "pathParameter": null, + "productParameter": null, + "redirect": "/", + "routeHref": "/", + "viewParameter": null, + }, + ], + "allConfigsById": Object { + "missing": Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewMissing", + "default": true, + "disabled": false, + "id": "missing", + "isSearchable": false, + "path": "/", + "pathParameter": null, + "productParameter": null, + "redirect": "/", + "routeHref": "/", + "viewParameter": null, + }, + "openshift-container": Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewOpenShiftContainer", + "default": false, + "disabled": false, + "id": "openshift-container", + "isSearchable": true, + "path": "/openshift-container", + "pathParameter": Array [ + "OpenShift Container Platform", + "OpenShift-metrics", + ], + "productParameter": Array [ + "OpenShift Container Platform", + "OpenShift-metrics", + ], + "redirect": null, + }, + "openshift-dedicated": Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewOpenShiftDedicated", + "default": false, + "disabled": false, + "id": "openshift-dedicated", + "isSearchable": true, + "path": "/openshift-dedicated", + "pathParameter": Array [ + "OpenShift-dedicated-metrics", + ], + "productParameter": Array [ + "OpenShift-dedicated-metrics", + ], + "redirect": null, + }, + "optin": Object { + "activateOnError": true, + "aliases": Array [], + "component": "optinView/optinView", + "default": false, + "disabled": false, + "id": "optin", + "isSearchable": false, + "path": "/optin", + "pathParameter": null, + "productParameter": null, + "redirect": null, + "routeHref": "/optin", + "viewParameter": null, + }, + "rhel": Object { + "activateOnError": false, + "aliases": Array [ + "insights", + ], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel", + "isSearchable": true, + "path": "/rhel", + "pathParameter": Array [ + "RHEL", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + "rhel-arm": Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-arm", + "isSearchable": false, + "path": "/rhel-arm", + "pathParameter": "RHEL for ARM", + "productParameter": "RHEL", + "redirect": null, + "routeHref": "/rhel-arm", + "viewParameter": "viewRHEL", + }, + "rhel-ibmpower": Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-ibmpower", + "isSearchable": false, + "path": "/rhel-ibmpower", + "pathParameter": Array [ + "RHEL for IBM Power", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + "rhel-ibmz": Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-ibmz", + "isSearchable": false, + "path": "/rhel-ibmz", + "pathParameter": Array [ + "RHEL for IBM z", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + "rhel-x86": Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-x86", + "isSearchable": false, + "path": "/rhel-x86", + "pathParameter": Array [ + "RHEL for x86", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + "satellite": Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewSatellite", + "default": false, + "disabled": false, + "id": "satellite", + "isSearchable": false, + "path": "/satellite", + "pathParameter": Array [ + "Satellite", + ], + "productParameter": Array [ + "Satellite", + ], + "redirect": null, + }, + "satellite-capsule": Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewSatellite", + "default": false, + "disabled": false, + "id": "satellite-capsule", + "isSearchable": false, + "path": "/satellite-capsule", + "pathParameter": Array [ + "Satellite Capsule", + ], + "productParameter": Array [ + "Satellite", + ], + "redirect": null, + }, + "satellite-server": Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewSatellite", + "default": false, + "disabled": false, + "id": "satellite-server", + "isSearchable": false, + "path": "/satellite-server", + "pathParameter": Array [ + "Satellite Server", + ], + "productParameter": Array [ + "Satellite", + ], + "redirect": null, }, }, + "configs": Array [], + "configsById": Object {}, + "firstMatch": undefined, + }, +} +`; + +exports[`RouterHelpers should return navigation and route details from a path: detail: match specific path 1`] = ` +Object { + "navRoute": Object { + "activateOnError": false, + "aliases": Array [ + "insights", + ], + "component": "productView/productViewRhel", + "default": false, "disabled": false, - "exact": true, "id": "rhel", "isSearchable": true, "path": "/rhel", - "pathParameter": "RHEL", + "pathParameter": Array [ + "RHEL", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, +} +`; + +exports[`RouterHelpers should return navigation and route details from a path: detail: missing parameters 1`] = ` +Object { + "navRoute": undefined, +} +`; + +exports[`RouterHelpers should return navigation and route details from a path: detail: missing pathName 1`] = ` +Object { + "navRoute": undefined, +} +`; + +exports[`RouterHelpers should return navigation and route details from a path: detail: specific product path 1`] = ` +Object { + "navRoute": Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-arm", + "isSearchable": false, + "path": "/rhel-arm", + "pathParameter": "RHEL for ARM", "productParameter": "RHEL", - "render": true, - "routeHref": "/rhel", - "to": "/:variant(rhel|rhel-arm|rhel-ibmpower|rhel-ibmz|rhel-x86)", + "redirect": null, + "routeHref": "/rhel-arm", "viewParameter": "viewRHEL", }, - "route": Object { - "component": Object { - "$$typeof": Symbol(react.lazy), - "_init": [Function], - "_payload": Object { - "_result": [Function], - "_status": -1, - }, - }, +} +`; + +exports[`RouterHelpers should return navigation and route details from a related name: detail: match related name 1`] = ` +Object { + "navRoute": Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, "disabled": false, - "exact": true, - "render": true, - "to": "/:variant(rhel|rhel-arm|rhel-ibmpower|rhel-ibmz|rhel-x86)", + "id": "rhel-arm", + "isSearchable": false, + "path": "/rhel-arm", + "pathParameter": "RHEL for ARM", + "productParameter": "RHEL", + "redirect": null, + "routeHref": "/rhel-arm", + "viewParameter": "viewRHEL", }, } `; -exports[`RouterHelpers should return navigation and route details that align to location: detail: missing ID, specific path 1`] = ` +exports[`RouterHelpers should return navigation and route details that align to location: detail: match specific path navigation 1`] = ` Object { - "nav": Object { + "navRoute": Object { + "activateOnError": false, + "aliases": Array [ + "insights", + ], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, "id": "rhel", "isSearchable": true, "path": "/rhel", "pathParameter": "RHEL", "productParameter": "RHEL", + "redirect": null, "routeHref": "/rhel", "viewParameter": "viewRHEL", }, +} +`; + +exports[`RouterHelpers should return navigation and route details that align to location: detail: missing ID, specific path 1`] = ` +Object { "navRoute": Object { - "component": Object { - "$$typeof": Symbol(react.lazy), - "_init": [Function], - "_payload": Object { - "_result": [Function], - "_status": -1, - }, - }, + "activateOnError": false, + "aliases": Array [ + "insights", + ], + "component": "productView/productViewRhel", + "default": false, "disabled": false, - "exact": true, "id": "rhel", "isSearchable": true, "path": "/rhel", "pathParameter": "RHEL", "productParameter": "RHEL", - "render": true, + "redirect": null, "routeHref": "/rhel", - "to": "/:variant(rhel|rhel-arm|rhel-ibmpower|rhel-ibmz|rhel-x86)", "viewParameter": "viewRHEL", }, - "route": Object { - "component": Object { - "$$typeof": Symbol(react.lazy), - "_init": [Function], - "_payload": Object { - "_result": [Function], - "_status": -1, - }, - }, - "disabled": false, - "exact": true, - "render": true, - "to": "/:variant(rhel|rhel-arm|rhel-ibmpower|rhel-ibmz|rhel-x86)", - }, } `; -exports[`RouterHelpers should return navigation and route details that align to location: detail: missing id and pathname and default 1`] = ` +exports[`RouterHelpers should return navigation and route details that align to location: detail: missing id and pathName and default 1`] = ` Object { - "nav": Object {}, "navRoute": Object {}, - "route": Object {}, } `; -exports[`RouterHelpers should return navigation and route details that align to location: detail: missing id and pathname, default 1`] = ` +exports[`RouterHelpers should return navigation and route details that align to location: detail: missing id and pathName, default 1`] = ` Object { - "nav": Object { - "default": true, - "id": "missing", - "isSearchable": false, - "path": "/", - "pathParameter": null, - "productParameter": null, - "routeHref": "/", - "viewParameter": null, - }, "navRoute": Object { - "component": Object { - "$$typeof": Symbol(react.lazy), - "_init": [Function], - "_payload": Object { - "_result": [Function], - "_status": -1, - }, - }, + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewMissing", "default": true, "disabled": false, - "exact": true, "id": "missing", "isSearchable": false, "path": "/", "pathParameter": null, "productParameter": null, "redirect": "/", - "render": true, "routeHref": "/", - "to": "/", "viewParameter": null, }, - "route": Object {}, } `; exports[`RouterHelpers should return navigation and route details that align to location: detail: missing parameters 1`] = ` Object { - "nav": Object {}, "navRoute": Object {}, - "route": Object {}, } `; exports[`RouterHelpers should return navigation and route details that align to location: detail: specific navigation ID 1`] = ` Object { - "nav": Object { - "id": "rhel-arm", - "isSearchable": false, - "path": "/rhel-arm", - "pathParameter": "RHEL for ARM", - "productParameter": "RHEL", - "routeHref": "/rhel-arm", - "viewParameter": "viewRHEL", - }, "navRoute": Object { - "component": Object { - "$$typeof": Symbol(react.lazy), - "_init": [Function], - "_payload": Object { - "_result": [Function], - "_status": -1, - }, - }, + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, "disabled": false, - "exact": true, "id": "rhel-arm", "isSearchable": false, "path": "/rhel-arm", "pathParameter": "RHEL for ARM", "productParameter": "RHEL", - "render": true, + "redirect": null, "routeHref": "/rhel-arm", - "to": "/:variant(rhel|rhel-arm|rhel-ibmpower|rhel-ibmz|rhel-x86)", "viewParameter": "viewRHEL", }, - "route": Object {}, } `; exports[`RouterHelpers should return navigation and route details that align to location: detail: specific route ID 1`] = ` Object { - "nav": Object { + "navRoute": Object { + "activateOnError": true, + "aliases": Array [], + "component": "optinView/optinView", + "default": false, + "disabled": false, "id": "optin", "isSearchable": false, "path": "/optin", "pathParameter": null, "productParameter": null, + "redirect": null, "routeHref": "/optin", "viewParameter": null, }, - "navRoute": Object { +} +`; + +exports[`RouterHelpers should return specific properties: routerHelpers 1`] = ` +Object { + "appName": "subscriptions", + "baseName": "/", + "basePath": "/", + "dynamicBaseName": [Function], + "dynamicBasePath": [Function], + "generateProductGroups": [Function], + "generateRoutes": [Function], + "getErrorRoute": Object { "activateOnError": true, - "component": Object { - "$$typeof": Symbol(react.lazy), - "_init": [Function], - "_payload": Object { - "_result": [Function], - "_status": -1, - }, - }, + "component": "optinView/optinView", "disabled": false, "exact": true, "id": "optin", - "isSearchable": false, "path": "/optin", - "pathParameter": null, - "productParameter": null, - "render": true, - "routeHref": "/optin", - "to": "/optin", - "viewParameter": null, + "redirect": null, }, - "route": Object {}, + "getRouteConfig": [Function], + "getRouteConfigByPath": [Function], + "importView": [Function], + "platformLandingRedirect": "/", + "platformModalRedirect": "/?not_entitled=subscriptions", + "productGroups": Object { + "viewOpenShift Container Platform": Array [ + "OpenShift Container Platform", + ], + "viewOpenShift-dedicated-metrics": Array [ + "OpenShift-dedicated-metrics", + ], + "viewOpenShift-metrics": Array [ + "OpenShift-metrics", + ], + "viewRHEL": Array [ + "RHEL", + "RHEL for ARM", + "RHEL for IBM Power", + "RHEL for IBM z", + "RHEL for x86", + ], + "viewSatellite": Array [ + "Satellite", + "Satellite Capsule", + "Satellite Server", + ], + }, + "routes": Array [ + Object { + "activateOnError": false, + "component": "productView/productViewRhel", + "disabled": false, + "exact": true, + "id": "rhel", + "path": "/rhel", + "redirect": null, + }, + Object { + "activateOnError": false, + "component": "productView/productViewRhel", + "disabled": false, + "exact": true, + "id": "rhel-arm", + "path": "/rhel-arm", + "redirect": null, + }, + Object { + "activateOnError": false, + "component": "productView/productViewRhel", + "disabled": false, + "exact": true, + "id": "rhel-ibmpower", + "path": "/rhel-ibmpower", + "redirect": null, + }, + Object { + "activateOnError": false, + "component": "productView/productViewRhel", + "disabled": false, + "exact": true, + "id": "rhel-ibmz", + "path": "/rhel-ibmz", + "redirect": null, + }, + Object { + "activateOnError": false, + "component": "productView/productViewRhel", + "disabled": false, + "exact": true, + "id": "rhel-x86", + "path": "/rhel-x86", + "redirect": null, + }, + Object { + "activateOnError": false, + "component": "productView/productViewOpenShiftContainer", + "disabled": false, + "exact": true, + "id": "openshift-container", + "path": "/openshift-container", + "redirect": null, + }, + Object { + "activateOnError": false, + "component": "productView/productViewOpenShiftDedicated", + "disabled": false, + "exact": true, + "id": "openshift-dedicated", + "path": "/openshift-dedicated", + "redirect": null, + }, + Object { + "activateOnError": false, + "component": "productView/productViewSatellite", + "disabled": false, + "exact": true, + "id": "satellite", + "path": "/satellite", + "redirect": null, + }, + Object { + "activateOnError": false, + "component": "productView/productViewSatellite", + "disabled": false, + "exact": true, + "id": "satellite-capsule", + "path": "/satellite-capsule", + "redirect": null, + }, + Object { + "activateOnError": false, + "component": "productView/productViewSatellite", + "disabled": false, + "exact": true, + "id": "satellite-server", + "path": "/satellite-server", + "redirect": null, + }, + Object { + "activateOnError": true, + "component": "optinView/optinView", + "disabled": false, + "exact": true, + "id": "optin", + "path": "/optin", + "redirect": null, + }, + Object { + "activateOnError": false, + "component": "productView/productViewMissing", + "disabled": false, + "exact": true, + "id": "missing", + "path": "/", + "redirect": "/", + }, + ], + "routesConfig": Array [ + Object { + "activateOnError": false, + "aliases": Array [ + "insights", + ], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel", + "isSearchable": true, + "path": "/rhel", + "pathParameter": Array [ + "RHEL", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-arm", + "isSearchable": false, + "path": "/rhel-arm", + "pathParameter": Array [ + "RHEL for ARM", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-ibmpower", + "isSearchable": false, + "path": "/rhel-ibmpower", + "pathParameter": Array [ + "RHEL for IBM Power", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-ibmz", + "isSearchable": false, + "path": "/rhel-ibmz", + "pathParameter": Array [ + "RHEL for IBM z", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-x86", + "isSearchable": false, + "path": "/rhel-x86", + "pathParameter": Array [ + "RHEL for x86", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewOpenShiftContainer", + "default": false, + "disabled": false, + "id": "openshift-container", + "isSearchable": true, + "path": "/openshift-container", + "pathParameter": Array [ + "OpenShift Container Platform", + "OpenShift-metrics", + ], + "productParameter": Array [ + "OpenShift Container Platform", + "OpenShift-metrics", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewOpenShiftDedicated", + "default": false, + "disabled": false, + "id": "openshift-dedicated", + "isSearchable": true, + "path": "/openshift-dedicated", + "pathParameter": Array [ + "OpenShift-dedicated-metrics", + ], + "productParameter": Array [ + "OpenShift-dedicated-metrics", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewSatellite", + "default": false, + "disabled": false, + "id": "satellite", + "isSearchable": false, + "path": "/satellite", + "pathParameter": Array [ + "Satellite", + ], + "productParameter": Array [ + "Satellite", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewSatellite", + "default": false, + "disabled": false, + "id": "satellite-capsule", + "isSearchable": false, + "path": "/satellite-capsule", + "pathParameter": Array [ + "Satellite Capsule", + ], + "productParameter": Array [ + "Satellite", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewSatellite", + "default": false, + "disabled": false, + "id": "satellite-server", + "isSearchable": false, + "path": "/satellite-server", + "pathParameter": Array [ + "Satellite Server", + ], + "productParameter": Array [ + "Satellite", + ], + "redirect": null, + }, + Object { + "activateOnError": true, + "aliases": Array [], + "component": "optinView/optinView", + "default": false, + "disabled": false, + "id": "optin", + "isSearchable": false, + "path": "/optin", + "pathParameter": null, + "productParameter": null, + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewMissing", + "default": true, + "disabled": false, + "id": "missing", + "isSearchable": false, + "path": "/", + "pathParameter": null, + "productParameter": null, + "redirect": "/", + }, + ], } `; diff --git a/src/components/router/__tests__/redirect.test.js b/src/components/router/__tests__/redirect.test.js index 777a222f5..4265cbea6 100644 --- a/src/components/router/__tests__/redirect.test.js +++ b/src/components/router/__tests__/redirect.test.js @@ -1,71 +1,64 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { BrowserRouter } from 'react-router-dom'; -import { Redirect, RoutedRedirect } from '../redirect'; +import { Redirect } from '../redirect'; +import { Router } from '../router'; describe('Redirect Component', () => { it('should render a basic component', () => { const props = { - isRedirect: false + route: '/openshift-dedicated' }; const component = shallow(); - expect(component.render()).toMatchSnapshot('basic'); + expect(component).toMatchSnapshot('basic'); }); - it('should render a routed component', () => { + it('should handle a forced redirect', () => { const props = { - isRedirect: false + isForced: true, + route: '/dolor' }; - const component = shallow( - - - + + mockWindowLocation( + () => { + const mockReplace = jest.spyOn(window.location, 'replace').mockImplementation((type, data) => ({ type, data })); + const component = shallow(); + + expect(mockReplace.mock.calls).toMatchSnapshot('forced route, replace'); + expect(component).toMatchSnapshot('forced route'); + + mockReplace.mockClear(); + }, + { + url: 'http://lorem/ipsum?dolor=sit' + } ); - expect(component.render()).toMatchSnapshot('routed'); }); it('should handle a redirect with a url', () => { const props = { - isRedirect: true, url: '//lorem/ipsum?dolor=sit' }; const component = shallow(); expect(component).toMatchSnapshot('redirect url'); }); - it('should handle missing routes with and without withRouter', () => { + it('should handle missing routes', () => { const props = { - isRedirect: true, route: '/lorem-ipsum' }; const component = shallow(); - expect(component).toMatchSnapshot('missing route: outside of withRouter'); - - const componentWithRouter = shallow( - - - - ); - - expect(componentWithRouter).toMatchSnapshot('missing route: routed redirect route'); + expect(component).toMatchSnapshot('missing route, component'); }); - it('should handle existing routes with and without withRouter', () => { + it('should handle existing routes', () => { const props = { - isRedirect: true, - route: '/openshift-sw' + route: '/openshift-container' }; - const component = shallow(); - - expect(component).toMatchSnapshot('existing route: outside of withRouter'); - const componentWithRouter = shallow( - - - - ); + const component = shallow(); + const { routes } = component.find(Router).props(); - expect(componentWithRouter).toMatchSnapshot('existing route: routed redirect route'); + expect(routes[0]).toMatchSnapshot('existing route'); }); }); diff --git a/src/components/router/__tests__/router.test.js b/src/components/router/__tests__/router.test.js index 91efc45fc..346981791 100644 --- a/src/components/router/__tests__/router.test.js +++ b/src/components/router/__tests__/router.test.js @@ -1,14 +1,13 @@ import React from 'react'; -import { mount, shallow } from 'enzyme'; -import { MemoryRouter } from 'react-router-dom'; -import { Router, Redirect, routerHelpers, routerConfig } from '../router'; +import { shallow } from 'enzyme'; +import { Provider } from 'react-redux'; +import { MemoryRouter, Route } from 'react-router-dom'; +import { store } from '../../../redux'; +import { Router } from '../router'; describe('Router Component', () => { it('should export specific properties', () => { expect(Router).toBeDefined(); - expect(Redirect).toBeDefined(); - expect(routerHelpers).toBeDefined(); - expect(routerConfig).toBeDefined(); }); it('should render a basic component', () => { @@ -20,21 +19,17 @@ describe('Router Component', () => { const props = { routes: [ { - title: 'Lorem', - to: '/lorem', + path: '/lorem', redirect: '/loremIpsum', - component: () => Lorem, + component: 'loremComponent', exact: false, - render: false, disabled: false }, { - title: 'Ipsum', - to: '/ipsum', - component: () => Ipsum, + path: '/ipsum', + component: 'ipsumComponent', activateOnError: true, exact: false, - render: false, disabled: false } ] @@ -44,31 +39,18 @@ describe('Router Component', () => { expect(component).toMatchSnapshot('settings'); }); - it('should pass customized props to routed components', () => { - const props = { - routes: [ - { - title: 'Lorem', - to: '/lorem', - redirect: '/loremIpsum', - component: () => Lorem, - exact: false, - render: true, - disabled: false - } - ] - }; + it('should load a specific route', async () => { + const props = {}; - const component = mount( - - - + const component = await mountHookComponent( + + + + + ); - - const routedComponentProps = component.find(props.routes[0].component).props(); - expect({ - routeDetail: routedComponentProps.routeDetail, - locationParsedSearch: routedComponentProps.location.parsedSearch - }).toMatchSnapshot('routeDetail and location parsedSearch props'); + const specificRoute = component.find(Route); + expect(specificRoute.length).toBe(1); + expect(specificRoute.props().path).toBe('/rhel-arm'); }); }); diff --git a/src/components/router/__tests__/routerConfig.test.js b/src/components/router/__tests__/routerConfig.test.js deleted file mode 100644 index 00d285aa0..000000000 --- a/src/components/router/__tests__/routerConfig.test.js +++ /dev/null @@ -1,35 +0,0 @@ -import { - appName, - navigation, - platformLandingRedirect, - platformModalRedirect, - productGroups, - routes -} from '../routerConfig'; - -describe('RouterConfig', () => { - it('should return specific properties', () => { - expect(appName).toMatchSnapshot('appName'); - expect(navigation).toMatchSnapshot('navigation'); - expect(platformLandingRedirect).toMatchSnapshot('platformLandingRedirect'); - expect(platformModalRedirect).toMatchSnapshot('platformModalRedirect'); - expect(productGroups).toMatchSnapshot('productGroups'); - expect(routes).toMatchSnapshot('routes'); - }); - - it('should return a lazy loaded view for every route', () => { - const lazyLoadComponents = []; - - routes.forEach(({ component, to }) => { - const routeComponent = Object.getOwnPropertyNames(component) - .map(prop => (component[prop] || '').toString()) - .find(val => /react/i.test(val)); - - if (/lazy/.test(routeComponent)) { - lazyLoadComponents.push({ routeComponentType: routeComponent, route: to }); - } - }); - - expect(lazyLoadComponents.length).toBe(6); - }); -}); diff --git a/src/components/router/__tests__/routerHelpers.test.js b/src/components/router/__tests__/routerHelpers.test.js index a41df4756..70a69667e 100644 --- a/src/components/router/__tests__/routerHelpers.test.js +++ b/src/components/router/__tests__/routerHelpers.test.js @@ -1,31 +1,15 @@ import { - baseName, - basePath, + routerHelpers, dynamicBaseName, + dynamicBasePath, getErrorRoute, - getNavigationDetail, - getRouteDetail, - getNavRouteDetail + getRouteConfig, + getRouteConfigByPath } from '../routerHelpers'; describe('RouterHelpers', () => { - const mockWindowLocation = async ({ url, callback }) => { - const updatedUrl = new URL(url); - const { location } = window; - delete window.location; - window.location = { href: updatedUrl.href, search: updatedUrl.search, hash: updatedUrl.hash }; - await callback(); - window.location = location; - }; - it('should return specific properties', () => { - expect(baseName).toBeDefined(); - expect(basePath).toBeDefined(); - expect(dynamicBaseName).toBeDefined(); - expect(getErrorRoute).toBeDefined(); - expect(getNavigationDetail).toBeDefined(); - expect(getRouteDetail).toBeDefined(); - expect(getNavRouteDetail).toBeDefined(); + expect(routerHelpers).toMatchSnapshot('routerHelpers'); }); it('should return a generated baseName using NO path prefix', () => { @@ -90,89 +74,150 @@ describe('RouterHelpers', () => { ).toMatchSnapshot('insights, beta app lorem route name'); }); + it('should return a generated basePath', () => { + expect( + dynamicBasePath({ + pathName: '/insights/appName', + appName: 'appName' + }) + ).toMatchSnapshot('insights, app base path'); + + expect( + dynamicBasePath({ + pathName: '/beta/insights/appName', + appName: 'appName' + }) + ).toMatchSnapshot('insights, beta app base path'); + + expect( + dynamicBasePath({ + pathName: '/insights/appName/loremRoute', + appName: 'appName' + }) + ).toMatchSnapshot('insights, app lorem route name base path'); + + expect( + dynamicBasePath({ + pathName: '/beta/insights/appName/loremRoute', + appName: 'appName' + }) + ).toMatchSnapshot('insights, beta app lorem route name base path'); + }); + it('should return an error route', () => { expect(getErrorRoute).toMatchSnapshot('error route'); }); it('should return navigation and route details that align to location', () => { expect({ - nav: getNavigationDetail({ id: 'optin' }), - route: getRouteDetail({ id: 'optin' }), - navRoute: getNavRouteDetail({ id: 'optin' }) + navRoute: getRouteConfig({ id: 'optin' }) }).toMatchSnapshot('detail: specific route ID'); expect({ - nav: getNavigationDetail({ id: 'rhel-arm' }), - route: getRouteDetail({ id: 'rhel-arm' }), - navRoute: getNavRouteDetail({ id: 'rhel-arm' }) + navRoute: getRouteConfig({ id: 'rhel-arm' }) }).toMatchSnapshot('detail: specific navigation ID'); expect({ - nav: getNavigationDetail({ pathname: '/rhel' }), - route: getRouteDetail({ pathname: '/rhel' }), - navRoute: getNavRouteDetail({ pathname: '/rhel' }) + navRoute: getRouteConfig({ pathName: '/rhel' }) }).toMatchSnapshot('detail: match specific path navigation'); expect({ - nav: getNavigationDetail({ id: 'lorem-missing', pathname: '/rhel' }), - route: getRouteDetail({ id: 'lorem-missing', pathname: '/rhel' }), - navRoute: getNavRouteDetail({ id: 'lorem-missing', pathname: '/rhel' }) + navRoute: getRouteConfig({ id: 'lorem-missing', pathName: '/rhel' }) }).toMatchSnapshot('detail: missing ID, specific path'); expect({ - nav: getNavigationDetail({ id: 'lorem', pathname: '/lorem-ipsum-missing', returnDefault: true }), - route: getRouteDetail({ id: 'lorem', pathname: '/lorem-ipsum-missing', returnDefault: true }), - navRoute: getNavRouteDetail({ id: 'lorem', pathname: '/lorem-ipsum-missing', returnDefault: true }) - }).toMatchSnapshot('detail: missing id and pathname, default'); + navRoute: getRouteConfig({ id: 'lorem', pathName: '/lorem-ipsum-missing', returnDefault: true }) + }).toMatchSnapshot('detail: missing id and pathName, default'); expect({ - nav: getNavigationDetail({ id: 'lorem', pathname: '/lorem-ipsum-missing', returnDefault: false }), - route: getRouteDetail({ id: 'lorem', pathname: '/lorem-ipsum-missing', returnDefault: false }), - navRoute: getNavRouteDetail({ id: 'lorem', pathname: '/lorem-ipsum-missing', returnDefault: false }) - }).toMatchSnapshot('detail: missing id and pathname and default'); + navRoute: getRouteConfig({ id: 'lorem', pathName: '/lorem-ipsum-missing', returnDefault: false }) + }).toMatchSnapshot('detail: missing id and pathName and default'); expect({ - nav: getNavigationDetail({}), - route: getRouteDetail({}), - navRoute: getNavRouteDetail({}) + navRoute: getRouteConfig({}) }).toMatchSnapshot('detail: missing parameters'); }); + it('should return default navigation and route details', () => { + mockWindowLocation( + () => { + expect({ + navRoute: getRouteConfigByPath() + }).toMatchSnapshot('detail: defaults'); + }, + { + url: 'https://ci.foo.redhat.com/loremIpsum/dolorSit/' + } + ); + }); + + it('should return navigation and route details from a path', () => { + expect({ + navRoute: getRouteConfigByPath({ pathName: '/rhel' }).firstMatch + }).toMatchSnapshot('detail: match specific path'); + + expect({ + navRoute: getRouteConfigByPath({ pathName: '/rhel-arm' }).firstMatch + }).toMatchSnapshot('detail: specific product path'); + + expect({ + navRoute: getRouteConfigByPath({ pathName: '/lorem-ipsum-missing' }).firstMatch + }).toMatchSnapshot('detail: missing pathName'); + + expect({ + navRoute: getRouteConfigByPath({}).firstMatch + }).toMatchSnapshot('detail: missing parameters'); + }); + + it('should return navigation and route details from a related name', () => { + expect({ + navRoute: getRouteConfigByPath({ pathName: '/lorem-ipsum/RHEL%20for%20ARM' }).firstMatch + }).toMatchSnapshot('detail: match related name'); + }); + it('should handle location search and hash passthrough values', () => { - mockWindowLocation({ - url: 'https://ci.foo.redhat.com/subscriptions/rhel', - callback: () => { + mockWindowLocation( + () => { expect({ - routeHref: getNavigationDetail({ pathname: '/rhel' }).routeHref + routeHref: getRouteConfig({ pathName: '/rhel' }).routeHref }).toMatchSnapshot('NO search and hash'); + }, + { + url: 'https://ci.foo.redhat.com/subscriptions/rhel' } - }); + ); - mockWindowLocation({ - url: 'https://ci.foo.redhat.com/subscriptions/rhel?dolor=sit', - callback: () => { + mockWindowLocation( + () => { expect({ - routeHref: getNavigationDetail({ pathname: '/rhel' }).routeHref + routeHref: getRouteConfig({ pathName: '/rhel' }).routeHref }).toMatchSnapshot('search'); + }, + { + url: 'https://ci.foo.redhat.com/subscriptions/rhel?dolor=sit' } - }); + ); - mockWindowLocation({ - url: 'https://ci.foo.redhat.com/subscriptions/rhel#lorem', - callback: () => { + mockWindowLocation( + () => { expect({ - routeHref: getNavigationDetail({ pathname: '/rhel' }).routeHref + routeHref: getRouteConfig({ pathName: '/rhel' }).routeHref }).toMatchSnapshot('hash'); + }, + { + url: 'https://ci.foo.redhat.com/subscriptions/rhel#lorem' } - }); + ); - mockWindowLocation({ - url: 'https://ci.foo.redhat.com/subscriptions/rhel?dolor=sit#lorem', - callback: () => { + mockWindowLocation( + () => { expect({ - routeHref: getNavigationDetail({ pathname: '/rhel' }).routeHref + routeHref: getRouteConfig({ pathName: '/rhel' }).routeHref }).toMatchSnapshot('search and hash'); + }, + { + url: 'https://ci.foo.redhat.com/subscriptions/rhel?dolor=sit#lorem' } - }); + ); }); }); diff --git a/src/components/router/index.js b/src/components/router/index.js new file mode 100644 index 000000000..493436635 --- /dev/null +++ b/src/components/router/index.js @@ -0,0 +1,5 @@ +import { Redirect } from './redirect'; +import { Router } from './router'; +import { routerHelpers } from './routerHelpers'; + +export { Redirect, Router, routerHelpers }; diff --git a/src/components/router/redirect.js b/src/components/router/redirect.js index 830dc7a21..1135a62d9 100644 --- a/src/components/router/redirect.js +++ b/src/components/router/redirect.js @@ -1,84 +1,68 @@ import path from 'path'; import React from 'react'; import PropTypes from 'prop-types'; -import { withRouter, Route } from 'react-router-dom'; +import { Router } from './router'; import { routerHelpers } from './routerHelpers'; import { helpers } from '../../common'; -import { Loader } from '../loader/loader'; - /** * A routing redirect. * * @param {object} props * @param {string} props.baseName - * @param {object} props.history - * @param {boolean} props.isRedirect - * @param {boolean} props.isReplace - * @param {string} props.url + * @param {boolean} props.isForced * @param {string} props.route + * @param {string} props.routes + * @param {string} props.url * @returns {Node} */ -const Redirect = ({ baseName, history, isRedirect, isReplace, url, route }) => { - const forceNavigation = urlRoute => { - if (!helpers.DEV_MODE && !helpers.TEST_MODE) { - if (isReplace) { - window.location.replace(urlRoute); - } else { - window.location.href = urlRoute; - } - } - }; +const Redirect = ({ baseName, isForced, route, routes, url }) => { + /** + * Bypass router, force the location. + */ + const forceNavigation = () => { + const { hash = '', search = '' } = window.location; + const forcePath = url || (route && `${path.join(baseName, route)}${search}${hash}`); - if (isRedirect === true) { - if (route && history) { - const routeDetail = routerHelpers.getRouteDetail({ pathname: route }); - - return ( - }> - {routeDetail && } - - ); - } + window.location.replace(forcePath); + }; - const forcePath = url || (route && path.join(baseName, route)); - forceNavigation(forcePath); + const { path: matchedRoutePath, ...matchedRoute } = routerHelpers.getRouteConfig({ pathName: route, id: route }); - return ( - ((helpers.DEV_MODE || helpers.TEST_MODE) && Redirected towards {forcePath}) || - null - ); + if (!isForced && matchedRoutePath) { + return ; } - return null; + forceNavigation(); + + return (helpers.TEST_MODE && Redirected towards {url || route}) || null; }; /** * Prop types. * - * @type {{isRedirect: boolean, route: string, isReplace: boolean, history: object, baseName: string, url: string}} + * @type {{isRedirect: boolean, route: string, routes: Array, isReplace: boolean, baseName: string, url: string, + * isForced: boolean}} */ Redirect.propTypes = { - history: PropTypes.object, - isRedirect: PropTypes.bool.isRequired, - isReplace: PropTypes.bool, - url: PropTypes.string, baseName: PropTypes.string, - route: PropTypes.string + isForced: PropTypes.bool, + route: PropTypes.string, + routes: PropTypes.array, + url: PropTypes.string }; /** * Default props. * - * @type {{route: null, isReplace: boolean, history: null, baseName: string, url: null}} + * @type {{isRedirect: boolean, route: string, routes: Array, isReplace: boolean, baseName: string, url: string, + * isForced: boolean}} */ Redirect.defaultProps = { - history: null, - isReplace: false, - url: null, baseName: routerHelpers.baseName, - route: null + isForced: false, + route: null, + routes: routerHelpers.routes, + url: null }; -const RoutedRedirect = withRouter(Redirect); - -export { RoutedRedirect as default, RoutedRedirect, Redirect }; +export { Redirect as default, Redirect }; diff --git a/src/components/router/router.js b/src/components/router/router.js index f54390a8f..dc05594b3 100644 --- a/src/components/router/router.js +++ b/src/components/router/router.js @@ -1,111 +1,94 @@ -import React from 'react'; +import React, { useState } from 'react'; import PropTypes from 'prop-types'; import { Redirect as ReactRouterDomRedirect, Route, Switch } from 'react-router-dom'; -import Redirect from './redirect'; +import { useMount } from 'react-use'; import { routerHelpers } from './routerHelpers'; -import { routerConfig } from './routerConfig'; import { Loader } from '../loader/loader'; /** * Load routes. * - * @augments React.Component + * @param {object} props + * @param {Array} props.routes + * @returns {Node} */ -class Router extends React.Component { +const Router = ({ routes } = {}) => { + const [updatedRoutes, setUpdatedRoutes] = useState([]); + const [redirectDefault, setRedirectDefault] = useState(null); + /** - * Parse settings array with route options. - * - * @returns {{redirectRoot: Node, renderRoutes: Array}} + * Initialize routes. */ - renderRoutes() { - const { routes } = this.props; + useMount(async () => { const activateOnErrorRoute = routes.find(route => route.activateOnError === true); - let redirectRoot = null; - return { - renderRoutes: routes.map(item => { + const results = await Promise.all( + routes.map(async item => { if (item.disabled) { return null; } - if (item.redirect) { - redirectRoot = ; - } - - if (item.render === true) { - return ( - { - const navDetail = routerHelpers.getNavigationDetail({ - pathname: location && location.pathname, - returnDefault: false - }); + const View = await routerHelpers.importView(item.component); - const { URLSearchParams, decodeURIComponent } = window; - const parsedSearch = {}; + return ( + { + const routeConfig = item.id && routerHelpers.getRouteConfig({ id: item.id }); + const { URLSearchParams, decodeURIComponent } = window; + const parsedSearch = {}; - [ - ...new Set( - [...new URLSearchParams(decodeURIComponent(location.search))].map( - ([param, value]) => `${param}~${value}` - ) + [ + ...new Set( + [...new URLSearchParams(decodeURIComponent(location.search))].map( + ([param, value]) => `${param}~${value}` ) - ].forEach(v => { - const [param, value] = v.split('~'); - parsedSearch[param] = value; - }); + ) + ].forEach(v => { + const [param, value] = v.split('~'); + parsedSearch[param] = value; + }); - const updatedLocation = { - ...location, - parsedSearch - }; - - return ( - - ); - }} - /> - ); - } + const updatedLocation = { + ...location, + parsedSearch + }; - return ; - }), - redirectRoot - }; - } + return ( + + ); + }} + /> + ); + }) + ); - /** - * Render router. - * - * @returns {Node} - */ - render() { - const { renderRoutes, redirectRoot } = this.renderRoutes(); + setUpdatedRoutes(results); + setRedirectDefault(routes.find(({ disabled, redirect }) => !disabled && redirect) ?? null); + }); - return ( - }> - - {renderRoutes} - {redirectRoot} - - - ); - } -} + return ( + }> + + {updatedRoutes} + {redirectDefault && } + + + ); +}; /** * Prop types. @@ -116,13 +99,14 @@ Router.propTypes = { routes: PropTypes.arrayOf( PropTypes.shape({ activateOnError: PropTypes.boolean, - component: PropTypes.any.isRequired, + component: PropTypes.string.isRequired, disabled: PropTypes.boolean, exact: PropTypes.boolean, + id: PropTypes.string, + path: PropTypes.string.isRequired, redirect: PropTypes.string, render: PropTypes.boolean, - strict: PropTypes.boolean, - to: PropTypes.string.isRequired + strict: PropTypes.boolean }) ) }; @@ -133,7 +117,7 @@ Router.propTypes = { * @type {{routes: Array}} */ Router.defaultProps = { - routes: routerConfig.routes + routes: routerHelpers.routes }; -export { Router as default, Router, Redirect, routerHelpers, routerConfig }; +export { Router as default, Router }; diff --git a/src/components/router/routerConfig.js b/src/components/router/routerConfig.js deleted file mode 100644 index 8cdaa9a26..000000000 --- a/src/components/router/routerConfig.js +++ /dev/null @@ -1,229 +0,0 @@ -import React from 'react'; -import path from 'path'; -import { helpers } from '../../common/helpers'; -import { RHSM_API_PATH_ID_TYPES } from '../../types/rhsmApiTypes'; - -/** - * Platform name/id. - * - * @type {string} - */ -const appName = helpers.UI_NAME; - -/** - * Return a string that describes a platform redirect. - * - * @returns {Array} - */ -const platformLandingRedirect = path.join(helpers.UI_DEPLOY_PATH_PREFIX, '/'); - -/** - * Return a string that describes a platform redirect. - * - * @returns {Array} - */ -const platformModalRedirect = path.join(helpers.UI_DEPLOY_PATH_PREFIX, '/?not_entitled=subscriptions'); - -/** - * ToDo: Dynamically generate productGroups listing from navigation, possible helper - * In addition to the platform nav IDs, we'll need to account for viewIds that are used - * for both viewId and productIds, and multi-column products views. This should tie into - * the future blend of routing, navigation, and product configuration. - */ -/** - * Reference for products grouped by view. - */ -const productGroups = { - [`view${RHSM_API_PATH_ID_TYPES.RHEL}`]: [ - RHSM_API_PATH_ID_TYPES.RHEL, - RHSM_API_PATH_ID_TYPES.RHEL_ARM, - RHSM_API_PATH_ID_TYPES.RHEL_IBM_POWER, - RHSM_API_PATH_ID_TYPES.RHEL_IBM_Z, - RHSM_API_PATH_ID_TYPES.RHEL_X86 - ], - viewOpenShift: [RHSM_API_PATH_ID_TYPES.OPENSHIFT], - viewOpenShiftMetric: [RHSM_API_PATH_ID_TYPES.OPENSHIFT_METRICS], - [`view${RHSM_API_PATH_ID_TYPES.OPENSHIFT_DEDICATED_METRICS}`]: [RHSM_API_PATH_ID_TYPES.OPENSHIFT_DEDICATED_METRICS], - [`view${RHSM_API_PATH_ID_TYPES.SATELLITE}`]: [ - RHSM_API_PATH_ID_TYPES.SATELLITE, - RHSM_API_PATH_ID_TYPES.SATELLITE_CAPSULE, - RHSM_API_PATH_ID_TYPES.SATELLITE_SERVER - ] -}; - -/** - * Return array of objects that describes routing. - * - * @returns {Array} - */ -const routes = [ - { - to: '/:variant(rhel|rhel-arm|rhel-ibmpower|rhel-ibmz|rhel-x86)', - component: React.lazy(() => import('../productView/productViewRhel')), - exact: true, - render: true, - disabled: helpers.UI_DISABLED - }, - { - to: '/openshift-container', - component: React.lazy(() => import('../productView/productViewOpenShiftContainer')), - exact: true, - render: true, - disabled: helpers.UI_DISABLED - }, - { - to: '/openshift-dedicated', - component: React.lazy(() => import('../productView/productViewOpenShiftDedicated')), - exact: true, - render: true, - disabled: helpers.UI_DISABLED - }, - { - to: '/:variant(satellite|satellite-capsule|satellite-server)', - component: React.lazy(() => import('../productView/productViewSatellite')), - exact: true, - render: true, - disabled: helpers.UI_DISABLED - }, - { - to: '/optin', - component: React.lazy(() => import('../optinView/optinView')), - exact: true, - render: true, - activateOnError: true, - disabled: helpers.UI_DISABLED - }, - { - to: '/', - redirect: '/', - component: React.lazy(() => import('../productView/productViewMissing')), - exact: true, - render: true, - disabled: helpers.UI_DISABLED - } -]; - -/** - * Return an array of objects that describes navigation against API product IDs. - * - * @returns {Array} - */ -const navigation = [ - { - id: 'rhel', - path: '/rhel', - pathParameter: RHSM_API_PATH_ID_TYPES.RHEL, - productParameter: RHSM_API_PATH_ID_TYPES.RHEL, - viewParameter: `view${RHSM_API_PATH_ID_TYPES.RHEL}`, - isSearchable: true - }, - { - id: 'rhel-arm', - path: '/rhel-arm', - pathParameter: RHSM_API_PATH_ID_TYPES.RHEL_ARM, - productParameter: RHSM_API_PATH_ID_TYPES.RHEL, - viewParameter: `view${RHSM_API_PATH_ID_TYPES.RHEL}`, - isSearchable: false - }, - { - id: 'rhel-ibmpower', - path: '/rhel-ibmpower', - pathParameter: RHSM_API_PATH_ID_TYPES.RHEL_IBM_POWER, - productParameter: RHSM_API_PATH_ID_TYPES.RHEL, - viewParameter: `view${RHSM_API_PATH_ID_TYPES.RHEL}`, - isSearchable: false - }, - { - id: 'rhel-ibmz', - path: '/rhel-ibmz', - pathParameter: RHSM_API_PATH_ID_TYPES.RHEL_IBM_Z, - productParameter: RHSM_API_PATH_ID_TYPES.RHEL, - viewParameter: `view${RHSM_API_PATH_ID_TYPES.RHEL}`, - isSearchable: false - }, - { - id: 'rhel-x86', - path: '/rhel-x86', - pathParameter: RHSM_API_PATH_ID_TYPES.RHEL_X86, - productParameter: RHSM_API_PATH_ID_TYPES.RHEL, - viewParameter: `view${RHSM_API_PATH_ID_TYPES.RHEL}`, - isSearchable: false - }, - { - id: 'openshift-container', - path: '/openshift-container', - pathParameter: RHSM_API_PATH_ID_TYPES.OPENSHIFT, - productParameter: RHSM_API_PATH_ID_TYPES.OPENSHIFT, - viewParameter: `view${RHSM_API_PATH_ID_TYPES.OPENSHIFT}`, - isSearchable: true - }, - { - id: 'openshift-dedicated', - path: '/openshift-dedicated', - pathParameter: RHSM_API_PATH_ID_TYPES.OPENSHIFT_DEDICATED_METRICS, - productParameter: RHSM_API_PATH_ID_TYPES.OPENSHIFT_DEDICATED_METRICS, - viewParameter: `view${RHSM_API_PATH_ID_TYPES.OPENSHIFT_DEDICATED_METRICS}`, - isSearchable: true - }, - { - id: 'satellite', - path: '/satellite', - pathParameter: RHSM_API_PATH_ID_TYPES.SATELLITE, - productParameter: RHSM_API_PATH_ID_TYPES.SATELLITE, - viewParameter: `view${RHSM_API_PATH_ID_TYPES.SATELLITE}`, - isSearchable: false - }, - { - id: 'satellite-capsule', - path: '/satellite-capsule', - pathParameter: RHSM_API_PATH_ID_TYPES.SATELLITE_CAPSULE, - productParameter: RHSM_API_PATH_ID_TYPES.SATELLITE, - viewParameter: `view${RHSM_API_PATH_ID_TYPES.SATELLITE}`, - isSearchable: false - }, - { - id: 'satellite-server', - path: '/satellite-server', - pathParameter: RHSM_API_PATH_ID_TYPES.SATELLITE_SERVER, - productParameter: RHSM_API_PATH_ID_TYPES.SATELLITE, - viewParameter: `view${RHSM_API_PATH_ID_TYPES.SATELLITE}`, - isSearchable: false - }, - { - id: 'optin', - path: '/optin', - pathParameter: null, - productParameter: null, - viewParameter: null, - isSearchable: false - }, - { - id: 'missing', - path: '/', - pathParameter: null, - productParameter: null, - viewParameter: null, - isSearchable: false, - default: true - } -]; - -const routerConfig = { - appName, - navigation, - platformLandingRedirect, - platformModalRedirect, - productGroups, - routes -}; - -export { - routerConfig as default, - routerConfig, - appName, - navigation, - platformLandingRedirect, - platformModalRedirect, - productGroups, - routes -}; diff --git a/src/components/router/routerHelpers.js b/src/components/router/routerHelpers.js index 912393e30..229dfc058 100644 --- a/src/components/router/routerHelpers.js +++ b/src/components/router/routerHelpers.js @@ -1,5 +1,28 @@ +import React from 'react'; +import path from 'path'; import { helpers } from '../../common/helpers'; -import { routes, navigation } from './routerConfig'; +import { routesConfig } from '../../config'; + +/** + * Platform name/id. + * + * @type {string} + */ +const appName = helpers.UI_NAME; + +/** + * Return a string that describes a platform redirect. + * + * @returns {Array} + */ +const platformLandingRedirect = path.join(helpers.UI_DEPLOY_PATH_PREFIX, '/'); + +/** + * Return a string that describes a platform redirect. + * + * @returns {Array} + */ +const platformModalRedirect = path.join(helpers.UI_DEPLOY_PATH_PREFIX, '/?not_entitled=subscriptions'); /** * Return an assumed route baseName directory based on existing app name. @@ -11,8 +34,8 @@ import { routes, navigation } from './routerConfig'; * @param {string} params.appName * @returns {string} */ -const dynamicBaseName = ({ pathName = window.location.pathname, appName = helpers.UI_NAME } = {}) => - `${pathName.split(appName)[0]}${appName}`; +const dynamicBaseName = ({ pathName = window.location.pathname, appName: applicationName = helpers.UI_NAME } = {}) => + `${pathName.split(applicationName)[0]}${applicationName}`; /** * The app baseName. @@ -21,13 +44,82 @@ const dynamicBaseName = ({ pathName = window.location.pathname, appName = helper */ const baseName = (helpers.TEST_MODE && '/') || (helpers.DEV_MODE && '/') || dynamicBaseName(); +/** + * Return a base path. + * + * @param {object} params + * @param {string} params.pathName + * @param {string} params.appName + * @returns {string} + */ +const dynamicBasePath = ({ pathName = window.location.pathname, appName: applicationName = helpers.UI_NAME } = {}) => + pathName.split(applicationName)[0]; + /** * App basePath. * * @type {string} */ -const basePath = - (helpers.TEST_MODE && '/') || (helpers.DEV_MODE && '/') || window.location.pathname.split(helpers.UI_NAME)[0]; +const basePath = (helpers.TEST_MODE && '/') || (helpers.DEV_MODE && '/') || dynamicBasePath(); + +/** + * Generate product groups for applying query filter resets. + * + * @param {Array} config + * @returns {Array} + */ +const generateProductGroups = (config = routesConfig) => { + const productGroups = {}; + + config.forEach(({ pathParameter, productParameter }) => { + const viewIds = ((Array.isArray(productParameter) && productParameter) || [productParameter]).map( + id => (id && `view${id}`) || id + ); + + viewIds.forEach((id, index) => { + if (id) { + if (!productGroups[id]) { + productGroups[id] = []; + } + + if (pathParameter) { + productGroups[id].push((Array.isArray(pathParameter) && pathParameter?.[index]) || pathParameter); + } + } + }); + }); + + return productGroups; +}; + +/** + * Reference for products grouped by view. + */ +const productGroups = generateProductGroups(); + +/** + * Generate routes to be consumed by router. + * + * @param {Array} config + * @returns {Array} + */ +const generateRoutes = (config = routesConfig) => + config.map(({ activateOnError, component, disabled, id, path: routePath, redirect }) => ({ + activateOnError, + component, + disabled, + exact: true, + id, + path: routePath, + redirect + })); + +/** + * Return array of objects that describes routing. + * + * @returns {Array} + */ +const routes = generateRoutes(); /** * The first error route. @@ -37,107 +129,149 @@ const basePath = const getErrorRoute = routes.find(route => route.activateOnError === true) || {}; /** - * Return an object matching a specific navigation object. + * Match route config entries by path. * * @param {object} params - * @param {string} params.id - * @param {string} params.pathname - * @param {boolean} params.returnDefault - * @returns {object} + * @param {string} params.pathName + * @param {Array} params.config + * @returns {{configs: Array, configFirstMatch: object, configsById: object}} */ -const getNavigationDetail = ({ id = null, pathname = null, returnDefault = false }) => { - const defaultItem = returnDefault && navigation.find(item => item.default === true); - let navigationItem; +const getRouteConfigByPath = ({ pathName = dynamicBasePath(), config = routesConfig } = {}) => { + const basePathDirs = pathName?.split('/').filter(str => str.length > 0); + const configs = []; + const allConfigs = []; + const configsById = {}; + const allConfigsById = {}; - if (id) { - navigationItem = navigation.find(item => item.id === id); - } - - if (!navigationItem && pathname) { - navigationItem = - navigation.find(item => item.path.replace(/\/$/, '') === pathname.replace(/\/$/, '')) || - (returnDefault && defaultItem); - } + const findConfig = dir => { + config.forEach(({ id, path: configPath, pathParameter, productParameter, aliases, ...configItem }) => { + const updatedConfigItem = { + aliases, + id, + path: configPath, + pathParameter, + productParameter, + ...configItem + }; - if (!navigationItem && returnDefault) { - navigationItem = defaultItem; - } + if ( + dir && + (new RegExp(dir, 'i').test(configPath) || + new RegExp(dir, 'i').test(productParameter?.toString()) || + new RegExp(dir, 'i').test(pathParameter?.toString()) || + new RegExp(dir, 'i').test(aliases?.toString())) + ) { + if (!configsById[id]) { + configsById[id] = { ...updatedConfigItem }; + configs.push({ ...updatedConfigItem }); + } + } - /** - * Note: have to account for carrying through location.search and location.hash, future updates - * Originally, we used a split on window.location.href.split(navigationItem.path) as an easy way - * to pull everything and maintain sequence, but there appears to be a race like condition - * happening on certain routes where window.location.href is updated first in some routing - * instances, and then in other instances requires being updated by the app/GUI. - */ - if (navigationItem) { - const { search = '', hash = '' } = window.location; + if (!allConfigsById[id]) { + allConfigsById[id] = { ...updatedConfigItem }; + allConfigs.push({ ...updatedConfigItem }); + } + }); + }; - navigationItem.routeHref = `${navigationItem.path}${search}${hash}`; + if (basePathDirs?.length) { + basePathDirs.forEach(dir => { + if (dir) { + const decodedDir = window.decodeURI(dir); + findConfig(decodedDir); + } + }); + } else { + findConfig(); } - return { ...(navigationItem || {}) }; + return { allConfigs, allConfigsById, configs, configsById, firstMatch: configs?.[0] }; }; /** - * Return an object matching a specific, or the first generic route. + * Return a route config object. * * @param {object} params * @param {string} params.id - * @param {string} params.pathname + * @param {string} params.pathName + * @param {boolean} params.returnDefault + * @param {Array} params.config * @returns {object} */ -const getRouteDetail = ({ id = null, pathname = null }) => { - let routeItem; +const getRouteConfig = ({ id = null, pathName, returnDefault = false, config = routesConfig } = {}) => { + let navRouteItem; if (id) { - routeItem = routes.find(value => id === value.id); + navRouteItem = config.find(item => item.id === id); + } + + if ((!navRouteItem && pathName) || (!navRouteItem && !pathName && !returnDefault)) { + navRouteItem = getRouteConfigByPath({ pathName, config }).firstMatch; + } + + if (!navRouteItem && returnDefault) { + navRouteItem = config.find(item => item.default === true); } - if (!routeItem && pathname) { - routeItem = routes.find(value => pathname === value.to); - routeItem = routeItem || routes.find(item => item?.to?.includes(pathname.split('/').reverse()[0])); + if (navRouteItem) { + const { search = '', hash = '' } = window.location; + navRouteItem.routeHref = `${navRouteItem.path}${search}${hash}`; + + const { pathParameter, productParameter } = navRouteItem; + navRouteItem.pathParameter = (Array.isArray(pathParameter) && pathParameter[0]) || pathParameter; + navRouteItem.productParameter = (Array.isArray(productParameter) && productParameter[0]) || productParameter; + navRouteItem.viewParameter = + (productParameter && `view${(Array.isArray(productParameter) && productParameter[0]) || productParameter}`) || + productParameter; } - return { ...(routeItem || {}) }; + return { ...(navRouteItem || {}) }; }; /** - * Return an object generated from both generic routes and specific navigation objects. - * ID is not passed to "getRouteDetail" to avoid conflicts between routing and - * navigation. + * Import a route component. * - * @param {object} params - * @param {string} params.id - * @param {string} params.pathname - * @param {boolean} params.returnDefault - * @returns {object} + * @param {Node} component + * @returns {Node} */ -const getNavRouteDetail = ({ id = null, pathname = null, returnDefault = false }) => { - const navDetail = getNavigationDetail({ id, pathname, returnDefault }); - const routeDetail = getRouteDetail({ pathname: navDetail.path || pathname }); - - return { ...routeDetail, ...navDetail }; -}; +const importView = component => React.lazy(() => import(/* webpackExclude: /\.test\.js$/ */ `../${component}.js`)); const routerHelpers = { + appName, baseName, basePath, dynamicBaseName, + dynamicBasePath, + generateProductGroups, + generateRoutes, getErrorRoute, - getNavigationDetail, - getRouteDetail, - getNavRouteDetail + getRouteConfig, + getRouteConfigByPath, + importView, + platformLandingRedirect, + platformModalRedirect, + productGroups, + routes, + routesConfig }; export { routerHelpers as default, routerHelpers, + appName, baseName, basePath, dynamicBaseName, + dynamicBasePath, + generateProductGroups, + generateRoutes, getErrorRoute, - getNavigationDetail, - getRouteDetail, - getNavRouteDetail + getRouteConfig, + getRouteConfigByPath, + importView, + platformLandingRedirect, + platformModalRedirect, + productGroups, + routes, + routesConfig }; diff --git a/src/components/toolbar/__tests__/__snapshots__/toolbarFieldDisplayName.test.js.snap b/src/components/toolbar/__tests__/__snapshots__/toolbarFieldDisplayName.test.js.snap index b28c882bc..2509172dd 100644 --- a/src/components/toolbar/__tests__/__snapshots__/toolbarFieldDisplayName.test.js.snap +++ b/src/components/toolbar/__tests__/__snapshots__/toolbarFieldDisplayName.test.js.snap @@ -59,6 +59,7 @@ exports[`ToolbarFieldDisplayName Component should render a non-connected compone { onKeyUp={onKeyUp} value={currentValue} placeholder={t('curiosity-toolbar.placeholder', { context: 'displayName' })} + data-test={ToolbarFieldDisplayName.defaultProps.viewId} /> ); diff --git a/src/components/toolbar/toolbarFieldGranularity.js b/src/components/toolbar/toolbarFieldGranularity.js index b096d1de4..c395a8e4b 100644 --- a/src/components/toolbar/toolbarFieldGranularity.js +++ b/src/components/toolbar/toolbarFieldGranularity.js @@ -75,6 +75,7 @@ const ToolbarFieldGranularity = ({ options, t, value, viewId }) => { options={updatedOptions} selectedOptions={updatedValue} placeholder={t('curiosity-toolbar.placeholder', { context: 'granularity' })} + data-test={ToolbarFieldGranularity.defaultProps.viewId} /> ); }; diff --git a/src/components/toolbar/toolbarFieldRangedMonthly.js b/src/components/toolbar/toolbarFieldRangedMonthly.js index 28f1c0a8a..ed7a95289 100644 --- a/src/components/toolbar/toolbarFieldRangedMonthly.js +++ b/src/components/toolbar/toolbarFieldRangedMonthly.js @@ -75,6 +75,7 @@ const ToolbarFieldRangedMonthly = ({ options, t, value, viewId }) => { placeholder={t('curiosity-toolbar.placeholder', { context: 'granularity' })} position={SelectPosition.right} maxHeight={250} + data-test={ToolbarFieldRangedMonthly.defaultProps.viewId} /> ); }; diff --git a/src/components/toolbar/toolbarFieldUom.js b/src/components/toolbar/toolbarFieldUom.js index ce2b8af60..bda30a8de 100644 --- a/src/components/toolbar/toolbarFieldUom.js +++ b/src/components/toolbar/toolbarFieldUom.js @@ -59,6 +59,7 @@ const ToolbarFieldUom = ({ options, t, value, viewId }) => { options={updatedOptions} selectedOptions={updatedValue} placeholder={t('curiosity-toolbar.placeholder', { context: 'uom' })} + data-test={ToolbarFieldUom.defaultProps.viewId} /> ); }; diff --git a/src/config/__tests__/__snapshots__/index.test.js.snap b/src/config/__tests__/__snapshots__/index.test.js.snap new file mode 100644 index 000000000..e09aa69e5 --- /dev/null +++ b/src/config/__tests__/__snapshots__/index.test.js.snap @@ -0,0 +1,250 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Configuration should have specific config properties: config 1`] = ` +Object { + "rbac": Object { + "inventory": Object { + "permissions": Array [ + Object { + "operation": "*", + "resource": "*", + }, + Object { + "operation": "*", + "resource": "hosts", + }, + Object { + "operation": "read", + "resource": "hosts", + }, + Object { + "operation": "write", + "resource": "hosts", + }, + ], + }, + "subscriptions": Object { + "permissions": Array [ + Object { + "operation": "*", + "resource": "*", + }, + Object { + "operation": "*", + "resource": "reports", + }, + Object { + "operation": "read", + "resource": "reports", + }, + Object { + "operation": "write", + "resource": "reports", + }, + ], + }, + }, + "routes": Array [ + Object { + "activateOnError": false, + "aliases": Array [ + "insights", + ], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel", + "isSearchable": true, + "path": "/rhel", + "pathParameter": Array [ + "RHEL", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-arm", + "isSearchable": false, + "path": "/rhel-arm", + "pathParameter": Array [ + "RHEL for ARM", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-ibmpower", + "isSearchable": false, + "path": "/rhel-ibmpower", + "pathParameter": Array [ + "RHEL for IBM Power", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-ibmz", + "isSearchable": false, + "path": "/rhel-ibmz", + "pathParameter": Array [ + "RHEL for IBM z", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewRhel", + "default": false, + "disabled": false, + "id": "rhel-x86", + "isSearchable": false, + "path": "/rhel-x86", + "pathParameter": Array [ + "RHEL for x86", + ], + "productParameter": Array [ + "RHEL", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewOpenShiftContainer", + "default": false, + "disabled": false, + "id": "openshift-container", + "isSearchable": true, + "path": "/openshift-container", + "pathParameter": Array [ + "OpenShift Container Platform", + "OpenShift-metrics", + ], + "productParameter": Array [ + "OpenShift Container Platform", + "OpenShift-metrics", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewOpenShiftDedicated", + "default": false, + "disabled": false, + "id": "openshift-dedicated", + "isSearchable": true, + "path": "/openshift-dedicated", + "pathParameter": Array [ + "OpenShift-dedicated-metrics", + ], + "productParameter": Array [ + "OpenShift-dedicated-metrics", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewSatellite", + "default": false, + "disabled": false, + "id": "satellite", + "isSearchable": false, + "path": "/satellite", + "pathParameter": Array [ + "Satellite", + ], + "productParameter": Array [ + "Satellite", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewSatellite", + "default": false, + "disabled": false, + "id": "satellite-capsule", + "isSearchable": false, + "path": "/satellite-capsule", + "pathParameter": Array [ + "Satellite Capsule", + ], + "productParameter": Array [ + "Satellite", + ], + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewSatellite", + "default": false, + "disabled": false, + "id": "satellite-server", + "isSearchable": false, + "path": "/satellite-server", + "pathParameter": Array [ + "Satellite Server", + ], + "productParameter": Array [ + "Satellite", + ], + "redirect": null, + }, + Object { + "activateOnError": true, + "aliases": Array [], + "component": "optinView/optinView", + "default": false, + "disabled": false, + "id": "optin", + "isSearchable": false, + "path": "/optin", + "pathParameter": null, + "productParameter": null, + "redirect": null, + }, + Object { + "activateOnError": false, + "aliases": Array [], + "component": "productView/productViewMissing", + "default": true, + "disabled": false, + "id": "missing", + "isSearchable": false, + "path": "/", + "pathParameter": null, + "productParameter": null, + "redirect": "/", + }, + ], +} +`; diff --git a/src/config/__tests__/index.test.js b/src/config/__tests__/index.test.js new file mode 100644 index 000000000..aa32e824c --- /dev/null +++ b/src/config/__tests__/index.test.js @@ -0,0 +1,7 @@ +import { config } from '../index'; + +describe('Configuration', () => { + it('should have specific config properties', () => { + expect(config).toMatchSnapshot('config'); + }); +}); diff --git a/src/config/index.js b/src/config/index.js new file mode 100644 index 000000000..1b6855701 --- /dev/null +++ b/src/config/index.js @@ -0,0 +1,9 @@ +import rbacConfig from './rbac'; +import { routes as routesConfig } from './routes'; + +const config = { + rbac: rbacConfig, + routes: routesConfig +}; + +export { config as default, config, rbacConfig, routesConfig }; diff --git a/src/config/routes.js b/src/config/routes.js new file mode 100644 index 000000000..9c1e2f0b8 --- /dev/null +++ b/src/config/routes.js @@ -0,0 +1,163 @@ +import { RHSM_API_PATH_ID_TYPES } from '../types/rhsmApiTypes'; +import { helpers } from '../common'; + +const routes = [ + { + id: 'rhel', + path: '/rhel', + pathParameter: [RHSM_API_PATH_ID_TYPES.RHEL], + productParameter: [RHSM_API_PATH_ID_TYPES.RHEL], + redirect: null, + isSearchable: true, + aliases: ['insights'], + activateOnError: false, + disabled: helpers.UI_DISABLED, + default: false, + component: 'productView/productViewRhel' + }, + { + id: 'rhel-arm', + path: '/rhel-arm', + pathParameter: [RHSM_API_PATH_ID_TYPES.RHEL_ARM], + productParameter: [RHSM_API_PATH_ID_TYPES.RHEL], + redirect: null, + isSearchable: false, + aliases: [], + activateOnError: false, + disabled: helpers.UI_DISABLED, + default: false, + component: 'productView/productViewRhel' + }, + { + id: 'rhel-ibmpower', + path: '/rhel-ibmpower', + pathParameter: [RHSM_API_PATH_ID_TYPES.RHEL_IBM_POWER], + productParameter: [RHSM_API_PATH_ID_TYPES.RHEL], + redirect: null, + isSearchable: false, + aliases: [], + activateOnError: false, + disabled: helpers.UI_DISABLED, + default: false, + component: 'productView/productViewRhel' + }, + { + id: 'rhel-ibmz', + path: '/rhel-ibmz', + pathParameter: [RHSM_API_PATH_ID_TYPES.RHEL_IBM_Z], + productParameter: [RHSM_API_PATH_ID_TYPES.RHEL], + redirect: null, + isSearchable: false, + aliases: [], + activateOnError: false, + disabled: helpers.UI_DISABLED, + default: false, + component: 'productView/productViewRhel' + }, + { + id: 'rhel-x86', + path: '/rhel-x86', + pathParameter: [RHSM_API_PATH_ID_TYPES.RHEL_X86], + productParameter: [RHSM_API_PATH_ID_TYPES.RHEL], + redirect: null, + isSearchable: false, + aliases: [], + activateOnError: false, + disabled: helpers.UI_DISABLED, + default: false, + component: 'productView/productViewRhel' + }, + { + id: 'openshift-container', + path: '/openshift-container', + pathParameter: [RHSM_API_PATH_ID_TYPES.OPENSHIFT, RHSM_API_PATH_ID_TYPES.OPENSHIFT_METRICS], + productParameter: [RHSM_API_PATH_ID_TYPES.OPENSHIFT, RHSM_API_PATH_ID_TYPES.OPENSHIFT_METRICS], + redirect: null, + isSearchable: true, + aliases: [], + activateOnError: false, + disabled: helpers.UI_DISABLED, + default: false, + component: 'productView/productViewOpenShiftContainer' + }, + { + id: 'openshift-dedicated', + path: '/openshift-dedicated', + pathParameter: [RHSM_API_PATH_ID_TYPES.OPENSHIFT_DEDICATED_METRICS], + productParameter: [RHSM_API_PATH_ID_TYPES.OPENSHIFT_DEDICATED_METRICS], + redirect: null, + isSearchable: true, + aliases: [], + activateOnError: false, + disabled: helpers.UI_DISABLED, + default: false, + component: 'productView/productViewOpenShiftDedicated' + }, + { + id: 'satellite', + path: '/satellite', + pathParameter: [RHSM_API_PATH_ID_TYPES.SATELLITE], + productParameter: [RHSM_API_PATH_ID_TYPES.SATELLITE], + redirect: null, + isSearchable: false, + aliases: [], + activateOnError: false, + disabled: helpers.UI_DISABLED, + default: false, + component: 'productView/productViewSatellite' + }, + { + id: 'satellite-capsule', + path: '/satellite-capsule', + pathParameter: [RHSM_API_PATH_ID_TYPES.SATELLITE_CAPSULE], + productParameter: [RHSM_API_PATH_ID_TYPES.SATELLITE], + redirect: null, + isSearchable: false, + aliases: [], + activateOnError: false, + disabled: helpers.UI_DISABLED, + default: false, + component: 'productView/productViewSatellite' + }, + { + id: 'satellite-server', + path: '/satellite-server', + pathParameter: [RHSM_API_PATH_ID_TYPES.SATELLITE_SERVER], + productParameter: [RHSM_API_PATH_ID_TYPES.SATELLITE], + redirect: null, + isSearchable: false, + aliases: [], + activateOnError: false, + disabled: helpers.UI_DISABLED, + default: false, + component: 'productView/productViewSatellite' + }, + { + id: 'optin', + path: '/optin', + pathParameter: null, + productParameter: null, + redirect: null, + isSearchable: false, + aliases: [], + activateOnError: true, + disabled: helpers.UI_DISABLED, + default: false, + component: 'optinView/optinView' + }, + { + id: 'missing', + path: '/', + pathParameter: null, + productParameter: null, + redirect: '/', + isSearchable: false, + aliases: [], + activateOnError: false, + disabled: helpers.UI_DISABLED, + default: true, + component: 'productView/productViewMissing' + } +]; + +export { routes as default, routes }; diff --git a/src/hooks/__tests__/__snapshots__/useRouter.test.js.snap b/src/hooks/__tests__/__snapshots__/useRouter.test.js.snap new file mode 100644 index 000000000..8f62a0c3e --- /dev/null +++ b/src/hooks/__tests__/__snapshots__/useRouter.test.js.snap @@ -0,0 +1,35 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`useRouter should apply a hook for useHistory: push, config route 1`] = ` +Array [ + Array [ + Object { + "meta": Object { + "appName": undefined, + "id": "rhel", + "secondaryNav": undefined, + }, + "payload": Promise {}, + "type": "PLATFORM_SET_NAV", + }, + ], +] +`; + +exports[`useRouter should apply a hook for useHistory: push, unique route 1`] = ` +Array [ + Array [ + "/lorem/ipsum", + undefined, + ], +] +`; + +exports[`useRouter should return specific properties: specific properties 1`] = ` +Object { + "useHistory": [Function], + "useLocation": [Function], + "useParams": [Function], + "useRouteMatch": [Function], +} +`; diff --git a/src/hooks/__tests__/useRouter.test.js b/src/hooks/__tests__/useRouter.test.js new file mode 100644 index 000000000..f4cad2d22 --- /dev/null +++ b/src/hooks/__tests__/useRouter.test.js @@ -0,0 +1,24 @@ +import { routerHooks } from '../useRouter'; + +describe('useRouter', () => { + it('should return specific properties', () => { + expect(routerHooks).toMatchSnapshot('specific properties'); + }); + + it('should apply a hook for useHistory', () => { + const mockDispatch = jest.fn(); + const mockHistoryPush = jest.fn(); + const mockUseHistory = mockHook(() => + routerHooks.useHistory({ + useDispatch: () => action => action(mockDispatch), + useHistory: () => ({ push: mockHistoryPush }) + }) + ); + + mockUseHistory.push('rhel'); + expect(mockDispatch.mock.calls).toMatchSnapshot('push, config route'); + + mockUseHistory.push('/lorem/ipsum'); + expect(mockHistoryPush.mock.calls).toMatchSnapshot('push, unique route'); + }); +}); diff --git a/src/hooks/useRouter.js b/src/hooks/useRouter.js new file mode 100644 index 000000000..41848e6be --- /dev/null +++ b/src/hooks/useRouter.js @@ -0,0 +1,49 @@ +import { useHistory as useHistoryRRD, useLocation, useParams, useRouteMatch } from 'react-router-dom'; +import { routerHelpers } from '../components/router/routerHelpers'; +import { reduxActions, useDispatch } from '../redux'; +import { helpers } from '../common/helpers'; + +/** + * ToDo: reevaluate this alternative pattern of passing library hooks as options + * We did this as a test to see if its more convenient for unit testing instead of + * having to spy or mock entire resources. + */ +/** + * Pass useHistory methods. Proxy useHistory push with Platform specific navigation update. + * + * @param {object} hooks + * @param {Function} hooks.useHistory + * @param {Function} hooks.useDispatch + * @returns {object} + */ +const useHistory = ({ + useHistory: useAliasHistory = useHistoryRRD, + useDispatch: useAliasDispatch = useDispatch +} = {}) => { + const history = useAliasHistory(); + const dispatch = useAliasDispatch(); + + return { + ...history, + push: (pathLocation, historyState) => { + const pathName = (typeof pathLocation === 'string' && pathLocation) || pathLocation?.pathname; + const { productParameter, id, routeHref } = routerHelpers.getRouteConfig({ pathName, id: pathName }); + const { hash, search } = window.location; + + if (!helpers.DEV_MODE && productParameter) { + return dispatch(reduxActions.platform.setAppNav(id)); + } + + return history.push(routeHref || (pathName && `${pathName}${search}${hash}`) || pathLocation, historyState); + } + }; +}; + +const routerHooks = { + useHistory, + useLocation, + useParams, + useRouteMatch +}; + +export { routerHooks as default, routerHooks, useHistory, useLocation, useParams, useRouteMatch }; diff --git a/src/index.js b/src/index.js index cb6ca6027..dd54f291f 100644 --- a/src/index.js +++ b/src/index.js @@ -2,7 +2,7 @@ import React from 'react'; import { render } from 'react-dom'; import { Provider } from 'react-redux'; import { BrowserRouter } from 'react-router-dom'; -import { baseName } from './components/router/routerHelpers'; +import { routerHelpers } from './components/router'; import { store } from './redux'; import App from './components/app'; import './styles/index.scss'; @@ -10,7 +10,7 @@ import '@patternfly/react-styles/css/components/Select/select.css'; render( - + , diff --git a/src/redux/actions/__tests__/__snapshots__/platformActions.test.js.snap b/src/redux/actions/__tests__/__snapshots__/platformActions.test.js.snap index 8cc2f40ab..30d446d7f 100644 --- a/src/redux/actions/__tests__/__snapshots__/platformActions.test.js.snap +++ b/src/redux/actions/__tests__/__snapshots__/platformActions.test.js.snap @@ -30,17 +30,16 @@ exports[`PlatformActions Should return a function for the onNavigation method: e exports[`PlatformActions Should return a function for the onNavigation method: function 1`] = `[Function]`; -exports[`PlatformActions Should return a function for the setNavigation method: expected process 1`] = ` -Array [ - Object { - "active": false, +exports[`PlatformActions Should return a function for the setAppNav method: expected process 1`] = ` +Object { + "meta": Object { + "appName": undefined, "id": "lorem", + "secondaryNav": undefined, }, - Object { - "active": false, - "id": "ipsum", - }, -] + "payload": Promise {}, + "type": "PLATFORM_SET_NAV", +} `; -exports[`PlatformActions Should return a function for the setNavigation method: function 1`] = `[Function]`; +exports[`PlatformActions Should return a function for the setAppNav method: function 1`] = `[Function]`; diff --git a/src/redux/actions/__tests__/platformActions.test.js b/src/redux/actions/__tests__/platformActions.test.js index c3d0fc105..ab7660ab9 100644 --- a/src/redux/actions/__tests__/platformActions.test.js +++ b/src/redux/actions/__tests__/platformActions.test.js @@ -21,13 +21,11 @@ describe('PlatformActions', () => { expect(platformActions.setAppName()).toMatchSnapshot('dispatch object'); }); - it('Should return a function for the setNavigation method', () => { - expect(platformActions.setNavigation()).toMatchSnapshot('function'); + it('Should return a function for the setAppNav method', () => { + expect(platformActions.setAppNav()).toMatchSnapshot('function'); window.insights.chrome.navigation = jest.fn().mockImplementation(value => value); const dispatch = obj => obj; - expect(platformActions.setNavigation([{ id: 'lorem' }, { id: 'ipsum' }])(dispatch)).toMatchSnapshot( - 'expected process' - ); + expect(platformActions.setAppNav('lorem')(dispatch)).toMatchSnapshot('expected process'); }); }); diff --git a/src/redux/actions/platformActions.js b/src/redux/actions/platformActions.js index 16c90333e..9445209ee 100644 --- a/src/redux/actions/platformActions.js +++ b/src/redux/actions/platformActions.js @@ -78,17 +78,24 @@ const setAppName = name => ({ }); /** - * Apply platform method for handling the left-nav navigation active item. + * Apply platform method for changing routes via the left-nav navigation. * - * @param {object} data + * @param {string} id + * @param {object} options + * @param {string} options.appName + * @param {boolean} options.secondaryNav * @returns {Function} */ -const setNavigation = data => dispatch => { +const setAppNav = (id, { appName, secondaryNav } = {}) => dispatch => dispatch({ - type: platformTypes.PLATFORM_SET_NAV + type: platformTypes.PLATFORM_SET_NAV, + payload: platformServices.setAppNav(id, { appName, secondaryNav }), + meta: { + id, + appName, + secondaryNav + } }); - return platformServices.setNavigation(data); -}; const platformActions = { addNotification, @@ -98,7 +105,7 @@ const platformActions = { initializeChrome, onNavigation, setAppName, - setNavigation + setAppNav }; export { @@ -111,5 +118,5 @@ export { initializeChrome, onNavigation, setAppName, - setNavigation + setAppNav }; diff --git a/src/redux/reducers/viewReducer.js b/src/redux/reducers/viewReducer.js index 4669c96f0..4e0cfe036 100644 --- a/src/redux/reducers/viewReducer.js +++ b/src/redux/reducers/viewReducer.js @@ -1,4 +1,4 @@ -import { routerConfig } from '../../components/router/routerConfig'; +import { routerHelpers } from '../../components/router'; import { reduxTypes } from '../types'; import { reduxHelpers } from '../common/reduxHelpers'; import { RHSM_API_QUERY_TYPES } from '../../types/rhsmApiTypes'; @@ -29,7 +29,7 @@ const viewReducer = (state = initialState, action) => { switch (action.type) { case reduxTypes.query.SET_QUERY_RESET_INVENTORY_LIST: const updateResetQueries = (query = {}, id) => { - const queryIds = routerConfig.productGroups[id] || (query[id] && [id]) || []; + const queryIds = routerHelpers.productGroups[id] || (query[id] && [id]) || []; const updatedQuery = { ...query }; queryIds.forEach(queryId => { @@ -60,7 +60,7 @@ const viewReducer = (state = initialState, action) => { ); case reduxTypes.query.SET_QUERY_CLEAR_INVENTORY_LIST: const updateClearQueries = (query = {}, id) => { - const queryIds = routerConfig.productGroups[id] || (query[id] && [id]) || []; + const queryIds = routerHelpers.productGroups[id] || (query[id] && [id]) || []; const updatedQuery = { ...query }; queryIds.forEach(queryId => { diff --git a/src/redux/selectors/__tests__/__snapshots__/graphCardSelectors.test.js.snap b/src/redux/selectors/__tests__/__snapshots__/graphCardSelectors.test.js.snap index 42cdd8a47..585cd688a 100644 --- a/src/redux/selectors/__tests__/__snapshots__/graphCardSelectors.test.js.snap +++ b/src/redux/selectors/__tests__/__snapshots__/graphCardSelectors.test.js.snap @@ -5,6 +5,7 @@ Object { "error": false, "fulfilled": false, "graphData": Object {}, + "meta": Object {}, "pending": true, "query": Object { "granularity": "daily", @@ -459,6 +460,10 @@ Object { }, ], }, + "meta": Object { + "count": undefined, + "totalCoreHours": undefined, + }, "pending": false, "query": Object { "granularity": "daily", @@ -472,6 +477,7 @@ Object { "error": false, "fulfilled": false, "graphData": Object {}, + "meta": Object {}, "pending": false, "query": Object { "granularity": "daily", @@ -485,6 +491,7 @@ Object { "error": false, "fulfilled": false, "graphData": Object {}, + "meta": Object {}, "pending": false, "query": Object {}, "status": undefined, @@ -496,6 +503,7 @@ Object { "error": false, "fulfilled": false, "graphData": Object {}, + "meta": Object {}, "pending": false, "query": Object {}, "status": undefined, @@ -680,6 +688,10 @@ Object { }, ], }, + "meta": Object { + "count": undefined, + "totalCoreHours": undefined, + }, "pending": false, "query": Object { "granularity": "daily", @@ -866,6 +878,10 @@ Object { }, ], }, + "meta": Object { + "count": undefined, + "totalCoreHours": undefined, + }, "pending": false, "query": Object { "granularity": "daily", @@ -1052,6 +1068,10 @@ Object { }, ], }, + "meta": Object { + "count": undefined, + "totalCoreHours": undefined, + }, "pending": false, "query": Object { "granularity": "daily", @@ -1238,6 +1258,10 @@ Object { }, ], }, + "meta": Object { + "count": undefined, + "totalCoreHours": undefined, + }, "pending": false, "query": Object { "granularity": "daily", @@ -1790,6 +1814,10 @@ Object { }, ], }, + "meta": Object { + "count": undefined, + "totalCoreHours": undefined, + }, "pending": false, "query": Object { "granularity": "daily", @@ -2022,6 +2050,10 @@ Object { }, ], }, + "meta": Object { + "count": undefined, + "totalCoreHours": undefined, + }, "pending": false, "query": Object { "granularity": "daily", diff --git a/src/redux/selectors/graphCardSelectors.js b/src/redux/selectors/graphCardSelectors.js index c26bafbe2..cafe385f6 100644 --- a/src/redux/selectors/graphCardSelectors.js +++ b/src/redux/selectors/graphCardSelectors.js @@ -71,6 +71,7 @@ const selector = createSelector([statePropsFilter, queryFilter], (response, quer fulfilled: false, pending: responseData.pending || responseData.cancelled || false, graphData: {}, + meta: {}, query, status: responseData.status }; @@ -85,6 +86,7 @@ const selector = createSelector([statePropsFilter, queryFilter], (response, quer if (responseData.fulfilled && productId === metaId && _isEqual(query, responseMetaQuery)) { const [report, capacity] = responseData.data; const reportData = report?.[rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA] || []; + const reportMeta = report?.[rhsmApiTypes.RHSM_API_RESPONSE_META] || {}; const capacityData = capacity?.[rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA] || []; /** @@ -171,7 +173,16 @@ const selector = createSelector([statePropsFilter, queryFilter], (response, quer }); }); + // Generate normalized properties + const [updatedReportMeta] = reduxHelpers.setNormalizedResponse({ + schema: rhsmApiTypes.RHSM_API_RESPONSE_META_TYPES, + data: reportMeta + }); + + const [meta = {}] = updatedReportMeta || []; + // Update response and cache + Object.assign(updatedResponseData.meta, meta); updatedResponseData.fulfilled = true; selectorCache.set(`${viewId}_${productId}_${JSON.stringify(query)}`, { ...updatedResponseData }); } diff --git a/src/redux/selectors/userSelectors.js b/src/redux/selectors/userSelectors.js index 56ed52b04..2001f4ae1 100644 --- a/src/redux/selectors/userSelectors.js +++ b/src/redux/selectors/userSelectors.js @@ -1,6 +1,6 @@ import { createSelectorCreator, defaultMemoize } from 'reselect'; import _isEqual from 'lodash/isEqual'; -import permissions from '../../config/rbac'; +import { rbacConfig as permissions } from '../../config'; import { platformApiTypes, PLATFORM_API_RESPONSE_USER_PERMISSION_APP_TYPES as APP_TYPES, diff --git a/src/services/__tests__/__snapshots__/platformServices.test.js.snap b/src/services/__tests__/__snapshots__/platformServices.test.js.snap index 48a51c68c..5662831af 100644 --- a/src/services/__tests__/__snapshots__/platformServices.test.js.snap +++ b/src/services/__tests__/__snapshots__/platformServices.test.js.snap @@ -8,6 +8,8 @@ exports[`PlatformServices should return a failed initializeChrome: failed initia exports[`PlatformServices should return a failed setAppName: failed setAppName 1`] = `"{ identifyApp } = insights.chrome, insights.chrome.identifyApp is not a function"`; +exports[`PlatformServices should return a failed setAppNav: failed setAppNav 1`] = `[Error: { appNavClick } = insights.chrome, insights.chrome.appNavClick is not a function]`; + exports[`PlatformServices should return a successful getUser with a specific response: specific success for authorized user 1`] = `"lorem ipsum"`; exports[`PlatformServices should return a successful getUser: success authorized user 1`] = ` diff --git a/src/services/__tests__/platformServices.test.js b/src/services/__tests__/platformServices.test.js index 56c0137b2..102dea74d 100644 --- a/src/services/__tests__/platformServices.test.js +++ b/src/services/__tests__/platformServices.test.js @@ -25,7 +25,7 @@ describe('PlatformServices', () => { expect(platformServices.initializeChrome).toBeDefined(); expect(platformServices.onNavigation).toBeDefined(); expect(platformServices.setAppName).toBeDefined(); - expect(platformServices.setNavigation).toBeDefined(); + expect(platformServices.setAppNav).toBeDefined(); }); /** @@ -95,10 +95,10 @@ describe('PlatformServices', () => { expect(response).toMatchSnapshot('failed setAppName'); }); - it('should return a failed setNavigation', () => { - window.insights.chrome.navigation = undefined; - expect(platformServices.setNavigation).toThrowError( - '{ navigation } = insights.chrome, insights.chrome.navigation is not a function' - ); + it('should return a failed setAppNav', async () => { + window.insights.chrome.appNavClick = undefined; + const response = await returnPromiseAsync(platformServices.setAppNav); + + expect(response).toMatchSnapshot('failed setAppNav'); }); }); diff --git a/src/services/platformServices.js b/src/services/platformServices.js index 27dbff1d0..a995e54fe 100644 --- a/src/services/platformServices.js +++ b/src/services/platformServices.js @@ -122,24 +122,24 @@ const setAppName = async (name = null) => { } }; -// ToDo: Clean up, consider removing setNavigation, currently no longer used. /** - * Set platform left hand navigation active item. + * Set app routes via the platform left-nav navigation. * - * @param {Array} data - * @returns {*} + * @param {string} id The navigation ID associated with internal route config, and external platform nav config + * @param {object} options + * @param {string} options.appName + * @param {boolean} options.secondaryNav + * @returns {Promise} */ -const setNavigation = (data = []) => { - const { insights, location } = window; +const setAppNav = async (id, { appName = helpers.UI_NAME, secondaryNav = true } = {}) => { + const { insights } = window; try { - return insights.chrome.navigation( - data.map(item => ({ - ...item, - active: item.id === location.pathname.split('/').slice(-1)[0] - })) + return ( + (helpers.DEV_MODE && { [platformApiTypes.PLATFORM_API_RESPONSE_NAV_TYPES.ACTIVE_APP]: id }) || + (await insights.chrome.appNavClick({ id, secondaryNav, parentId: appName })) ); } catch (e) { - throw new Error(`{ navigation } = insights.chrome, ${e.message}`); + throw new Error(`{ appNavClick } = insights.chrome, ${e.message}`); } }; @@ -150,7 +150,7 @@ const platformServices = { initializeChrome, onNavigation, setAppName, - setNavigation + setAppNav }; export { @@ -162,5 +162,5 @@ export { initializeChrome, onNavigation, setAppName, - setNavigation + setAppNav }; diff --git a/src/services/rhsmServices.js b/src/services/rhsmServices.js index b6b7eb22a..69416f624 100644 --- a/src/services/rhsmServices.js +++ b/src/services/rhsmServices.js @@ -380,7 +380,8 @@ const getApiVersion = (options = {}) => { * "meta": { * "count": 12, * "product": "RHEL", - * "granularity": "daily" + * "granularity": "daily", + * "total_core_hours": 30500.04 * } * } * @@ -504,7 +505,8 @@ const getApiVersion = (options = {}) => { * "meta": { * "count": 10, * "product": "RHEL", - * "granularity": "weekly" + * "granularity": "weekly", + * "total_core_hours": 200.03 * } * } * @@ -631,7 +633,8 @@ const getApiVersion = (options = {}) => { * "meta": { * "count": 6, * "product": "RHEL", - * "granularity": "monthly" + * "granularity": "monthly", + * "total_core_hours": 2050.04 * } * } * diff --git a/src/services/userServices.js b/src/services/userServices.js index adf315283..8c82d8dc8 100644 --- a/src/services/userServices.js +++ b/src/services/userServices.js @@ -1,7 +1,7 @@ import Cookies from 'js-cookie'; import LocaleCode from 'locale-code'; import _isPlainObject from 'lodash/isPlainObject'; -import permissions from '../config/rbac'; +import { rbacConfig as permissions } from '../config'; import { getUser, getUserPermissions } from './platformServices'; import { serviceCall } from './config'; import { helpers } from '../common'; diff --git a/src/setupTests.js b/src/setupTests.js index 49458dc36..d5c04ad4b 100644 --- a/src/setupTests.js +++ b/src/setupTests.js @@ -1,5 +1,7 @@ -import { configure } from 'enzyme'; +import React from 'react'; +import { configure, mount, shallow } from 'enzyme'; import Adapter from '@wojtekmaj/enzyme-adapter-react-17'; +import { act } from 'react-dom/test-utils'; import * as pfReactCoreComponents from '@patternfly/react-core'; import * as pfReactChartComponents from '@patternfly/react-charts'; @@ -17,13 +19,11 @@ jest.mock('i18next', () => { return new Test(); }); -jest.mock('lodash/debounce', () => jest.fn); - /** - * FixMe: Use of arrow functions removes the usefulness of the "displayName" when shallow rendering - * PF appears to have updated components with a "displayName". Because we potentially have internal - * components, and other resources that are missing "displayName". We're leaving this test helper active. + * Emulate for component checks */ +jest.mock('lodash/debounce', () => jest.fn); + /** * Add the displayName property to function based components. Makes sure that snapshot tests have named components * instead of displaying a generic "". @@ -42,8 +42,15 @@ const addDisplayName = components => { addDisplayName(pfReactCoreComponents); addDisplayName(pfReactChartComponents); +/** + * Apply a global insights chroming object. + * + * @type {{chrome: {init: Function, navigation: Function, auth: {getUser: Function}, identifyApp: Function, + * getUserPermissions: Function, isBeta: Function, hideGlobalFilter: Function, on: Function}}} + */ global.window.insights = { chrome: { + appNavClick: Function.prototype, auth: { getUser: () => new Promise(resolve => @@ -60,11 +67,73 @@ global.window.insights = { identifyApp: Function.prototype, init: Function.prototype, isBeta: Function.prototype, - navigation: Function.prototype, on: Function.prototype } }; +/** + * Enzyme for components using hooks. + * + * @param {Node} component + * @param {object} options + * + * @returns {Promise} + */ +global.mountHookComponent = async (component, options = {}) => { + let mountedComponent = null; + await act(async () => { + mountedComponent = mount(component, options); + }); + mountedComponent?.update(); + return mountedComponent; +}; + +/** + * Fire a hook, return the result. + * + * @param {Function} useHook + * @returns {*} + */ +global.mockHook = (useHook = Function.prototype) => { + let result; + const Hook = () => { + result = useHook(); + return null; + }; + shallow(); + return result; +}; + +/** + * Generate a mock window location object, allow async. + * + * @param {Function} callback + * @param {object} options + * @param {string} options.url + * @param {object} options.location + * @returns {Promise} + */ +global.mockWindowLocation = async ( + callback = Function.prototype, + { url = 'https://ci.foo.redhat.com/subscriptions/rhel', location: locationProps = {} } = {} +) => { + const updatedUrl = new URL(url); + const { location } = window; + delete window.location; + // mock + window.location = { + href: updatedUrl.href, + search: updatedUrl.search, + hash: updatedUrl.hash, + pathname: updatedUrl.pathname, + replace: Function.prototype, + ...locationProps + }; + await callback(window.location); + // restore + window.location = location; +}; + /* * For applying a global Jest "beforeAll", based on * jest-prop-type-error, https://www.npmjs.com/package/jest-prop-type-error @@ -77,6 +146,8 @@ beforeAll(() => { throw new Error(message); } - error.apply(console, [message, ...args]); + if (!/(Not implemented: navigation)/gi.test(message)) { + error.apply(console, [message, ...args]); + } }; }); diff --git a/src/types/__tests__/__snapshots__/index.test.js.snap b/src/types/__tests__/__snapshots__/index.test.js.snap index 423cd1e19..afbf15f00 100644 --- a/src/types/__tests__/__snapshots__/index.test.js.snap +++ b/src/types/__tests__/__snapshots__/index.test.js.snap @@ -4,6 +4,9 @@ exports[`ApiTypes should have specific API properties: all exported api types 1` Object { "apiTypes": Object { "platformApi": Object { + "PLATFORM_API_RESPONSE_NAV_TYPES": Object { + "ACTIVE_APP": "activeApp", + }, "PLATFORM_API_RESPONSE_USER_ENTITLEMENTS": "entitlements", "PLATFORM_API_RESPONSE_USER_ENTITLEMENTS_APP_TYPES": Object { "ENTITLED": "is_entitled", @@ -218,6 +221,7 @@ Object { "RHSM_API_RESPONSE_META": "meta", "RHSM_API_RESPONSE_META_TYPES": Object { "COUNT": "count", + "TOTAL_CORE_HOURS": "total_core_hours", }, "RHSM_API_RESPONSE_PRODUCTS_DATA": "data", "RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES": Object { @@ -240,6 +244,9 @@ Object { }, "default": Object { "platformApi": Object { + "PLATFORM_API_RESPONSE_NAV_TYPES": Object { + "ACTIVE_APP": "activeApp", + }, "PLATFORM_API_RESPONSE_USER_ENTITLEMENTS": "entitlements", "PLATFORM_API_RESPONSE_USER_ENTITLEMENTS_APP_TYPES": Object { "ENTITLED": "is_entitled", @@ -454,6 +461,7 @@ Object { "RHSM_API_RESPONSE_META": "meta", "RHSM_API_RESPONSE_META_TYPES": Object { "COUNT": "count", + "TOTAL_CORE_HOURS": "total_core_hours", }, "RHSM_API_RESPONSE_PRODUCTS_DATA": "data", "RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES": Object { @@ -475,6 +483,9 @@ Object { }, }, "platformApiTypes": Object { + "PLATFORM_API_RESPONSE_NAV_TYPES": Object { + "ACTIVE_APP": "activeApp", + }, "PLATFORM_API_RESPONSE_USER_ENTITLEMENTS": "entitlements", "PLATFORM_API_RESPONSE_USER_ENTITLEMENTS_APP_TYPES": Object { "ENTITLED": "is_entitled", @@ -689,6 +700,7 @@ Object { "RHSM_API_RESPONSE_META": "meta", "RHSM_API_RESPONSE_META_TYPES": Object { "COUNT": "count", + "TOTAL_CORE_HOURS": "total_core_hours", }, "RHSM_API_RESPONSE_PRODUCTS_DATA": "data", "RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES": Object { @@ -714,6 +726,9 @@ Object { exports[`ApiTypes should have specific API properties: specific types 1`] = ` Object { "platformApi": Object { + "PLATFORM_API_RESPONSE_NAV_TYPES": Object { + "ACTIVE_APP": "activeApp", + }, "PLATFORM_API_RESPONSE_USER_ENTITLEMENTS": "entitlements", "PLATFORM_API_RESPONSE_USER_ENTITLEMENTS_APP_TYPES": Object { "ENTITLED": "is_entitled", @@ -928,6 +943,7 @@ Object { "RHSM_API_RESPONSE_META": "meta", "RHSM_API_RESPONSE_META_TYPES": Object { "COUNT": "count", + "TOTAL_CORE_HOURS": "total_core_hours", }, "RHSM_API_RESPONSE_PRODUCTS_DATA": "data", "RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES": Object { diff --git a/src/types/platformApiTypes.js b/src/types/platformApiTypes.js index 07fba9023..9ef235fd6 100644 --- a/src/types/platformApiTypes.js +++ b/src/types/platformApiTypes.js @@ -1,3 +1,12 @@ +/** + * Platform response for appNavClick. + * + * @type {{ACTIVE_APP: string}} + */ +const PLATFORM_API_RESPONSE_NAV_TYPES = { + ACTIVE_APP: 'activeApp' +}; + /** * Platform response entitlements type. * @@ -76,6 +85,7 @@ const PLATFORM_API_RESPONSE_USER_PERMISSION_OPERATION_TYPES = { * PLATFORM_API_RESPONSE_USER_IDENTITY_USER_TYPES: {ORG_ADMIN: string}}} */ const platformApiTypes = { + PLATFORM_API_RESPONSE_NAV_TYPES, PLATFORM_API_RESPONSE_USER_ENTITLEMENTS, PLATFORM_API_RESPONSE_USER_ENTITLEMENTS_APP_TYPES, PLATFORM_API_RESPONSE_USER_IDENTITY, @@ -90,6 +100,7 @@ const platformApiTypes = { export { platformApiTypes as default, platformApiTypes, + PLATFORM_API_RESPONSE_NAV_TYPES, PLATFORM_API_RESPONSE_USER_ENTITLEMENTS, PLATFORM_API_RESPONSE_USER_ENTITLEMENTS_APP_TYPES, PLATFORM_API_RESPONSE_USER_IDENTITY, diff --git a/src/types/rhsmApiTypes.js b/src/types/rhsmApiTypes.js index c8cb577d9..62c3c26cb 100644 --- a/src/types/rhsmApiTypes.js +++ b/src/types/rhsmApiTypes.js @@ -57,10 +57,11 @@ const RHSM_API_RESPONSE_META = 'meta'; * RHSM response META types. * Schema/map of expected META response properties. * - * @type {string} + * @type {{COUNT: string, TOTAL_CORE_HOURS: string}} */ const RHSM_API_RESPONSE_META_TYPES = { - COUNT: 'count' + COUNT: 'count', + TOTAL_CORE_HOURS: 'total_core_hours' }; /** @@ -386,35 +387,35 @@ const RHSM_API_QUERY_TYPES = { /** * RHSM API types. * - * @type {{RHSM_API_QUERY_SET_INVENTORY_SUBSCRIPTIONS_TYPES: {UOM: string, USAGE: string, DIRECTION: string, SORT: string, - * OFFSET: string, SLA: string, LIMIT: string}, RHSM_API_RESPONSE_INVENTORY_SUBSCRIPTIONS_DATA_TYPES: {UOM: string, - * PHYSICAL_CAPACITY: string, USAGE: string, UPCOMING_EVENT_TYPE: string, UPCOMING_EVENT_DATE: string, - * SUBSCRIPTION_NUMBERS: string, VIRTUAL_CAPACITY: string, TOTAL_CAPACITY: string, SKU: string, SERVICE_LEVEL: string}, + * @type {{RHSM_API_QUERY_SET_INVENTORY_SUBSCRIPTIONS_TYPES: {UOM: string, USAGE: string, DIRECTION: string, + * SORT: string, OFFSET: string, SLA: string, LIMIT: string}, + * RHSM_API_RESPONSE_INVENTORY_SUBSCRIPTIONS_DATA_TYPES: {UOM: string, PHYSICAL_CAPACITY: string, USAGE: string, + * UPCOMING_EVENT_TYPE: string, UPCOMING_EVENT_DATE: string, SUBSCRIPTION_NUMBERS: string, + * VIRTUAL_CAPACITY: string, TOTAL_CAPACITY: string, SKU: string, SERVICE_LEVEL: string}, * RHSM_API_RESPONSE_ERROR_DATA_CODE_TYPES: {GENERIC: string, OPTIN: string}, RHSM_API_RESPONSE_INVENTORY_DATA: string, * RHSM_API_RESPONSE_CAPACITY_DATA: string, RHSM_API_RESPONSE_ERROR_DATA_TYPES: {CODE: string, DETAIL: string}, * RHSM_API_RESPONSE_CAPACITY_DATA_TYPES: {HYPERVISOR_SOCKETS: string, CORES: string, DATE: string, SOCKETS: string, * PHYSICAL_SOCKETS: string, HYPERVISOR_CORES: string, HAS_INFINITE: string, PHYSICAL_CORES: string}, - * RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES: {UOM: string, PHYSICAL_CAPACITY: string, USAGE: string, - * UPCOMING_EVENT_DATE: string, VIRTUAL_CAPACITY: string, TOTAL_CAPACITY: string, SKU: string, PRODUCT_NAME: string, - * SERVICE_LEVEL: string}, RHSM_API_RESPONSE_META_TYPES: string, RHSM_API_QUERY_GRANULARITY_TYPES: {WEEKLY: string, - * QUARTERLY: string, DAILY: string, MONTHLY: string}, RHSM_API_QUERY_SORT_DIRECTION_TYPES: {ASCENDING: string, - * DESCENDING: string}, RHSM_API_RESPONSE_PRODUCTS_DATA: string, RHSM_API_QUERY_TYPES: {GRANULARITY: string, - * TALLY_SYNC: string, DIRECTION: string, END_DATE: string, SLA: string, START_DATE: string, LIMIT: string, UOM: string, - * TALLY_REPORT: string, USAGE: string, SORT: string, OFFSET: string, CONDUIT_SYNC: string}, - * RHSM_API_RESPONSE_LINKS: string, RHSM_API_QUERY_SET_INVENTORY_GUESTS_TYPES: {OFFSET: string, LIMIT: string}, - * RHSM_API_PATH_ID_TYPES: {RHEL_ARM: string, OPENSHIFT_METRICS: string, SATELLITE: string, RHEL_WORKSTATION: string, - * RHEL_COMPUTE_NODE: string, RHEL_X86: string, OPENSHIFT: string, SATELLITE_SERVER: string, - * OPENSHIFT_DEDICATED_METRICS: string, RHEL_DESKTOP: string, RHEL: string, SATELLITE_CAPSULE: string, RHEL_SERVER: string, - * RHEL_IBM_Z: string, RHEL_IBM_POWER: string}, RHSM_API_QUERY_SET_OPTIN_TYPES: {TALLY_SYNC: string, TALLY_REPORT: string, - * CONDUIT_SYNC: string}, RHSM_API_QUERY_USAGE_TYPES: {UNSPECIFIED: string, DISASTER: string, DEVELOPMENT: string, - * PRODUCTION: string}, RHSM_API_QUERY_SLA_TYPES: {PREMIUM: string, SELF: string, NONE: string, STANDARD: string}, - * RHSM_API_QUERY_SET_INVENTORY_TYPES: {UOM: string, USAGE: string, DIRECTION: string, SORT: string, OFFSET: string, - * SLA: string, LIMIT: string}, RHSM_API_QUERY_SORT_TYPES: {CORES: string, CORE_HOURS: string, HARDWARE: string, - * SOCKETS: string, MEASUREMENT: string, LAST_SEEN: string, NAME: string}, - * RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES: {HYPERVISOR_SOCKETS: string, CORES: string, SOCKETS: string, - * CLOUD_CORES: string, HAS_DATA: string, PHYSICAL_SOCKETS: string, PHYSICAL_CORES: string, CLOUD_INSTANCES: string, - * DATE: string, CORE_HOURS: string, CLOUD_SOCKETS: string, HAS_CLOUDIGRADE_DATA: string, HAS_CLOUDIGRADE_MISMATCH: string, - * HYPERVISOR_CORES: string}, RHSM_API_QUERY_UOM_TYPES: {CORES: string, SOCKETS: string}, + * RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES: {UOM: string, PHYSICAL_CAPACITY: string, USAGE: string, UPCOMING_EVENT_DATE: string, + * VIRTUAL_CAPACITY: string, TOTAL_CAPACITY: string, SKU: string, PRODUCT_NAME: string, SERVICE_LEVEL: string}, + * RHSM_API_RESPONSE_META_TYPES: {COUNT: string, TOTAL_CORE_HOURS: string}, RHSM_API_QUERY_GRANULARITY_TYPES: {WEEKLY: string, + * QUARTERLY: string, DAILY: string, MONTHLY: string}, RHSM_API_QUERY_SORT_DIRECTION_TYPES: {ASCENDING: string, DESCENDING: string}, + * RHSM_API_RESPONSE_PRODUCTS_DATA: string, RHSM_API_QUERY_TYPES: {GRANULARITY: string, TALLY_SYNC: string, DIRECTION: string, + * END_DATE: string, SLA: string, START_DATE: string, LIMIT: string, UOM: string, TALLY_REPORT: string, USAGE: string, + * SORT: string, OFFSET: string, CONDUIT_SYNC: string}, RHSM_API_RESPONSE_LINKS: string, + * RHSM_API_QUERY_SET_INVENTORY_GUESTS_TYPES: {OFFSET: string, LIMIT: string}, RHSM_API_PATH_ID_TYPES: {RHEL_ARM: string, + * OPENSHIFT_METRICS: string, SATELLITE: string, RHEL_WORKSTATION: string, RHEL_COMPUTE_NODE: string, RHEL_X86: string, + * OPENSHIFT: string, SATELLITE_SERVER: string, OPENSHIFT_DEDICATED_METRICS: string, RHEL_DESKTOP: string, RHEL: string, + * SATELLITE_CAPSULE: string, RHEL_SERVER: string, RHEL_IBM_Z: string, RHEL_IBM_POWER: string}, + * RHSM_API_QUERY_SET_OPTIN_TYPES: {TALLY_SYNC: string, TALLY_REPORT: string, CONDUIT_SYNC: string}, + * RHSM_API_QUERY_USAGE_TYPES: {UNSPECIFIED: string, DISASTER: string, DEVELOPMENT: string, PRODUCTION: string}, + * RHSM_API_QUERY_SLA_TYPES: {PREMIUM: string, SELF: string, NONE: string, STANDARD: string}, + * RHSM_API_QUERY_SET_INVENTORY_TYPES: {UOM: string, USAGE: string, DIRECTION: string, SORT: string, OFFSET: string, SLA: string, + * LIMIT: string}, RHSM_API_QUERY_SORT_TYPES: {CORES: string, CORE_HOURS: string, HARDWARE: string, SOCKETS: string, + * MEASUREMENT: string, LAST_SEEN: string, NAME: string}, RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES: {HYPERVISOR_SOCKETS: string, + * CORES: string, SOCKETS: string, CLOUD_CORES: string, HAS_DATA: string, PHYSICAL_SOCKETS: string, PHYSICAL_CORES: string, + * CLOUD_INSTANCES: string, DATE: string, CORE_HOURS: string, CLOUD_SOCKETS: string, HAS_CLOUDIGRADE_DATA: string, + * HAS_CLOUDIGRADE_MISMATCH: string, HYPERVISOR_CORES: string}, RHSM_API_QUERY_UOM_TYPES: {CORES: string, SOCKETS: string}, * RHSM_API_RESPONSE_LINKS_TYPES: string, RHSM_API_RESPONSE_INVENTORY_GUESTS_DATA_TYPES: {SUBSCRIPTION_ID: string, ID: string, * NAME: string, LAST_SEEN: string}, RHSM_API_RESPONSE_ERROR_DATA: string, RHSM_API_RESPONSE_META: string, * RHSM_API_RESPONSE_INVENTORY_DATA_TYPES: {CORES: string, CORE_HOURS: string, HARDWARE: string, SOCKETS: string, diff --git a/tests/__snapshots__/code.test.js.snap b/tests/__snapshots__/code.test.js.snap index a3752bd68..1fd6f4a83 100644 --- a/tests/__snapshots__/code.test.js.snap +++ b/tests/__snapshots__/code.test.js.snap @@ -6,6 +6,6 @@ Array [ "components/inventorySubscriptions/inventorySubscriptions.js:60: console.warn(\`Sorting can only be performed on select fields, confirm field \${id} is allowed.\`);", "redux/common/reduxHelpers.js:250: console.error(\`Error: Property \${prop} does not exist within the passed state.\`, state);", "redux/common/reduxHelpers.js:254: console.warn(\`Warning: Property \${prop} does not exist within the passed initialState.\`, initialState);", - "setupTests.js:75: console.error = (message, ...args) => {", + "setupTests.js:144: console.error = (message, ...args) => {", ] `; diff --git a/tests/__snapshots__/dist.test.js.snap b/tests/__snapshots__/dist.test.js.snap index 2f917abf0..dcbd45073 100644 --- a/tests/__snapshots__/dist.test.js.snap +++ b/tests/__snapshots__/dist.test.js.snap @@ -7,14 +7,36 @@ Array [ "./build/locales/en-US.json", "./build/locales/en.json", "./build/locales/locales.json", - "./build/static/css/0*chunk*map", - "./build/static/css/0*chunk.css", - "./build/static/css/5*chunk*map", - "./build/static/css/5*chunk.css", - "./build/static/css/6*chunk*map", - "./build/static/css/6*chunk.css", + "./build/static/css/1*chunk*map", + "./build/static/css/1*chunk.css", + "./build/static/css/10*chunk*map", + "./build/static/css/10*chunk.css", + "./build/static/css/11*chunk*map", + "./build/static/css/11*chunk.css", + "./build/static/css/12*chunk*map", + "./build/static/css/12*chunk.css", + "./build/static/css/13*chunk*map", + "./build/static/css/13*chunk.css", + "./build/static/css/15*chunk*map", + "./build/static/css/15*chunk.css", + "./build/static/css/16*chunk*map", + "./build/static/css/16*chunk.css", + "./build/static/css/18*chunk*map", + "./build/static/css/18*chunk.css", + "./build/static/css/19*chunk*map", + "./build/static/css/19*chunk.css", + "./build/static/css/2*chunk*map", + "./build/static/css/2*chunk.css", + "./build/static/css/20*chunk*map", + "./build/static/css/20*chunk.css", + "./build/static/css/4*chunk*map", + "./build/static/css/4*chunk.css", "./build/static/css/7*chunk*map", "./build/static/css/7*chunk.css", + "./build/static/css/8*chunk*map", + "./build/static/css/8*chunk.css", + "./build/static/css/9*chunk*map", + "./build/static/css/9*chunk.css", "./build/static/css/main*chunk*map", "./build/static/css/main*chunk.css", "./build/static/js/0*chunk*map", @@ -25,13 +47,73 @@ Array [ "./build/static/js/10*chunk.js", "./build/static/js/11*chunk*map", "./build/static/js/11*chunk.js", + "./build/static/js/12*chunk*map", + "./build/static/js/12*chunk.js", + "./build/static/js/13*chunk*map", + "./build/static/js/13*chunk.js", + "./build/static/js/14*chunk*map", + "./build/static/js/14*chunk.js", + "./build/static/js/15*chunk*map", + "./build/static/js/15*chunk.js", + "./build/static/js/16*chunk*map", + "./build/static/js/16*chunk.js", + "./build/static/js/17*chunk*map", + "./build/static/js/17*chunk.js", + "./build/static/js/18*chunk*map", + "./build/static/js/18*chunk.js", + "./build/static/js/19*chunk*map", + "./build/static/js/19*chunk.js", "./build/static/js/2*chunk*map", "./build/static/js/2*chunk.js", - "./build/static/js/5*chunk*LICENSE.txt", - "./build/static/js/5*chunk*map", - "./build/static/js/5*chunk.js", - "./build/static/js/6*chunk*map", - "./build/static/js/6*chunk.js", + "./build/static/js/20*chunk*map", + "./build/static/js/20*chunk.js", + "./build/static/js/21*chunk*map", + "./build/static/js/21*chunk.js", + "./build/static/js/22*chunk*map", + "./build/static/js/22*chunk.js", + "./build/static/js/23*chunk*map", + "./build/static/js/23*chunk.js", + "./build/static/js/24*chunk*map", + "./build/static/js/24*chunk.js", + "./build/static/js/25*chunk*map", + "./build/static/js/25*chunk.js", + "./build/static/js/26*chunk*map", + "./build/static/js/26*chunk.js", + "./build/static/js/27*chunk*map", + "./build/static/js/27*chunk.js", + "./build/static/js/28*chunk*map", + "./build/static/js/28*chunk.js", + "./build/static/js/29*chunk*map", + "./build/static/js/29*chunk.js", + "./build/static/js/3*chunk*map", + "./build/static/js/3*chunk.js", + "./build/static/js/30*chunk*map", + "./build/static/js/30*chunk.js", + "./build/static/js/31*chunk*map", + "./build/static/js/31*chunk.js", + "./build/static/js/32*chunk*map", + "./build/static/js/32*chunk.js", + "./build/static/js/33*chunk*map", + "./build/static/js/33*chunk.js", + "./build/static/js/34*chunk*map", + "./build/static/js/34*chunk.js", + "./build/static/js/35*chunk*map", + "./build/static/js/35*chunk.js", + "./build/static/js/36*chunk*map", + "./build/static/js/36*chunk.js", + "./build/static/js/37*chunk*map", + "./build/static/js/37*chunk.js", + "./build/static/js/38*chunk*map", + "./build/static/js/38*chunk.js", + "./build/static/js/39*chunk*map", + "./build/static/js/39*chunk.js", + "./build/static/js/4*chunk*map", + "./build/static/js/4*chunk.js", + "./build/static/js/40*chunk*map", + "./build/static/js/40*chunk.js", + "./build/static/js/41*chunk*map", + "./build/static/js/41*chunk.js", + "./build/static/js/7*chunk*LICENSE.txt", "./build/static/js/7*chunk*map", "./build/static/js/7*chunk.js", "./build/static/js/8*chunk*map", diff --git a/yarn.lock b/yarn.lock index 0aec2001a..cb87c088b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1084,13 +1084,20 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.13.6", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.13.17" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.17.tgz#8966d1fc9593bf848602f0662d6b4d0069e3a7ec" integrity sha512-NCdgJEelPTSh+FEFylhnP1ylq848l1z9t9N0j1Lfbcw0+KXGjsTvUmkxy+voLLXB5SOKMbLLx4jxYliGrYQseA== dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.14.0": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.5.tgz#665450911c6031af38f81db530f387ec04cd9a98" + integrity sha512-121rumjddw9c3NCQ55KGkyE1h/nzWhU/owjhw0l4mQrkzz4x9SGS1X8gFLraHwX7td3Yo4QTL+qj0NcIzN87BA== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.10.4", "@babel/template@^7.12.13", "@babel/template@^7.3.3": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" @@ -1137,50 +1144,50 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@cspell/cspell-bundled-dicts@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-5.4.0.tgz#ef241c9cee00e674fd8ac034bd1dacec77d94f5c" - integrity sha512-aZyml0UaJ2BXmqcrjdMJWyKGQVu33FQ1eRsnV2SZ4WkdkRsxPtdQoFDi+lKSSvIEYSfRkis6lffzwvp0CPQOmw== +"@cspell/cspell-bundled-dicts@^5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-5.6.1.tgz#5b6a07f44a4f74c093e800320b1fc9869b93b2b3" + integrity sha512-u9lEGPU6yL1mdc5xydZELCbxAgPJAtaw74s+HJmKtJodaURYCd3nFZjaWAKEAbpC/q7qB8xW6QfJhafGGLrs0g== dependencies: "@cspell/dict-ada" "^1.1.2" "@cspell/dict-aws" "^1.0.14" - "@cspell/dict-bash" "^1.0.12" - "@cspell/dict-companies" "^1.0.37" - "@cspell/dict-cpp" "^1.1.38" + "@cspell/dict-bash" "^1.0.13" + "@cspell/dict-companies" "^1.0.38" + "@cspell/dict-cpp" "^1.1.39" "@cspell/dict-cryptocurrencies" "^1.0.10" "@cspell/dict-csharp" "^1.0.11" "@cspell/dict-css" "^1.0.11" "@cspell/dict-django" "^1.0.26" "@cspell/dict-dotnet" "^1.0.25" "@cspell/dict-elixir" "^1.0.24" - "@cspell/dict-en-gb" "^1.1.28" - "@cspell/dict-en_us" "^1.2.40" + "@cspell/dict-en-gb" "^1.1.30" + "@cspell/dict-en_us" "^1.2.43" "@cspell/dict-filetypes" "^1.1.5" "@cspell/dict-fonts" "^1.0.14" - "@cspell/dict-fullstack" "^1.0.37" + "@cspell/dict-fullstack" "^1.0.38" "@cspell/dict-golang" "^1.1.24" "@cspell/dict-haskell" "^1.0.13" - "@cspell/dict-html" "^1.1.6" + "@cspell/dict-html" "^1.1.7" "@cspell/dict-html-symbol-entities" "^1.0.23" "@cspell/dict-java" "^1.0.22" "@cspell/dict-latex" "^1.0.25" "@cspell/dict-lorem-ipsum" "^1.0.22" "@cspell/dict-lua" "^1.0.16" - "@cspell/dict-node" "^1.0.11" - "@cspell/dict-npm" "^1.0.11" - "@cspell/dict-php" "^1.0.23" - "@cspell/dict-powershell" "^1.0.14" - "@cspell/dict-python" "^1.0.34" - "@cspell/dict-ruby" "^1.0.13" + "@cspell/dict-node" "^1.0.12" + "@cspell/dict-npm" "^1.0.14" + "@cspell/dict-php" "^1.0.24" + "@cspell/dict-powershell" "^1.0.16" + "@cspell/dict-python" "^1.0.35" + "@cspell/dict-ruby" "^1.0.14" "@cspell/dict-rust" "^1.0.22" "@cspell/dict-scala" "^1.0.21" - "@cspell/dict-software-terms" "^1.0.28" - "@cspell/dict-typescript" "^1.0.17" + "@cspell/dict-software-terms" "^1.0.34" + "@cspell/dict-typescript" "^1.0.19" -"@cspell/cspell-types@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@cspell/cspell-types/-/cspell-types-5.4.0.tgz#af555d9a9c08a75cdd2b38bac259a5127a59cb31" - integrity sha512-mQM+65u0jbTilhj0Mrnufk3jC7dWRymlWdxVK9phLRqtJsDJsxpa0opumVw1CnoBHfPj6HnW7SBGufmcCQp/PQ== +"@cspell/cspell-types@^5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@cspell/cspell-types/-/cspell-types-5.6.1.tgz#946306f2a607b716e46bd18a8dfae7468d20ec38" + integrity sha512-u5yBVyGP3NtUgJ6Mn/F+S57Kgo8QS/bL7ubjn+YNT5F4r4yS8EIMyYIzL2aiifL+V7VjLt2zeZEEuo2oCtA42Q== "@cspell/dict-ada@^1.1.2": version "1.1.2" @@ -1192,20 +1199,20 @@ resolved "https://registry.yarnpkg.com/@cspell/dict-aws/-/dict-aws-1.0.14.tgz#beddede1053ce3622400e36c65da9fd2954e939d" integrity sha512-K21CfB4ZpKYwwDQiPfic2zJA/uxkbsd4IQGejEvDAhE3z8wBs6g6BwwqdVO767M9NgZqc021yAVpr79N5pWe3w== -"@cspell/dict-bash@^1.0.12": - version "1.0.12" - resolved "https://registry.yarnpkg.com/@cspell/dict-bash/-/dict-bash-1.0.12.tgz#fdf828c520dfd274f1cee6a4a90a0f6d86a703ac" - integrity sha512-BOMHVW/m281mqUSJkZ3oiJiUUItLd7QdzpMjm428V9yBYFwIdbds1CeatS7C6kgpI2eBE4RXmy1Hjk/lR63Jew== +"@cspell/dict-bash@^1.0.13": + version "1.0.15" + resolved "https://registry.yarnpkg.com/@cspell/dict-bash/-/dict-bash-1.0.15.tgz#ac70ab1572d9b8d0e3cf7777383b6caa2daad022" + integrity sha512-rY5Bq4RWTgJTioG8vqFbCmnalc/UEM+iBuAZBYvBfT3nU/6SN00Zjyvlh823ir2ODkUryT29CwRYwXcPnuM04w== -"@cspell/dict-companies@^1.0.37": - version "1.0.37" - resolved "https://registry.yarnpkg.com/@cspell/dict-companies/-/dict-companies-1.0.37.tgz#eaaf51c5356e6949071f78f6bc8a32c0dda7ef80" - integrity sha512-7DuwT64u88v0qvvuhHK23zn8zyX7S3lIYj0ntAoMvErr1+O0SuUopZrw4Y1pm1pgcVAv6+ny80RDDhSD1h565w== +"@cspell/dict-companies@^1.0.38": + version "1.0.38" + resolved "https://registry.yarnpkg.com/@cspell/dict-companies/-/dict-companies-1.0.38.tgz#f915ae1e83de7554875350c19e53e91e948679f2" + integrity sha512-5GzatV4gOAvRW8Hz9T90XMN/svRhmzQecE4C7EcSibZkHZC1o3frTFNuzN2eKzvWb0f9xKuhOBcw9+jm8T9BzQ== -"@cspell/dict-cpp@^1.1.38": - version "1.1.38" - resolved "https://registry.yarnpkg.com/@cspell/dict-cpp/-/dict-cpp-1.1.38.tgz#a5723f0827be36463894c12dcf42bd1ff1e27003" - integrity sha512-QqVMxVNYX9XtxzflpJ/888GSyjPU5VeotltsHql1BeEPxhyV27ud9bRKDrBGzCijCK/+MvCxiMZGDpYZqHTjXw== +"@cspell/dict-cpp@^1.1.39": + version "1.1.39" + resolved "https://registry.yarnpkg.com/@cspell/dict-cpp/-/dict-cpp-1.1.39.tgz#7e119e2c009f9200127733cbca3435180c405c70" + integrity sha512-zrQjzMaT5YqAa4PMEaLfOWnfyh4uJjW53kwtuTo9nfJPaga2+FfrqdeWD8XYMxvTGCtzjivXhAn4FDIMh+66YQ== "@cspell/dict-cryptocurrencies@^1.0.10": version "1.0.10" @@ -1237,15 +1244,15 @@ resolved "https://registry.yarnpkg.com/@cspell/dict-elixir/-/dict-elixir-1.0.24.tgz#fc5c15b9f66b8aa5e25c98f54103c796fec70aba" integrity sha512-pEX6GYlEx4Teusw/m+XmqoXzcHOqpcn1ZX4H33ONqR81XdPwbaKorBr1IG23Ic76IhwrFlOqs48tcnxrHYpFnA== -"@cspell/dict-en-gb@^1.1.28": - version "1.1.28" - resolved "https://registry.yarnpkg.com/@cspell/dict-en-gb/-/dict-en-gb-1.1.28.tgz#7abe6498aea15a87c502eefbf6f1850ccc1f54a2" - integrity sha512-noOH+iv4xFpPxu1agiQgp5LhY/KA0Ir28y1xnC2QTtLvlIid7vIvgixBOz4Zi0P7lo/mPmMjQY+x7//2EKFDgQ== +"@cspell/dict-en-gb@^1.1.30": + version "1.1.30" + resolved "https://registry.yarnpkg.com/@cspell/dict-en-gb/-/dict-en-gb-1.1.30.tgz#eee3d16b0176f5a44667f966f83097c3d6a7d654" + integrity sha512-xQUXZZ0ODBY9saso9e0BozS5FsX2o2+0fmbrekyITTTOCt/RN7bqByC7Hfj7HziQ3LxuC06EsS8ao8CKk9JTmQ== -"@cspell/dict-en_us@^1.2.40": - version "1.2.40" - resolved "https://registry.yarnpkg.com/@cspell/dict-en_us/-/dict-en_us-1.2.40.tgz#03e7c7458f9685e09a19fc23f964a9d3dbe52ecd" - integrity sha512-e8leCvGAWPWQIw0SoozgEAiMt2YM12rafOuW4aQwgTJD++vp32a9RrnVL8olBfWaA57rRWWndbMSmPTrsO9mpg== +"@cspell/dict-en_us@^1.2.43": + version "1.2.43" + resolved "https://registry.yarnpkg.com/@cspell/dict-en_us/-/dict-en_us-1.2.43.tgz#dae5a5cd1a47408a5d3a13c2f215793ecde5f400" + integrity sha512-WAOtAZr3rNH4zpUXSeuxEo/C65o4Xp4sVdZ9cIqI+FPU7Vrgz0wuQZIL5TwbkuGUdtQtpRfgs2kTPXzns0fjGw== "@cspell/dict-filetypes@^1.1.5": version "1.1.5" @@ -1257,10 +1264,10 @@ resolved "https://registry.yarnpkg.com/@cspell/dict-fonts/-/dict-fonts-1.0.14.tgz#7b18129910d30bd23cd9187d0c0009dfc3fef4ba" integrity sha512-VhIX+FVYAnqQrOuoFEtya6+H72J82cIicz9QddgknsTqZQ3dvgp6lmVnsQXPM3EnzA8n1peTGpLDwHzT7ociLA== -"@cspell/dict-fullstack@^1.0.37": - version "1.0.37" - resolved "https://registry.yarnpkg.com/@cspell/dict-fullstack/-/dict-fullstack-1.0.37.tgz#0d3bf8fff97a320037cc9823942b056d194a45a2" - integrity sha512-ljVzUdIlBENMiyHUV06007hz2FPRt+BQmC9Jgn6iGIEQeAQp37Q6oIDmxv2lD65ScEIbysxXuaUgJ5x0j4a48A== +"@cspell/dict-fullstack@^1.0.38": + version "1.0.38" + resolved "https://registry.yarnpkg.com/@cspell/dict-fullstack/-/dict-fullstack-1.0.38.tgz#a26d9db5fdc51e8743f57e51b0fa44a1d4791cf6" + integrity sha512-4reajWiUxwWrSyZaWm9e15kaWzjYcZbzlB+CVcxE1+0NqdIoqlEESDhbnrAjKPSq+jspKtes7nQ1CdZEOj1gCA== "@cspell/dict-golang@^1.1.24": version "1.1.24" @@ -1277,10 +1284,10 @@ resolved "https://registry.yarnpkg.com/@cspell/dict-html-symbol-entities/-/dict-html-symbol-entities-1.0.23.tgz#0efbdbc7712c9fbe545e14acac637226ac948f2d" integrity sha512-PV0UBgcBFbBLf/m1wfkVMM8w96kvfHoiCGLWO6BR3Q9v70IXoE4ae0+T+f0CkxcEkacMqEQk/I7vuE9MzrjaNw== -"@cspell/dict-html@^1.1.6": - version "1.1.6" - resolved "https://registry.yarnpkg.com/@cspell/dict-html/-/dict-html-1.1.6.tgz#29c40c0ebc51de4cfe2d6041206ba39d74b28b67" - integrity sha512-RsZXIrmsnLcUpXfyZdNg7OtO2+e4p7m/qILg03kM6vhSUMY6ryCQNPWKrHqsl8+LBKd54EgFM+O5zcgq6IIsCw== +"@cspell/dict-html@^1.1.7": + version "1.1.7" + resolved "https://registry.yarnpkg.com/@cspell/dict-html/-/dict-html-1.1.7.tgz#723d2c0ef37401d59478685add875d2fa2ae2bad" + integrity sha512-5pea/5fA4iy1s5ko+JvCzNsCO5FGdjT006feVmCIxpUsPdgrV/7ONdm6508XOftot3opRlhEqWq/kB8H+GNdrQ== "@cspell/dict-java@^1.0.22": version "1.0.22" @@ -1302,35 +1309,35 @@ resolved "https://registry.yarnpkg.com/@cspell/dict-lua/-/dict-lua-1.0.16.tgz#c0ca43628f8927fc10731fd27cd9ee0af651bf6a" integrity sha512-YiHDt8kmHJ8nSBy0tHzaxiuitYp+oJ66ffCYuFWTNB3//Y0SI4OGHU3omLsQVeXIfCeVrO4DrVvRDoCls9B5zQ== -"@cspell/dict-node@^1.0.11": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@cspell/dict-node/-/dict-node-1.0.11.tgz#c5a9dbb6dd096850910a5d7bd5c1e78d81df63af" - integrity sha512-q66zAqtNmuvZGKt4stRwQPFLsbOjZGGZOZ1HEbqpOkicxvF0BWhR0Di/JBq27PDxeqQP3S5sLeogQTSNQBuTww== +"@cspell/dict-node@^1.0.12": + version "1.0.12" + resolved "https://registry.yarnpkg.com/@cspell/dict-node/-/dict-node-1.0.12.tgz#a7236be30340ff8fe365f62c8d13121fdbe7f51c" + integrity sha512-RPNn/7CSkflAWk0sbSoOkg0ORrgBARUjOW3QjB11KwV1gSu8f5W/ij/S50uIXtlrfoBLqd4OyE04jyON+g/Xfg== -"@cspell/dict-npm@^1.0.11": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@cspell/dict-npm/-/dict-npm-1.0.11.tgz#e19f746c76a657be96297d0c68fb4dcc62ad162c" - integrity sha512-mokmv9/Yk1yliDz97drWyuDWv7eKGEcFhdM43YSPK7GuMLh6i2ULOmORPFhUcjxQjPf0uySMDA2JguiQ4m5Lmg== +"@cspell/dict-npm@^1.0.14": + version "1.0.15" + resolved "https://registry.yarnpkg.com/@cspell/dict-npm/-/dict-npm-1.0.15.tgz#4eac51a4e5258b48e2fd1af277c12cb1fd189f4d" + integrity sha512-6N1G1rGi5AsCaDu9mu+VmrrAj5S9gHv8TvJlarauDeEMS6uVl+ce2JpzDf7ld3Qu/4Dkr0sKS63OeA0DKeQTkw== -"@cspell/dict-php@^1.0.23": - version "1.0.23" - resolved "https://registry.yarnpkg.com/@cspell/dict-php/-/dict-php-1.0.23.tgz#8ee85fec8416a88b71edb2a53e26a79f280c9fa7" - integrity sha512-rRLf/09rXDrzs0DJuNXNmFVTw2b2zLmZKNF4LIPrFHYHvdfsMvwVqxkr/SAyhF8C6zi5sW0XYC/J0S/3IE927w== +"@cspell/dict-php@^1.0.24": + version "1.0.24" + resolved "https://registry.yarnpkg.com/@cspell/dict-php/-/dict-php-1.0.24.tgz#40c15a4c5e1e2deba28841e2b498595b13f0ff88" + integrity sha512-vHCqETX1idT9tN1plkxUFnXMIHjbbrNOINZh1PYSvVlBrOdahSaL/g6dOJZC5QTaaidoU4WXUlgnNb/7JN4Plg== -"@cspell/dict-powershell@^1.0.14": - version "1.0.14" - resolved "https://registry.yarnpkg.com/@cspell/dict-powershell/-/dict-powershell-1.0.14.tgz#f8998f2f413b3b94e69a512117de89552cfa1834" - integrity sha512-hisOXXi5PBXB5YKtrJQIis2FIRHgSW1U0/sd4yI36lzb3ZMEvGJwdAdyhXN3IGiqRUNxMzJiXAeXfhnia4xPtQ== +"@cspell/dict-powershell@^1.0.16": + version "1.0.16" + resolved "https://registry.yarnpkg.com/@cspell/dict-powershell/-/dict-powershell-1.0.16.tgz#06a2966b2dca7a0d97938ff90fcfc74354cfb7ba" + integrity sha512-cbauyYR6H53gfd/J9B3wgly9kg1joLSVxxqbry+y0BqF7FBtkctnXev2WHRbX68o6X9iQPhUz6+3zGKwFW5Stg== -"@cspell/dict-python@^1.0.34": - version "1.0.34" - resolved "https://registry.yarnpkg.com/@cspell/dict-python/-/dict-python-1.0.34.tgz#26601cbc78e937b6f5c45110722c720cde4ca7c3" - integrity sha512-1VvyvvEv3ToVdlFIPzD6sOh+bFVrYMHoAL6VnJYfFMnCxw/YftHIc7INg9LEUWcolovVFoUHFOhBN8saXw8bzA== +"@cspell/dict-python@^1.0.35": + version "1.0.35" + resolved "https://registry.yarnpkg.com/@cspell/dict-python/-/dict-python-1.0.35.tgz#0f9880626a1422cdd2be39b18086ae0cd59b4c3f" + integrity sha512-vVlx01SG8VjNHAQGaE/OGSShX1CoiXmdmCBsPX2sip6JmBluengGPtRPhpVLQOMxnXvTKg96eGtcnVRrYkVzag== -"@cspell/dict-ruby@^1.0.13": - version "1.0.13" - resolved "https://registry.yarnpkg.com/@cspell/dict-ruby/-/dict-ruby-1.0.13.tgz#2cb63b575376de3bd85ec9b862bc31cdabb287b9" - integrity sha512-YeN1acY38dgMYlEJ6iWPH+8qXB6seLKHm9BszXxaKT/IzGA9Y9XUWPGobeJFD5E/tC6HjvcqRKxEs8vnvakoLQ== +"@cspell/dict-ruby@^1.0.14": + version "1.0.14" + resolved "https://registry.yarnpkg.com/@cspell/dict-ruby/-/dict-ruby-1.0.14.tgz#6ecbda6e0a01e4692abd4a14b64ff8f61d86e161" + integrity sha512-XHBGN4U1y9rjRuqrCA+3yIm2TCdhwwHXpOEcWkNeyXm8K03yPnIrKFS+kap8GTTrLpfNDuFsrmkkQTa7ssXLRA== "@cspell/dict-rust@^1.0.22": version "1.0.22" @@ -1342,15 +1349,15 @@ resolved "https://registry.yarnpkg.com/@cspell/dict-scala/-/dict-scala-1.0.21.tgz#bfda392329061e2352fbcd33d228617742c93831" integrity sha512-5V/R7PRbbminTpPS3ywgdAalI9BHzcEjEj9ug4kWYvBIGwSnS7T6QCFCiu+e9LvEGUqQC+NHgLY4zs1NaBj2vA== -"@cspell/dict-software-terms@^1.0.28": - version "1.0.28" - resolved "https://registry.yarnpkg.com/@cspell/dict-software-terms/-/dict-software-terms-1.0.28.tgz#0c26bbfa89546d257b52cd433000ba7fe86a1901" - integrity sha512-N/5H+J68CgToDSZiMMSJl3ws5qU7GJOj1sXZ9oXr1wojvu/qifCp32zDh8hzFWrZF1VUdnStusNVTeW1Wq4Pog== +"@cspell/dict-software-terms@^1.0.34": + version "1.0.36" + resolved "https://registry.yarnpkg.com/@cspell/dict-software-terms/-/dict-software-terms-1.0.36.tgz#16c2ee2812964e3b1b8392de38e41ff7c27d1bd8" + integrity sha512-T8jyVQktz2LPlJdU1k+GtTyghSLuQy7w/BeInT+aa0H8zssvwoi/kliWNXjOz9ZdvBF+VYjw4gbHWRDXPzTOAg== -"@cspell/dict-typescript@^1.0.17": - version "1.0.17" - resolved "https://registry.yarnpkg.com/@cspell/dict-typescript/-/dict-typescript-1.0.17.tgz#56ae757bdbf785e90846e62297fe1295c58468f4" - integrity sha512-CXCuXcrgAc56P3kL9I6gW6bZwTs6t3duyAtHerHg5YAYbPs6/4nXgniQgLgu8kjFHFy07XrqaaBdLU9V2DmMtQ== +"@cspell/dict-typescript@^1.0.19": + version "1.0.19" + resolved "https://registry.yarnpkg.com/@cspell/dict-typescript/-/dict-typescript-1.0.19.tgz#44f3ad1c93ffc89ebf98fa6964e1634e6612fc30" + integrity sha512-qmJApzoVskDeJnLZzZMaafEDGbEg5Elt4c3Mpg49SWzIHm1N4VXCp5CcFfHsOinJ30dGrs3ARAJGJZIw56kK6A== "@csstools/convert-colors@^1.4.0": version "1.4.0" @@ -1371,14 +1378,14 @@ enabled "2.0.x" kuler "^2.0.0" -"@es-joy/jsdoccomment@^0.4.4": - version "0.4.4" - resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.4.4.tgz#8a25154156edbfc29e310943ebb17ee29122c9df" - integrity sha512-ua4qDt9dQb4qt5OI38eCZcQZYE5Bq3P0GzgvDARdT8Lt0mAUpxKTPy8JGGqEvF77tG1irKDZ3WreeezEa3P43w== +"@es-joy/jsdoccomment@^0.8.0-alpha.2": + version "0.8.0-alpha.2" + resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.8.0-alpha.2.tgz#78585147d8e6231270374dae528fe5b7b5587b5a" + integrity sha512-fjRY13Bh8sxDZkzO27U2R9L6xFqkh5fAbHuMGvGLXLfrTes8nTTMyOi6wIPt+CG0XPAxEUge8cDjhG+0aag6ew== dependencies: comment-parser "^1.1.5" esquery "^1.4.0" - jsdoctypeparser "^9.0.0" + jsdoc-type-pratt-parser "1.0.0-alpha.23" "@eslint/eslintrc@^0.3.0": version "0.3.0" @@ -1644,18 +1651,18 @@ mkdirp "^1.0.4" rimraf "^3.0.2" -"@patternfly/patternfly@4.102.2": - version "4.102.2" - resolved "https://registry.yarnpkg.com/@patternfly/patternfly/-/patternfly-4.102.2.tgz#604462f7d3079a9fb47725e1c3a5a00820870b77" - integrity sha512-n51n3iW/lRHCvModGYDCEzeLJO+x4Z9ZRkdz6HtUqrStfjIRFHCKbKlpyPvpWacdQEC5Mx1oNIrHmNASmm/Zgw== +"@patternfly/patternfly@4.108.2": + version "4.108.2" + resolved "https://registry.yarnpkg.com/@patternfly/patternfly/-/patternfly-4.108.2.tgz#b6686b9865fd5d4233a15bdf04cc53bded5a8ccc" + integrity sha512-z0VB+1CXcH+eoClYQABwapX5FURSvm1nPr6asLWwg/Z4Wuxs0RjZpC6Gb+KRm8nGQwSAcMKZY1jLfPqVnznQnw== -"@patternfly/react-charts@6.14.17": - version "6.14.17" - resolved "https://registry.yarnpkg.com/@patternfly/react-charts/-/react-charts-6.14.17.tgz#3779e921dc9c24d47d71bd83026b273d3e45d534" - integrity sha512-UZCdszEcLiezR/3TDFijMZqy+qq7oWQJAbOpwiAaxiJwTYv/cuJXY7ss437oQL4zZBqrpGBdCCh0QPML9dPE7g== +"@patternfly/react-charts@6.14.29": + version "6.14.29" + resolved "https://registry.yarnpkg.com/@patternfly/react-charts/-/react-charts-6.14.29.tgz#bae620dd9e249140ba3bc67692ce20b7c1682f21" + integrity sha512-bmpfhdhn0gnmZCCIeuGK/N6a6nb2TFWvBv8WZzjQq1lgxW3apeQGnXAEWg/iLEsRHrk19T7hbqoSTmh2t5/HIQ== dependencies: - "@patternfly/react-styles" "^4.10.2" - "@patternfly/react-tokens" "^4.11.3" + "@patternfly/react-styles" "^4.10.11" + "@patternfly/react-tokens" "^4.11.12" hoist-non-react-statics "^3.3.0" lodash "^4.17.19" tslib "1.13.0" @@ -1675,45 +1682,45 @@ victory-voronoi-container "^35.4.4" victory-zoom-container "^35.4.4" -"@patternfly/react-core@4.115.2", "@patternfly/react-core@^4.115.2": - version "4.115.2" - resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-4.115.2.tgz#084d1e408463945fa94f2b3bed13bd0b1146dcae" - integrity sha512-lnA+WmTQ0IyJIuSSUH0mjMUujAb6sYGNFMwkGDy4BpJjeu0aredVEmM0kAe/rFAurjSen/JpOhET2V3NiMGKtA== +"@patternfly/react-core@4.128.2", "@patternfly/react-core@^4.128.2": + version "4.128.2" + resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-4.128.2.tgz#dd0c218bc75a32ee41c69e3d51bead6b157c4aae" + integrity sha512-EhrxE3+V7AYVhbERrcRVH7oY6TeVRqqzaRx8HXWnyn/hxE2rTzhhaLHyjotxk9mGYmIYtMuMebBHFbX0g+6Ymg== dependencies: - "@patternfly/react-icons" "^4.10.2" - "@patternfly/react-styles" "^4.10.2" - "@patternfly/react-tokens" "^4.11.3" + "@patternfly/react-icons" "^4.10.11" + "@patternfly/react-styles" "^4.10.11" + "@patternfly/react-tokens" "^4.11.12" focus-trap "6.2.2" react-dropzone "9.0.0" tippy.js "5.1.2" tslib "1.13.0" -"@patternfly/react-icons@4.10.2", "@patternfly/react-icons@^4.10.2": - version "4.10.2" - resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-4.10.2.tgz#d0659e7763364b1e73ec0f3b60e20cf9e4f067d6" - integrity sha512-mSkBRaEFukpaAoLDyd3nI+6Cj0z2/5DgJTA2i7By/UW1wJifKnBWW8NRO2SsJQVQIUtuuAunjUrjzKHdcxs5IQ== - -"@patternfly/react-styles@4.10.2", "@patternfly/react-styles@^4.10.2": - version "4.10.2" - resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-4.10.2.tgz#f399766ecb26e44e605355e94271da54029b5990" - integrity sha512-cGvDFAISGrt+RAkX5NVyILCjWV1l9PCUpnMq6v4/6jBJOEHTBnRjaIGa92dw3OrLh407cBOIC0ugweRnocRmPw== - -"@patternfly/react-table@4.26.7": - version "4.26.7" - resolved "https://registry.yarnpkg.com/@patternfly/react-table/-/react-table-4.26.7.tgz#9f58d6f7d2b6189fa48ada5105391b38ecf823ab" - integrity sha512-rG6ZrkOf9sDGoKFP5VuntmB2DiOr2CyStZ4TKSFpH55ZIIIQB9FtuaDmX58cTE0xDpP4YW/NPEKkWHDVo7t76Q== - dependencies: - "@patternfly/react-core" "^4.115.2" - "@patternfly/react-icons" "^4.10.2" - "@patternfly/react-styles" "^4.10.2" - "@patternfly/react-tokens" "^4.11.3" +"@patternfly/react-icons@4.10.11", "@patternfly/react-icons@^4.10.11": + version "4.10.11" + resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-4.10.11.tgz#9bed483fc37c8b795b3fb98c17ede00eef775857" + integrity sha512-Qyxwvghb9HZB2do3UVw4EzJSvqWaw/AEw6mFzqshZiIm2oPrL4NkvavwDt5WRicz5sbyWTZluB4grOj33PEpww== + +"@patternfly/react-styles@4.10.11", "@patternfly/react-styles@^4.10.11": + version "4.10.11" + resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-4.10.11.tgz#6bda5673a71037c0fb9be7e11a117ed8cfea6ce0" + integrity sha512-M+NhTtAXreJzMAV2Z1P2pbnKpRYnWbB5iZ6mxB0tkxxG+KyZ0/se8M5rUepLOE/n7BMq8IiOjPJ9zu/vpWj0gA== + +"@patternfly/react-table@4.27.24": + version "4.27.24" + resolved "https://registry.yarnpkg.com/@patternfly/react-table/-/react-table-4.27.24.tgz#c61947800d9c82fae3d46a03a1e9989ec49f5f61" + integrity sha512-LXKWtCeEJ4KR8ZnyeAPHdDQFJC9KQe/2Z7yJxBHy8gWciLAPcrLvnTtAb+d1O2lFXKMpUKFNUIwzVvuAffjDSA== + dependencies: + "@patternfly/react-core" "^4.128.2" + "@patternfly/react-icons" "^4.10.11" + "@patternfly/react-styles" "^4.10.11" + "@patternfly/react-tokens" "^4.11.12" lodash "^4.17.19" tslib "1.13.0" -"@patternfly/react-tokens@4.11.3", "@patternfly/react-tokens@^4.11.3": - version "4.11.3" - resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-4.11.3.tgz#f102df85af3d248728b6b33d5c16784fa0ad3ebb" - integrity sha512-7VbmT+aOwxk1DYzwer+wZgcbvkSsUUTKMKJDzhMvm5xi9nDeW8qI7laxQbWC9PDfsI5tiPxI2+BSuHnZpV/eRg== +"@patternfly/react-tokens@4.11.12", "@patternfly/react-tokens@^4.11.12": + version "4.11.12" + resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-4.11.12.tgz#0d4d88ec768cbf5c4b46e75dc8673ba97448823c" + integrity sha512-PTEc2CQa/BqcDcUwT0V02l+ZoJa+bheLlh9R5g1+JQ6vlqH31gk0dpHmj6goEcSDLkbvMJgr3kNZdJsP1VdBMg== "@pmmmwh/react-refresh-webpack-plugin@0.4.3": version "0.4.3" @@ -1727,14 +1734,15 @@ schema-utils "^2.6.5" source-map "^0.7.3" -"@redhat-cloud-services/frontend-components-notifications@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@redhat-cloud-services/frontend-components-notifications/-/frontend-components-notifications-3.1.0.tgz#d0d7ec32e8d88b75a1aef0b2ebb1e12eecf93632" - integrity sha512-gHN424/3TJ1kPtk5Dos+aScUL+QjkmKhKhyiSDNN2o7LzhN+J+d2xA0bCx2mfEBspqHG+1nTiHpZbgQ3l0kntw== +"@redhat-cloud-services/frontend-components-notifications@3.2.2": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@redhat-cloud-services/frontend-components-notifications/-/frontend-components-notifications-3.2.2.tgz#588f08197ce75520ba1729774be0af8334e9f0bb" + integrity sha512-n6aGKwv5ttlW+dEFWoj9uclEbgl5V6iFWOwwMg5FdWsh3jQ6Y9oaUxX4XYsOGAJyNgD92JH6A6n0T9Fgy6mWQA== dependencies: "@redhat-cloud-services/frontend-components-utilities" "*" + redux-promise-middleware "6.1.2" -"@redhat-cloud-services/frontend-components-utilities@*", "@redhat-cloud-services/frontend-components-utilities@3.1.2", "@redhat-cloud-services/frontend-components-utilities@>=3.0.0": +"@redhat-cloud-services/frontend-components-utilities@*", "@redhat-cloud-services/frontend-components-utilities@>=3.0.0": version "3.1.2" resolved "https://registry.yarnpkg.com/@redhat-cloud-services/frontend-components-utilities/-/frontend-components-utilities-3.1.2.tgz#965c03508336e6d68dc9cad39b38ae05acd0f4e8" integrity sha512-CDnhCQTotqCWUzZUgPXEori95FDhrXGBUxodwQpR3wKTb1lBpwDHg4b3TdpzPz+KyryClT6OfNkVabmjQ2S6CA== @@ -1745,10 +1753,22 @@ commander ">=2.20.0" react-content-loader ">=3.4.1" -"@redhat-cloud-services/frontend-components@3.1.11": - version "3.1.11" - resolved "https://registry.yarnpkg.com/@redhat-cloud-services/frontend-components/-/frontend-components-3.1.11.tgz#ad655dc0a69c6b851087aac1d38beec3e79dfebc" - integrity sha512-6dvjKlb2l7cKn9Ex+z+aJkn4RHn2NzQIs8ylYQgN9fkKtZhm3dTQiINKxcmmlBTsody6pbPcp2I854jhyqfMug== +"@redhat-cloud-services/frontend-components-utilities@3.2.2": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@redhat-cloud-services/frontend-components-utilities/-/frontend-components-utilities-3.2.2.tgz#b84e107a603b18473bbd8600a98eb003b2f8be55" + integrity sha512-HCiXpAuXCmxFc3+Lf/QS0niemGa/4Z6BbbghixA9y3NZytt9ggHVeYyVJNIfHa6aEkQn7OiHL7RaISfmhmirKw== + dependencies: + "@sentry/browser" "^5.4.0" + awesome-debounce-promise "^2.1.0" + axios "^0.21.1" + commander ">=2.20.0" + mkdirp "^1.0.4" + react-content-loader ">=3.4.1" + +"@redhat-cloud-services/frontend-components@3.2.5": + version "3.2.5" + resolved "https://registry.yarnpkg.com/@redhat-cloud-services/frontend-components/-/frontend-components-3.2.5.tgz#8d82356ef6d4ee3abebcbb56a2a4f4712c79663b" + integrity sha512-Yf5NJg8XyAstHuRultbtr1m9QrOtMnA77dkHE7MT5Svv7HcgwXTeGVMQ2GKYFAmZq95D/RtgMnXQRW5PwYk/qw== dependencies: "@redhat-cloud-services/frontend-components-utilities" ">=3.0.0" "@scalprum/core" "^0.0.11" @@ -2695,11 +2715,6 @@ alphanum-sort@^1.0.0: resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= - ansi-align@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" @@ -2734,11 +2749,6 @@ ansi-regex@^2.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" @@ -2749,11 +2759,6 @@ ansi-regex@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -2784,10 +2789,10 @@ anymatch@^3.0.3, anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" -apidoc-core@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/apidoc-core/-/apidoc-core-0.12.0.tgz#96e5c04c17b92c288664ef3c8aa4c78cbfacccb6" - integrity sha512-VMhkJWz5IAyvWM0RnEbKNi1qe8se+id3/Ki3H/ePM8ih0KYTfaaSDxqo2w4uIVB1UVVKFvrTWyYUyQs7CEcoKQ== +apidoc-core@^0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/apidoc-core/-/apidoc-core-0.15.0.tgz#4dfcc76cc76694bd4457ccbd8655c03a87a2e2a5" + integrity sha512-CJNjRs6R8nc774vUtbv9Uakos5/JbEFpBXgE6oiWUX7OpjI1s04xPuULEoQQJyQM427r5hr55GSHAm5/LRc5TQ== dependencies: fs-extra "^9.0.1" glob "^7.1.6" @@ -2796,23 +2801,23 @@ apidoc-core@^0.12.0: lodash "^4.17.20" semver "~7.3.2" -apidoc-mock@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/apidoc-mock/-/apidoc-mock-3.0.4.tgz#5981d6762bae3f16edfade92aabd27847c2a18b0" - integrity sha512-iopmRbYV4gME4wiMYkp+/Yi9sL7KOiIk7plLG4CTm6Ptag0yhEj8Z24pNih5nbXXP0txkXG0v2nSvACcjeDeVQ== +apidoc-mock@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/apidoc-mock/-/apidoc-mock-4.0.0.tgz#952a073c28dccf4d100ec119b417bbcc3334d5d9" + integrity sha512-opQkVRfOKcDG7uBJ1dXMJ24+iYECGKsqpUCkKaSqhpanhFKM/FurV99IDaBfaoiKAKfbJ0ugI6sBx/EvdCWGTw== dependencies: - apidoc "^0.26.0" + apidoc "^0.27.1" express "^4.17.1" node-watch "^0.7.1" winston "^3.3.3" - yargs "^16.2.0" + yargs "^17.0.1" -apidoc@^0.26.0: - version "0.26.0" - resolved "https://registry.yarnpkg.com/apidoc/-/apidoc-0.26.0.tgz#7073ed5c92f06a22a611569985f578231c26e3a9" - integrity sha512-IEw/Z7HMMbjeVjK2sZvZSwAln8AqalLzf3qLDtkcedXVhdxGm6W7UgIW6fshegqNTMLzm8CFEMi4Lxbeu0xKTw== +apidoc@^0.27.1: + version "0.27.1" + resolved "https://registry.yarnpkg.com/apidoc/-/apidoc-0.27.1.tgz#2931dca6bb80a49154eb8375f6e49942f0d17ec8" + integrity sha512-CqbsmM1ew7LC2Lg2USaSWPxdtsIp7wb3dzR2DKHYvVSo+dYIY3K7oBsup5bpi6D1OkthTUxXvWvcrDyv7lPcnw== dependencies: - apidoc-core "^0.12.0" + apidoc-core "^0.15.0" commander "^2.20.0" fs-extra "^9.0.1" handlebars "^4.7.6" @@ -2821,19 +2826,11 @@ apidoc@^0.26.0: nodemon "^2.0.4" winston "^3.3.3" -aproba@^1.0.3, aproba@^1.1.1: +aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -2894,18 +2891,7 @@ array-ify@^1.0.0: resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4= -array-includes@^3.1.1, array-includes@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.2.tgz#a8db03e0b88c8c6aeddc49cb132f9bcab4ebf9c8" - integrity sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - get-intrinsic "^1.0.1" - is-string "^1.0.5" - -array-includes@^3.1.3: +array-includes@^3.1.1, array-includes@^3.1.2, array-includes@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a" integrity sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A== @@ -2943,7 +2929,7 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -array.prototype.flat@^1.2.3: +array.prototype.flat@^1.2.3, array.prototype.flat@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== @@ -2952,7 +2938,7 @@ array.prototype.flat@^1.2.3: define-properties "^1.1.3" es-abstract "^1.18.0-next.1" -array.prototype.flatmap@^1.2.3, array.prototype.flatmap@^1.2.4: +array.prototype.flatmap@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz#94cfd47cc1556ec0747d97f7c7738c58122004c9" integrity sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q== @@ -3027,11 +3013,6 @@ async-each@^1.0.1: resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== -async-foreach@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" - integrity sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI= - async-limiter@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" @@ -3369,13 +3350,6 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" -block-stream@*: - version "0.0.9" - resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" - integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= - dependencies: - inherits "~2.0.0" - bluebird@^3.5.5: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" @@ -3711,7 +3685,7 @@ callsites@^2.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= -callsites@^3.0.0: +callsites@^3.0.0, callsites@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== @@ -3797,17 +3771,6 @@ chalk@2.4.2, chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - chalk@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" @@ -3858,6 +3821,21 @@ cheerio@^1.0.0-rc.3: parse5 "^6.0.0" parse5-htmlparser2-tree-adapter "^6.0.0" +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.2.2, chokidar@^3.4.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.3.1" + chokidar@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" @@ -3877,21 +3855,6 @@ chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" -chokidar@^3.2.2, chokidar@^3.4.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" - integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.5.0" - optionalDependencies: - fsevents "~2.3.1" - chownr@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" @@ -3954,6 +3917,14 @@ clean-stack@^2.0.0: resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== +clear-module@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/clear-module/-/clear-module-4.1.1.tgz#bf8ba3b62eb70ee1e0adec90589741425cf32db8" + integrity sha512-ng0E7LeODcT3QkazOckzZqbca+JByQy/Q2Z6qO24YsTp+pLxCfohGz2gJYJqZS0CWTX3LEUiHOqe5KlYeUbEMw== + dependencies: + parent-module "^2.0.0" + resolve-from "^5.0.0" + cli-boxes@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" @@ -4007,11 +3978,6 @@ coa@^2.0.2: chalk "^2.4.1" q "^1.1.2" -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - collect-v8-coverage@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" @@ -4236,21 +4202,11 @@ console-browserify@^1.1.0: resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= -contains-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= - content-disposition@0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" @@ -4575,14 +4531,6 @@ cross-spawn@7.0.3, cross-spawn@^7.0.0, cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" -cross-spawn@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" - integrity sha1-ElYDfsufDF9549bvE14wdwGEuYI= - dependencies: - lru-cache "^4.0.1" - which "^1.2.9" - cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -4621,62 +4569,65 @@ crypto-random-string@^2.0.0: resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== -cspell-glob@^5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/cspell-glob/-/cspell-glob-5.4.0.tgz#13a2948e9e1defc59f25d76a9a95134521057cfe" - integrity sha512-4CwXDdO3Z0VdfZcD7OS7zFM8h5ay2ZHtzoc5oPLmxSs+tNQdRGNeFSPIv6CNt80AqILtZrlO7nVIbA6KtARqYA== +cspell-glob@^5.6.1: + version "5.6.1" + resolved "https://registry.yarnpkg.com/cspell-glob/-/cspell-glob-5.6.1.tgz#7c49343ee22d39be9c4601b1aa2bc1fc5be32362" + integrity sha512-vP3Jv/mtdTiXZQZauS3a0JjYq6UqgGZg2ahPf+GS0JBK1Dx02V4NM3JuFi17II71onOlazQ9Dilg5PICzyYhug== dependencies: micromatch "^4.0.4" -cspell-io@^5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/cspell-io/-/cspell-io-5.4.0.tgz#b2b74f3cf20db86ca37b4c3a7f648b8db7184f4e" - integrity sha512-VIPb/TmTNK/dG5nrbGhuhvWZQYAFXpYQQJ4hmlmuczhhQ2Qw1YSkRgoEB4Ir0neoRJTeEM2x5tgvSJCOwflSuA== +cspell-io@^5.6.1: + version "5.6.1" + resolved "https://registry.yarnpkg.com/cspell-io/-/cspell-io-5.6.1.tgz#c7b9c647391cddd2b86568d386b6fab69f236c58" + integrity sha512-KZTmFrOEHEOWqrd5nl2VhXDeY99F9gQog2/e41mX0YGupyt8z40D3GTgPTLTZ0lglVHUKd5caKDQ3BkF4ziV8g== dependencies: - iconv-lite "^0.6.2" - iterable-to-stream "^1.0.1" + iconv-lite "^0.6.3" + iterable-to-stream "^2.0.0" -cspell-lib@^5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/cspell-lib/-/cspell-lib-5.4.0.tgz#8e60a2ad7d46e79965bcb95cff9f1d97c37b65f1" - integrity sha512-ja1zvRF+pNi+hioWYZUGpWGXPFfhDujd+qbAoQ08It4xMTVER8cDYQpSo2ll4DPJ2YphPW//2Br6TBvQ5xO50Q== +cspell-lib@^5.6.1: + version "5.6.1" + resolved "https://registry.yarnpkg.com/cspell-lib/-/cspell-lib-5.6.1.tgz#7db04dc188fd77710c85149bb7687fc5706712c7" + integrity sha512-zswIU6ZJpil5+J5oBLFyNIQsNyanU7YLNlRhf82/dZjcDMHtXtnTCHW9ddZuiHxKgELvQtSdOg5H9FprjOudgg== dependencies: - "@cspell/cspell-bundled-dicts" "^5.4.0" - "@cspell/cspell-types" "^5.4.0" + "@cspell/cspell-bundled-dicts" "^5.6.1" + "@cspell/cspell-types" "^5.6.1" + clear-module "^4.1.1" comment-json "^4.1.0" configstore "^5.0.1" cosmiconfig "^7.0.0" - cspell-glob "^5.4.0" - cspell-io "^5.4.0" - cspell-trie-lib "^5.4.0" - fs-extra "^9.1.0" + cspell-glob "^5.6.1" + cspell-io "^5.6.1" + cspell-trie-lib "^5.6.1" + find-up "^5.0.0" + fs-extra "^10.0.0" gensequence "^3.1.1" + import-fresh "^3.3.0" resolve-from "^5.0.0" resolve-global "^1.0.0" vscode-uri "^3.0.2" -cspell-trie-lib@^5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/cspell-trie-lib/-/cspell-trie-lib-5.4.0.tgz#bfe721b6a5e5885f3edb73b5861500c142f3b46b" - integrity sha512-IpDFdOoUEdiyzDGEUCIAoAUenIMy0FjOKotmsl9GTbOyq0XPHE6s7Yz5s9pFzX9IHxvsJ7Plhvn627k7QAC6DQ== +cspell-trie-lib@^5.6.1: + version "5.6.1" + resolved "https://registry.yarnpkg.com/cspell-trie-lib/-/cspell-trie-lib-5.6.1.tgz#18a3103e031cf88a0090d4c5074124e98112be40" + integrity sha512-kMJUm+VKq0vV5MPDW9ZbYQs8/4rrlEwDtb/lEa2b8v+OcHIsPNKzchbfidWczqmpAD/LqFtW5QdBj2PSy24xQQ== dependencies: - fs-extra "^9.1.0" + fs-extra "^10.0.0" gensequence "^3.1.1" -cspell@^5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/cspell/-/cspell-5.4.0.tgz#3cafddc67b445deaea52b72af318b8c716891748" - integrity sha512-613oEbxry/xJWrFf/r6RS3jQ88Az0W3LRazGi0s+tcIAlprJn78inTKUn23oQslhoF0dhYADJdFaR6Q4Fd6+zw== +cspell@^5.6.1: + version "5.6.1" + resolved "https://registry.yarnpkg.com/cspell/-/cspell-5.6.1.tgz#9a56e3e344331f06a9085fd73878151ee840f954" + integrity sha512-jHMq0Yuoir9ziSo/oTqVk8LYiJNklAQesz3L6cxFiqg+t4n/bbodh/2Qkq7nCTXA1OhKQM2MbFnxpFUC4d87+Q== dependencies: - "@cspell/cspell-types" "^5.4.0" + "@cspell/cspell-types" "^5.6.1" chalk "^4.1.1" commander "^7.2.0" comment-json "^4.1.0" - cspell-glob "^5.4.0" - cspell-lib "^5.4.0" - fs-extra "^9.1.0" + cspell-glob "^5.6.1" + cspell-lib "^5.6.1" + fs-extra "^10.0.0" get-stdin "^8.0.0" - glob "^7.1.6" + glob "^7.1.7" strip-ansi "^6.0.0" css-blank-pseudo@^0.1.4: @@ -5051,7 +5002,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: dependencies: ms "2.0.0" -debug@^3.1.1, debug@^3.2.6: +debug@^3.1.1, debug@^3.2.6, debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -5192,10 +5143,10 @@ delaunator@^4.0.0: resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-4.0.1.tgz#3d779687f57919a7a418f8ab947d3bddb6846957" integrity sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag== -delaunay-find@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/delaunay-find/-/delaunay-find-0.0.5.tgz#5fb37e6509da934881b4b16c08898ac89862c097" - integrity sha512-7yAJ/wmKWj3SgqjtkGqT/RCwI0HWAo5YnHMoF5nYXD8cdci+YSo23iPmgrZUNOpDxRWN91PqxUvMMr2lKpjr+w== +delaunay-find@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/delaunay-find/-/delaunay-find-0.0.6.tgz#2ed017a79410013717fa7d9422e082c2502d4ae3" + integrity sha512-1+almjfrnR7ZamBk0q3Nhg6lqSe6Le4vL0WJDSMx4IDbQwTpUTXPjxC00lqLBT8MYsJpPCbI16sIkw9cPsbi7Q== dependencies: delaunator "^4.0.0" @@ -5204,11 +5155,6 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" @@ -5296,14 +5242,6 @@ dns-txt@^2.0.2: dependencies: buffer-indexof "^1.0.0" -doctrine@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -5697,6 +5635,28 @@ es-abstract@^1.18.0-next.2: string.prototype.trimstart "^1.0.4" unbox-primitive "^1.0.0" +es-abstract@^1.18.2: + version "1.18.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.3.tgz#25c4c3380a27aa203c44b2b685bba94da31b63e0" + integrity sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.2" + is-callable "^1.2.3" + is-negative-zero "^2.0.1" + is-regex "^1.1.3" + is-string "^1.0.6" + object-inspect "^1.10.3" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" + es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -5752,7 +5712,7 @@ escape-string-regexp@2.0.0, escape-string-regexp@^2.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -5812,12 +5772,12 @@ eslint-import-resolver-node@^0.3.4: debug "^2.6.9" resolve "^1.13.1" -eslint-module-utils@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6" - integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== +eslint-module-utils@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz#b51be1e473dd0de1c5ea638e22429c2490ea8233" + integrity sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A== dependencies: - debug "^2.6.9" + debug "^3.2.7" pkg-dir "^2.0.0" eslint-plugin-flowtype@^5.2.0: @@ -5828,23 +5788,25 @@ eslint-plugin-flowtype@^5.2.0: lodash "^4.17.15" string-natural-compare "^3.0.1" -eslint-plugin-import@^2.22.1: - version "2.22.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz#0896c7e6a0cf44109a2d97b95903c2bb689d7702" - integrity sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw== +eslint-plugin-import@^2.22.1, eslint-plugin-import@^2.23.4: + version "2.23.4" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz#8dceb1ed6b73e46e50ec9a5bb2411b645e7d3d97" + integrity sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ== dependencies: - array-includes "^3.1.1" - array.prototype.flat "^1.2.3" - contains-path "^0.1.0" + array-includes "^3.1.3" + array.prototype.flat "^1.2.4" debug "^2.6.9" - doctrine "1.5.0" + doctrine "^2.1.0" eslint-import-resolver-node "^0.3.4" - eslint-module-utils "^2.6.0" + eslint-module-utils "^2.6.1" + find-up "^2.0.0" has "^1.0.3" + is-core-module "^2.4.0" minimatch "^3.0.4" - object.values "^1.1.1" - read-pkg-up "^2.0.0" - resolve "^1.17.0" + object.values "^1.1.3" + pkg-up "^2.0.0" + read-pkg-up "^3.0.0" + resolve "^1.20.0" tsconfig-paths "^3.9.0" eslint-plugin-jest@^24.1.0: @@ -5861,18 +5823,18 @@ eslint-plugin-jest@^24.3.6: dependencies: "@typescript-eslint/experimental-utils" "^4.0.1" -eslint-plugin-jsdoc@^33.3.0: - version "33.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-33.3.0.tgz#a287db838d2cac4b36b76d99213901be6a31e9f5" - integrity sha512-wt6I9X8JoOyUtnsafM7AWBEfLCD3BI1wR5/vTu0hti4CoZc37bB4ZX9A7DsWKbEC/xROAAcBV2VAT638w9VKyQ== +eslint-plugin-jsdoc@^35.1.3: + version "35.1.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-35.1.3.tgz#ee9f8566eeb87a0e96fc52ec55897a2cb93ceea5" + integrity sha512-9AVpCssb7+cfEx3GJtnhJ8yLOVsHDKGMgngcfvwFBxdcOVPFhLENReL5aX1R2gNiG3psqIWFVBpSPnPQTrMZUA== dependencies: - "@es-joy/jsdoccomment" "^0.4.4" + "@es-joy/jsdoccomment" "^0.8.0-alpha.2" comment-parser "1.1.5" debug "^4.3.1" esquery "^1.4.0" - jsdoctypeparser "^9.0.0" + jsdoc-type-pratt-parser "^1.0.4" lodash "^4.17.21" - regextras "^0.7.1" + regextras "^0.8.0" semver "^7.3.5" spdx-expression-parse "^3.0.1" @@ -5913,27 +5875,10 @@ eslint-plugin-react-hooks@^4.2.0: resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz#8c229c268d468956334c943bb45fc860280f5556" integrity sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ== -eslint-plugin-react@^7.21.5: - version "7.22.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz#3d1c542d1d3169c45421c1215d9470e341707269" - integrity sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA== - dependencies: - array-includes "^3.1.1" - array.prototype.flatmap "^1.2.3" - doctrine "^2.1.0" - has "^1.0.3" - jsx-ast-utils "^2.4.1 || ^3.0.0" - object.entries "^1.1.2" - object.fromentries "^2.0.2" - object.values "^1.1.1" - prop-types "^15.7.2" - resolve "^1.18.1" - string.prototype.matchall "^4.0.2" - -eslint-plugin-react@^7.23.2: - version "7.23.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.23.2.tgz#2d2291b0f95c03728b55869f01102290e792d494" - integrity sha512-AfjgFQB+nYszudkxRkTFu0UR1zEQig0ArVMPloKhxwlwkzaw/fBiH0QWcBBhZONlXqQC51+nfqFrkn4EzHcGBw== +eslint-plugin-react@^7.21.5, eslint-plugin-react@^7.24.0: + version "7.24.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.24.0.tgz#eadedfa351a6f36b490aa17f4fa9b14e842b9eb4" + integrity sha512-KJJIx2SYx7PBx3ONe/mEeMz4YE0Lcr7feJTCMyyKb/341NcjuAgim3Acgan89GfPv7nxXK2+0slu0CWXYM4x+Q== dependencies: array-includes "^3.1.3" array.prototype.flatmap "^1.2.4" @@ -5941,12 +5886,12 @@ eslint-plugin-react@^7.23.2: has "^1.0.3" jsx-ast-utils "^2.4.1 || ^3.0.0" minimatch "^3.0.4" - object.entries "^1.1.3" + object.entries "^1.1.4" object.fromentries "^2.0.4" - object.values "^1.1.3" + object.values "^1.1.4" prop-types "^15.7.2" resolve "^2.0.0-next.3" - string.prototype.matchall "^4.0.4" + string.prototype.matchall "^4.0.5" eslint-plugin-testing-library@^3.9.2: version "3.10.1" @@ -6585,6 +6530,15 @@ fs-access@^1.0.1: dependencies: null-check "^1.0.0" +fs-extra@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" + integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-extra@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" @@ -6603,7 +6557,7 @@ fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^9.0.1, fs-extra@^9.1.0: +fs-extra@^9.0.1: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== @@ -6648,16 +6602,6 @@ fsevents@^2.1.2, fsevents@^2.1.3, fsevents@~2.3.1: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== -fstream@^1.0.0, fstream@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" - integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" - function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -6693,27 +6637,6 @@ functions-have-names@^1.2.1, functions-have-names@^1.2.2: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.2.tgz#98d93991c39da9361f8e50b337c4f6e41f120e21" integrity sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA== -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -gaze@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" - integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== - dependencies: - globule "^1.0.0" - gensequence@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/gensequence/-/gensequence-3.1.1.tgz#95c1afc7c0680f92942c17f2d6f83f3d26ea97af" @@ -6729,7 +6652,7 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.1, get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== @@ -6844,7 +6767,7 @@ glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0: dependencies: is-glob "^4.0.1" -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.1.7, glob@~7.1.1: +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.1.7: version "7.1.7" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== @@ -6933,15 +6856,6 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" -globule@^1.0.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/globule/-/globule-1.3.2.tgz#d8bdd9e9e4eef8f96e245999a5dee7eb5d8529c4" - integrity sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA== - dependencies: - glob "~7.1.1" - lodash "~4.17.10" - minimatch "~3.0.2" - got@^9.6.0: version "9.6.0" resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" @@ -7022,13 +6936,6 @@ harmony-reflect@^1.4.6: resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.1.tgz#c108d4f2bb451efef7a37861fdbdae72c9bdefa9" integrity sha512-WJTeyp0JzGtHcuMsi7rw2VwtkvLa+JyfEKJCFyfcS0+CDkjQ5lHPu7zEhFZP+PDSRrEgXa5Ah0l1MbgbE41XjA== -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - has-bigints@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" @@ -7059,11 +6966,6 @@ has-symbols@^1.0.2: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" @@ -7383,10 +7285,10 @@ i18next-xhr-backend@^3.2.2: dependencies: "@babel/runtime" "^7.5.5" -i18next@^20.2.2: - version "20.2.2" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-20.2.2.tgz#175644829dcf35546ba8c174583acfe449e4ef1a" - integrity sha512-uWCv9LzKpe+OwvnKKrb8CbJwgAhasQofD58cB0PQ6bTPXEl5PlItl5C4esmY8HtriLu9nrjc2Hi0IfYv3Fy8BQ== +i18next@^20.3.1: + version "20.3.1" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-20.3.1.tgz#b51dd281a2eec8087753edf1727e160dac8a5554" + integrity sha512-WTY07KreR5z2LBSzAIKs05zpR5tgUT98C4fD96e7Risbc/HZePwF6AEnb9VkjdeSeRn9PDqQBay7ZkphuXt0Xw== dependencies: "@babel/runtime" "^7.12.0" @@ -7404,6 +7306,13 @@ iconv-lite@^0.6.2: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" +iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + icss-utils@^4.0.0, icss-utils@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" @@ -7463,7 +7372,7 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: +import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -7504,11 +7413,6 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -in-publish@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.1.tgz#948b1a535c8030561cea522f73f78f4be357e00c" - integrity sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ== - indent-string@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" @@ -7539,7 +7443,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -7579,7 +7483,7 @@ internal-ip@^4.3.0: default-gateway "^4.2.0" ipaddr.js "^1.9.0" -internal-slot@^1.0.2, internal-slot@^1.0.3: +internal-slot@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== @@ -7704,17 +7608,10 @@ is-color-stop@^1.0.0: rgb-regex "^1.0.1" rgba-regex "^1.0.0" -is-core-module@^2.0.0, is-core-module@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" - integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== - dependencies: - has "^1.0.3" - -is-core-module@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.3.0.tgz#d341652e3408bca69c4671b79a0954a3d349f887" - integrity sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw== +is-core-module@^2.0.0, is-core-module@^2.2.0, is-core-module@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" + integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== dependencies: has "^1.0.3" @@ -7787,13 +7684,6 @@ is-finite@^1.0.0: resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -7927,6 +7817,14 @@ is-regex@^1.0.4, is-regex@^1.0.5, is-regex@^1.1.1, is-regex@^1.1.2: call-bind "^1.0.2" has-symbols "^1.0.1" +is-regex@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" + integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== + dependencies: + call-bind "^1.0.2" + has-symbols "^1.0.2" + is-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" @@ -7957,6 +7855,11 @@ is-string@^1.0.5: resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== +is-string@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f" + integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== + is-subset@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" @@ -8107,10 +8010,10 @@ istanbul-reports@^3.0.2: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -iterable-to-stream@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/iterable-to-stream/-/iterable-to-stream-1.0.1.tgz#37e86baacf6b1a0e9233dad4eb526d0423d08bf3" - integrity sha512-O62gD5ADMUGtJoOoM9U6LQ7i4byPXUNoHJ6mqsmkQJcom331ZJGDApWgDESWyBMEHEJRjtHozgIiTzYo9RU4UA== +iterable-to-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/iterable-to-stream/-/iterable-to-stream-2.0.0.tgz#8cc654ab9b1011dc138e681fee2c0f0bb3cc7e3c" + integrity sha512-efkLePxXjJk92hvN+2rS3tGJTRn8/tqXjmZvPI6LQ29xCj2sUF4zW8hkMsVe3jpTkxtMZ89xsKnz9FaRqNWM6g== jest-changed-files@^26.6.2: version "26.6.2" @@ -8547,11 +8450,6 @@ jest@26.6.0: import-local "^3.0.2" jest-cli "^26.6.0" -js-base64@^2.1.8: - version "2.6.4" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4" - integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ== - js-cookie@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" @@ -8575,10 +8473,15 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jsdoctypeparser@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz#8c97e2fb69315eb274b0f01377eaa5c940bd7b26" - integrity sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw== +jsdoc-type-pratt-parser@1.0.0-alpha.23: + version "1.0.0-alpha.23" + resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-1.0.0-alpha.23.tgz#01c232d92b99b7e7ef52235ab8c9115137426639" + integrity sha512-COtimMd97eo5W0h6R9ISFj9ufg/9EiAzVAeQpKBJ1xJs/x8znWE155HGBDR2rwOuZsCes1gBXGmFVfvRZxGrhg== + +jsdoc-type-pratt-parser@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-1.0.4.tgz#5750d2d32ffb001866537d3baaedea7cf84c7036" + integrity sha512-jzmW9gokeq9+bHPDR1nCeidMyFUikdZlbOhKzh9+/nJqB75XhpNKec1/UuxW5c4+O+Pi31Gc/dCboyfSm/pSpQ== jsdom@^16.4.0: version "16.4.0" @@ -8854,16 +8757,6 @@ load-json-file@^1.0.0: pinkie-promise "^2.0.0" strip-bom "^2.0.0" -load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - load-json-file@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" @@ -9004,7 +8897,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -"lodash@>=3.5 <5", lodash@^4.0.0, lodash@^4.17.0, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.5, lodash@~4.17.10: +"lodash@>=3.5 <5", lodash@^4.17.0, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.5: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -9057,14 +8950,6 @@ lowercase-keys@^2.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== -lru-cache@^4.0.1: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -9191,7 +9076,7 @@ memorystream@^0.3.1: resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= -meow@^3.3.0, meow@^3.7.0: +meow@^3.3.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= @@ -9357,7 +9242,7 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@3.0.4, minimatch@^3.0.4, minimatch@~3.0.2: +minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -9438,7 +9323,7 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1: +mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -9520,7 +9405,7 @@ multicast-dns@^6.0.1: dns-packet "^1.3.1" thunky "^1.0.2" -nan@^2.12.1, nan@^2.13.2: +nan@^2.12.1: version "2.14.2" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== @@ -9621,24 +9506,6 @@ node-forge@^0.10.0: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== -node-gyp@^3.8.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" - integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== - dependencies: - fstream "^1.0.0" - glob "^7.0.3" - graceful-fs "^4.1.2" - mkdirp "^0.5.0" - nopt "2 || 3" - npmlog "0 || 1 || 2 || 3 || 4" - osenv "0" - request "^2.87.0" - rimraf "2" - semver "~5.3.0" - tar "^2.0.0" - which "1" - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -9695,29 +9562,6 @@ node-releases@^1.1.61, node-releases@^1.1.70: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.70.tgz#66e0ed0273aa65666d7fe78febe7634875426a08" integrity sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw== -node-sass@^4.14.1: - version "4.14.1" - resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.14.1.tgz#99c87ec2efb7047ed638fb4c9db7f3a42e2217b5" - integrity sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g== - dependencies: - async-foreach "^0.1.3" - chalk "^1.1.1" - cross-spawn "^3.0.0" - gaze "^1.0.0" - get-stdin "^4.0.1" - glob "^7.0.3" - in-publish "^2.0.0" - lodash "^4.17.15" - meow "^3.7.0" - mkdirp "^0.5.1" - nan "^2.13.2" - node-gyp "^3.8.0" - npmlog "^4.0.0" - request "^2.88.0" - sass-graph "2.2.5" - stdout-stream "^1.4.0" - "true-case-path" "^1.0.2" - node-watch@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/node-watch/-/node-watch-0.7.1.tgz#0caaa6a6833b0d533487f953c52a6c787769ba7c" @@ -9739,13 +9583,6 @@ nodemon@^2.0.4: undefsafe "^2.0.3" update-notifier "^4.1.0" -"nopt@2 || 3": - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= - dependencies: - abbrev "1" - nopt@~1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" @@ -9839,16 +9676,6 @@ npm-run-path@^4.0.0: dependencies: path-key "^3.0.0" -"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - nth-check@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" @@ -9873,11 +9700,6 @@ num2fraction@^1.2.2: resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - numbro@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/numbro/-/numbro-2.3.2.tgz#4967c631b0ea99b17dd7f88cdd1eaa4ace4d4971" @@ -9909,6 +9731,11 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-inspect@^1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369" + integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw== + object-inspect@^1.7.0, object-inspect@^1.8.0, object-inspect@^1.9.0: version "1.9.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" @@ -9944,15 +9771,14 @@ object.assign@^4.1.0, object.assign@^4.1.1, object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" -object.entries@^1.1.0, object.entries@^1.1.1, object.entries@^1.1.2, object.entries@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.3.tgz#c601c7f168b62374541a07ddbd3e2d5e4f7711a6" - integrity sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg== +object.entries@^1.1.0, object.entries@^1.1.1, object.entries@^1.1.2, object.entries@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.4.tgz#43ccf9a50bc5fd5b649d45ab1a579f24e088cafd" + integrity sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - has "^1.0.3" + es-abstract "^1.18.2" object.fromentries@^2.0.0, object.fromentries@^2.0.4: version "2.0.4" @@ -9964,16 +9790,6 @@ object.fromentries@^2.0.0, object.fromentries@^2.0.4: es-abstract "^1.18.0-next.2" has "^1.0.3" -object.fromentries@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.3.tgz#13cefcffa702dc67750314a3305e8cb3fad1d072" - integrity sha512-IDUSMXs6LOSJBWE++L0lzIbSqHl9KDCfff2x/JSEIDtEUavUnyMYC2ZGay/04Zq4UT8lvd4xNhU4/YHKibAOlw== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - has "^1.0.3" - object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz#0dfda8d108074d9c563e80490c883b6661091544" @@ -9990,25 +9806,14 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -object.values@^1.1.0, object.values@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.2.tgz#7a2015e06fcb0f546bd652486ce8583a4731c731" - integrity sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - has "^1.0.3" - -object.values@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.3.tgz#eaa8b1e17589f02f698db093f7c62ee1699742ee" - integrity sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw== +object.values@^1.1.0, object.values@^1.1.1, object.values@^1.1.3, object.values@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.4.tgz#0d273762833e816b693a637d30073e7051535b30" + integrity sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.0-next.2" - has "^1.0.3" + es-abstract "^1.18.2" obuf@^1.0.0, obuf@^1.1.2: version "1.1.2" @@ -10107,24 +9912,6 @@ os-browserify@^0.3.0: resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-tmpdir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -osenv@0: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - p-cancelable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" @@ -10257,6 +10044,13 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parent-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-2.0.0.tgz#fa71f88ff1a50c27e15d8ff74e0e3a9523bf8708" + integrity sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg== + dependencies: + callsites "^3.1.0" + parse-asn1@^5.0.0, parse-asn1@^5.1.5: version "5.1.6" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" @@ -10411,13 +10205,6 @@ path-type@^1.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= - dependencies: - pify "^2.0.0" - path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -10523,6 +10310,13 @@ pkg-up@3.1.0: dependencies: find-up "^3.0.0" +pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= + dependencies: + find-up "^2.1.0" + pnp-webpack-plugin@1.6.4: version "1.6.4" resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" @@ -11349,11 +11143,6 @@ prr@~1.0.1: resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - psl@^1.1.28: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" @@ -11602,12 +11391,12 @@ react-fast-compare@^2.0.0: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== -react-i18next@^11.8.15: - version "11.8.15" - resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.8.15.tgz#89450d585298f18d4a8eb1628b0868863f3a4767" - integrity sha512-ZbKcbYYKukgDL0MiUWKJTEsEftjSTNVZv67/V+SjPqTRwuF/aL4NbUtuEcb4WjHk0HyZ1M+2wGd07Fp0RUNHKA== +react-i18next@^11.10.0: + version "11.10.0" + resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.10.0.tgz#f34257447e18e710e36d8fd3f721dd7d37c7004f" + integrity sha512-Vn0Xw2MczBZHKciWdayx4J+P3S9Im2FWIzUPV2O7iUVFqIOhMv6o9mVTJN1gEi/MA2FZzorjvaEijglCMeehZQ== dependencies: - "@babel/runtime" "^7.13.6" + "@babel/runtime" "^7.14.0" html-parse-stringify "^3.0.1" react-is@^16.12.0, react-is@^16.13.1, react-is@^16.3.2, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: @@ -11796,14 +11585,6 @@ read-pkg-up@^1.0.1: find-up "^1.0.0" read-pkg "^1.0.0" -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - read-pkg-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" @@ -11830,15 +11611,6 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - read-pkg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" @@ -11858,7 +11630,7 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@^2.3.7, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@^2.3.7, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -11940,7 +11712,7 @@ redux-mock-store@^1.5.4: dependencies: lodash.isplainobject "^4.0.6" -redux-promise-middleware@^6.1.2: +redux-promise-middleware@6.1.2, redux-promise-middleware@^6.1.2: version "6.1.2" resolved "https://registry.yarnpkg.com/redux-promise-middleware/-/redux-promise-middleware-6.1.2.tgz#1c14222686934be243cbb292e348ef7d5b20d6d2" integrity sha512-ZqZu/nnSzGgwTtNbGoGVontpk7LjTOv0kigtt3CcgXI9gpq+8WlfXTXRZD0WTD5yaohRq0q2nYmJXSTjwXs83Q== @@ -11999,7 +11771,7 @@ regex-parser@^2.2.11: resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== -regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.0, regexp.prototype.flags@^1.3.1: +regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== @@ -12024,10 +11796,10 @@ regexpu-core@^4.7.1: unicode-match-property-ecmascript "^1.0.4" unicode-match-property-value-ecmascript "^1.2.0" -regextras@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/regextras/-/regextras-0.7.1.tgz#be95719d5f43f9ef0b9fa07ad89b7c606995a3b2" - integrity sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w== +regextras@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/regextras/-/regextras-0.8.0.tgz#ec0f99853d4912839321172f608b544814b02217" + integrity sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ== registry-auth-token@^4.0.0: version "4.2.1" @@ -12109,7 +11881,7 @@ request-promise-native@^1.0.8: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.87.0, request@^2.88.0, request@^2.88.2: +request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -12235,12 +12007,12 @@ resolve@1.18.1: is-core-module "^2.0.0" path-parse "^1.0.6" -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.3.2, resolve@^1.8.1: - version "1.19.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" - integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.20.0, resolve@^1.3.2, resolve@^1.8.1: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== dependencies: - is-core-module "^2.1.0" + is-core-module "^2.2.0" path-parse "^1.0.6" resolve@^2.0.0-next.3: @@ -12296,7 +12068,7 @@ rgba-regex@^1.0.0: resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= -rimraf@2, rimraf@^2.5.4, rimraf@^2.6.3: +rimraf@^2.5.4, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -12440,16 +12212,6 @@ sanitize.css@^10.0.0: resolved "https://registry.yarnpkg.com/sanitize.css/-/sanitize.css-10.0.0.tgz#b5cb2547e96d8629a60947544665243b1dc3657a" integrity sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg== -sass-graph@2.2.5: - version "2.2.5" - resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.5.tgz#a981c87446b8319d96dce0671e487879bd24c2e8" - integrity sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag== - dependencies: - glob "^7.0.0" - lodash "^4.0.0" - scss-tokenizer "^0.2.3" - yargs "^13.3.2" - sass-loader@^10.0.5: version "10.1.1" resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.1.1.tgz#4ddd5a3d7638e7949065dd6e9c7c04037f7e663d" @@ -12461,6 +12223,13 @@ sass-loader@^10.0.5: schema-utils "^3.0.0" semver "^7.3.2" +sass@^1.34.1: + version "1.34.1" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.34.1.tgz#30f45c606c483d47b634f1e7371e13ff773c96ef" + integrity sha512-scLA7EIZM+MmYlej6sdVr0HRbZX5caX5ofDT9asWnUJj21oqgsC+1LuNfm0eg+vM0fCTZHhwImTiCU0sx9h9CQ== + dependencies: + chokidar ">=3.0.0 <4.0.0" + sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" @@ -12513,14 +12282,6 @@ screenfull@^5.1.0: resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-5.1.0.tgz#85c13c70f4ead4c1b8a935c70010dfdcd2c0e5c8" integrity sha512-dYaNuOdzr+kc6J6CFcBrzkLCfyGcMg+gWkJ8us93IQ7y1cevhQAugFsaCdMHb6lw8KV3xPzSxzH7zM1dQap9mA== -scss-tokenizer@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" - integrity sha1-jrBtualyMzOCTT9VMGQRSYR85dE= - dependencies: - js-base64 "^2.1.8" - source-map "^0.4.2" - select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -12567,11 +12328,6 @@ semver@^7.1.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.5, semver@~7.3.2: dependencies: lru-cache "^6.0.0" -semver@~5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" - integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= - send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -12628,7 +12384,7 @@ serve-static@1.14.1: parseurl "~1.3.3" send "0.17.1" -set-blocking@^2.0.0, set-blocking@~2.0.0: +set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= @@ -12714,7 +12470,7 @@ shellwords@^0.1.1: resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== -side-channel@^1.0.3, side-channel@^1.0.4: +side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== @@ -12851,13 +12607,6 @@ source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, sourc resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" - integrity sha1-66T12pwNyZneaAMti092FzZSA2s= - dependencies: - amdefine ">=0.0.4" - source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -13064,13 +12813,6 @@ static-extend@^0.1.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -stdout-stream@^1.4.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.1.tgz#5ac174cdd5cd726104aa0c0b2bd83815d8d535de" - integrity sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA== - dependencies: - readable-stream "^2.0.1" - stealthy-require@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" @@ -13126,23 +12868,6 @@ string-natural-compare@^3.0.1: resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" @@ -13161,28 +12886,16 @@ string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.matchall@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.3.tgz#24243399bc31b0a49d19e2b74171a15653ec996a" - integrity sha512-OBxYDA2ifZQ2e13cP82dWFMaCV9CGF8GzmN4fljBVw5O5wep0lu4gacm1OL6MjROoUnB8VbkWRThqkV2YFLNxw== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - has-symbols "^1.0.1" - internal-slot "^1.0.2" - regexp.prototype.flags "^1.3.0" - side-channel "^1.0.3" - -string.prototype.matchall@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.4.tgz#608f255e93e072107f5de066f81a2dfb78cf6b29" - integrity sha512-pknFIWVachNcyqRfaQSeu/FUfpvJTe4uskUSZ9Wc1RijsPuzbZ8TyYT8WCNnntCjUEqQ3vUHMAfVj2+wLAisPQ== +string.prototype.matchall@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz#59370644e1db7e4c0c045277690cf7b01203c4da" + integrity sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.0-next.2" - has-symbols "^1.0.1" + es-abstract "^1.18.2" + get-intrinsic "^1.1.1" + has-symbols "^1.0.2" internal-slot "^1.0.3" regexp.prototype.flags "^1.3.1" side-channel "^1.0.4" @@ -13279,13 +12992,6 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" @@ -13374,11 +13080,6 @@ stylis@^4.0.6: resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240" integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg== -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -13469,15 +13170,6 @@ tapable@^1.0.0, tapable@^1.1.3: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== -tar@^2.0.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" - integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== - dependencies: - block-stream "*" - fstream "^1.0.12" - inherits "2" - tar@^6.0.2: version "6.1.0" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" @@ -13766,13 +13458,6 @@ triple-beam@^1.2.0, triple-beam@^1.3.0: resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== -"true-case-path@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.3.tgz#f813b5a8c86b40da59606722b144e3225799f47d" - integrity sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew== - dependencies: - glob "^7.1.2" - tryer@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" @@ -13926,7 +13611,7 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.12.6.tgz#f884584fcc42e10bca70db5cb32e8625c2c42535" integrity sha512-aqWHe3DfQmZUDGWBbabZ2eQnJlQd1fKlMUu7gV+MiTuDzdgDw31bI3wA2jLLsV/hNcDP26IfyEgSVoft5+0SVw== -unbox-primitive@^1.0.0: +unbox-primitive@^1.0.0, unbox-primitive@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== @@ -14255,25 +13940,25 @@ victory-bar@^35.4.4: prop-types "^15.5.8" victory-core "^35.4.8" -victory-brush-container@^35.4.8: - version "35.4.8" - resolved "https://registry.yarnpkg.com/victory-brush-container/-/victory-brush-container-35.4.8.tgz#de8004a19c03c9a9b00e00052f682e7dad0b6892" - integrity sha512-/nTpCijvLfCr86M5P3sr8umLsRJM7GaYODqagRChcPIS5O4oEzRZsgEVhOYmWZZiS56PIjMoLAzMBvgsiwBsDg== +victory-brush-container@^35.8.1: + version "35.8.1" + resolved "https://registry.yarnpkg.com/victory-brush-container/-/victory-brush-container-35.8.1.tgz#9769760f42509a8f7062284690356edf0ce35e7c" + integrity sha512-vIPbWvxTu2T0z4lLFQI7miNwiutBJJquQR0WW0hewsGktw7Eir2VJ5sLLUyDwBF9T2gvj49HT0jrBwi/j90dsw== dependencies: lodash "^4.17.19" prop-types "^15.5.8" react-fast-compare "^2.0.0" - victory-core "^35.4.8" + victory-core "^35.8.1" -victory-brush-container@^35.5.1: - version "35.5.1" - resolved "https://registry.yarnpkg.com/victory-brush-container/-/victory-brush-container-35.5.1.tgz#fdbc5a0404da89cd2169bef89410e251b1525783" - integrity sha512-SMWlZyEhqz+VAJ+n3yoyMEPyQtMB9voikXG43Zj6KdTnVmFzTGtAis6PB24CphLaYyuxD7ko5vD62nAs9IEPfA== +victory-brush-container@^35.8.5: + version "35.8.5" + resolved "https://registry.yarnpkg.com/victory-brush-container/-/victory-brush-container-35.8.5.tgz#ca195421e65eb1da15a3e1208454c85aea34678a" + integrity sha512-BrwH8GMdsQAENnnnjXRli8rSTMpVdesk84gU5OVuWfjllfcE7XOPJN1YvuvAbU7Dn8wO3IQlaKf9YpOGX0zA3g== dependencies: lodash "^4.17.19" prop-types "^15.5.8" react-fast-compare "^2.0.0" - victory-core "^35.5.1" + victory-core "^35.8.1" victory-chart@^35.4.4: version "35.4.8" @@ -14288,24 +13973,10 @@ victory-chart@^35.4.4: victory-polar-axis "^35.4.8" victory-shared-events "^35.4.8" -victory-core@^35.4.4, victory-core@^35.4.8: - version "35.4.8" - resolved "https://registry.yarnpkg.com/victory-core/-/victory-core-35.4.8.tgz#c62a6a28b8aa8ad6bbff36e7fbe8945215ddfaf0" - integrity sha512-4yhNeeyttEe24mAG4DUPP3RvditQU+364WTnUS05ZHPrACyDWYTOfN5+L0GzmvkJ3kbteQkfX3UJgpHwwqVmug== - dependencies: - d3-ease "^1.0.0" - d3-interpolate "^1.1.1" - d3-scale "^1.0.0" - d3-shape "^1.2.0" - d3-timer "^1.0.0" - lodash "^4.17.19" - prop-types "^15.5.8" - react-fast-compare "^2.0.0" - -victory-core@^35.5.1: - version "35.5.1" - resolved "https://registry.yarnpkg.com/victory-core/-/victory-core-35.5.1.tgz#209c404458cdacccf8e64d8fbb09cf26464de13b" - integrity sha512-uzuYD5vn8VH+Wp+EFrIwQ+TCt45Vn4D0+uBh2wwie3fKfamLSmF093AeZPAxt39xCmnNTVOjfZYjUNpiuJ8rnQ== +victory-core@^35.4.4, victory-core@^35.4.8, victory-core@^35.8.1: + version "35.8.1" + resolved "https://registry.yarnpkg.com/victory-core/-/victory-core-35.8.1.tgz#39f28a88ace4f2ef2108b61ed6bb594731ac74ef" + integrity sha512-fkxZ1BtwL3C8/JeOtAML8b6GUrCkZWO5KFDqjKjkdHfs3d7DxbgXn0cxeCcUEPGd7brXQoyeFm5VKsREa4P2ig== dependencies: d3-ease "^1.0.0" d3-interpolate "^1.1.1" @@ -14317,48 +13988,39 @@ victory-core@^35.5.1: react-fast-compare "^2.0.0" victory-create-container@^35.4.4: - version "35.4.8" - resolved "https://registry.yarnpkg.com/victory-create-container/-/victory-create-container-35.4.8.tgz#d0f5d2b6d664bc29399899db15c01e59b56a3b43" - integrity sha512-1qYRi+npvvWurDjdrC2IthxvTWeKcP1nw8bw2OpL+oG21k/mQBrPGT2GtAmUBGp3e8LDr6BwrCx32FGd01PWYw== + version "35.8.1" + resolved "https://registry.yarnpkg.com/victory-create-container/-/victory-create-container-35.8.1.tgz#934f7bd663e0426b9247a16afb1c191697b55af3" + integrity sha512-6LkeywunlDxToyLhChHJ5kiSFcllQsJMjc7xpzHuT0JCfJruETWEXaXzySjsKoFUV8ogwx1I4OcRyFANqsrxXA== dependencies: lodash "^4.17.19" - victory-brush-container "^35.4.8" - victory-core "^35.4.8" - victory-cursor-container "^35.4.8" - victory-selection-container "^35.4.8" - victory-voronoi-container "^35.4.8" - victory-zoom-container "^35.4.8" - -victory-create-container@^35.5.1: - version "35.5.1" - resolved "https://registry.yarnpkg.com/victory-create-container/-/victory-create-container-35.5.1.tgz#c981e7b3cc087f8ee475c1e306d4a20338b18bef" - integrity sha512-uzumsrtiPgZcIIzKSIBlD0PTCza2VmFbyed05C1l0p6MX+ehDLQv0JWCNxi1J3crxwcWPxSqYxDqICE4JfRbGQ== - dependencies: - lodash "^4.17.19" - victory-brush-container "^35.5.1" - victory-core "^35.5.1" - victory-cursor-container "^35.5.1" - victory-selection-container "^35.5.1" - victory-voronoi-container "^35.5.1" - victory-zoom-container "^35.5.1" - -victory-cursor-container@^35.4.8: - version "35.4.8" - resolved "https://registry.yarnpkg.com/victory-cursor-container/-/victory-cursor-container-35.4.8.tgz#ca85dd05ecec929dac93c53640b6d874c725a2f7" - integrity sha512-KLQug3j4dY8nkcL5CrPqO/pz48hH9chLS86eFiN56gUzLCHx81lEujc01YrsFxQat1cOyC3LghyM+pnexLMWEQ== + victory-brush-container "^35.8.1" + victory-core "^35.8.1" + victory-cursor-container "^35.8.1" + victory-selection-container "^35.8.1" + victory-voronoi-container "^35.8.1" + victory-zoom-container "^35.8.1" + +victory-create-container@^35.8.5: + version "35.8.5" + resolved "https://registry.yarnpkg.com/victory-create-container/-/victory-create-container-35.8.5.tgz#bc0f316d5c60fca1f92cb635e8ecfa51d63fe39b" + integrity sha512-GJsIB/T3UbCS7nL+78nhHMnFeMt5a4ixi49BUx+PBLWTqAkrHuY3baoxG5HiNjQPt5XmRWCUqNu3aO/iWjeuCQ== dependencies: lodash "^4.17.19" - prop-types "^15.5.8" - victory-core "^35.4.8" - -victory-cursor-container@^35.5.1: - version "35.5.1" - resolved "https://registry.yarnpkg.com/victory-cursor-container/-/victory-cursor-container-35.5.1.tgz#5ee6f68c1bc3223af29a8b14baa37f2e1f4800b9" - integrity sha512-vLjrSDrvKiD9EclZdqN4L9VAIPMZEA28rQaODzneWukf7e8vXO9hBKRrQAYFX+fR9vJpL1WNvGLl0pzYo+Ro2w== + victory-brush-container "^35.8.5" + victory-core "^35.8.1" + victory-cursor-container "^35.8.1" + victory-selection-container "^35.8.1" + victory-voronoi-container "^35.8.4" + victory-zoom-container "^35.8.1" + +victory-cursor-container@^35.8.1: + version "35.8.1" + resolved "https://registry.yarnpkg.com/victory-cursor-container/-/victory-cursor-container-35.8.1.tgz#c7688b3f850883f7b8a4b0b864040155253dc753" + integrity sha512-PM+G19RZw4XMQiPUwkVemkt5d645BhWa5xLDGHROoXyCZ/T5zQzilq8BAFIxefbZ+eLpOFm2nTekqUhBUTKlqw== dependencies: lodash "^4.17.19" prop-types "^15.5.8" - victory-core "^35.5.1" + victory-core "^35.8.1" victory-group@^35.4.4: version "35.4.8" @@ -14418,23 +14080,14 @@ victory-scatter@^35.4.4: prop-types "^15.5.8" victory-core "^35.4.8" -victory-selection-container@^35.4.8: - version "35.4.8" - resolved "https://registry.yarnpkg.com/victory-selection-container/-/victory-selection-container-35.4.8.tgz#e356700230b731b015a0f3a8820e7c62b86c6ab7" - integrity sha512-2I2pEoUwjEltm0hJO+EwTlcrVhfvchph3OlcGp3N/Kw9q5veS/gfvcQMwur0FjS2GNwwCSjW/Gbv8zv31B/xFg== +victory-selection-container@^35.8.1: + version "35.8.1" + resolved "https://registry.yarnpkg.com/victory-selection-container/-/victory-selection-container-35.8.1.tgz#43ea8a36541200ab8e58bcada5ec8b5cbe872d35" + integrity sha512-zC0B70JquFbsm2ZH1FwpEl/mVTP5QfI/r3W5mDj7NLEhhywEjd7s4b5Sfl7lE1Kvzwto9jieimkqHqTLdg8IXA== dependencies: lodash "^4.17.19" prop-types "^15.5.8" - victory-core "^35.4.8" - -victory-selection-container@^35.5.1: - version "35.5.1" - resolved "https://registry.yarnpkg.com/victory-selection-container/-/victory-selection-container-35.5.1.tgz#cf3b5caf96fb12f8f99dc1dd97b9ec70e176a25f" - integrity sha512-wLYlHlfR/si/IqhxJjLo+oKBsPaUMBVFONaOmnsogQ3X18aP1sAWMEgrwr05WKaSqEhRP2WWea7gVpnt82D6Sg== - dependencies: - lodash "^4.17.19" - prop-types "^15.5.8" - victory-core "^35.5.1" + victory-core "^35.8.1" victory-shared-events@^35.4.8: version "35.4.8" @@ -14458,7 +14111,7 @@ victory-stack@^35.4.4: victory-core "^35.4.8" victory-shared-events "^35.4.8" -victory-tooltip@^35.4.4, victory-tooltip@^35.4.8: +victory-tooltip@^35.4.4: version "35.4.8" resolved "https://registry.yarnpkg.com/victory-tooltip/-/victory-tooltip-35.4.8.tgz#0d29276d3717cfbf500dd3d571c2087cd7c7a4c8" integrity sha512-CZLsLgfxUA6PdaIxUgIk4DJfoo5DRM70OLTZFekctQkvwt2S6Fc7DSv47ZvFw7nL6SEVaNjwsDmTZnabUJb+4Q== @@ -14467,56 +14120,47 @@ victory-tooltip@^35.4.4, victory-tooltip@^35.4.8: prop-types "^15.5.8" victory-core "^35.4.8" -victory-tooltip@^35.5.1: - version "35.5.1" - resolved "https://registry.yarnpkg.com/victory-tooltip/-/victory-tooltip-35.5.1.tgz#4d6103cf344ab8301499fb3bdf4114c49a3984e0" - integrity sha512-xcbVvOqls9PGPqS+2agUZShlreU6pGe3x/JKCbOTL/qIbU5dkcYaZ2BfqmRVq5zTSVPhgpe50Bn83cd5NfqIqg== +victory-tooltip@^35.8.1: + version "35.8.1" + resolved "https://registry.yarnpkg.com/victory-tooltip/-/victory-tooltip-35.8.1.tgz#ea596b98cdd749dabe49375c4432b4e46cb0e40e" + integrity sha512-hVsi5h05R95NKCQpE+dZHbB/zsGTORFvQEnFu/Reg1ZkTy2Uz/XiL7tjKT/gna8sL4DanhIVrju38RdwuWnmHQ== dependencies: lodash "^4.17.19" prop-types "^15.5.8" - victory-core "^35.5.1" + victory-core "^35.8.1" -victory-voronoi-container@^35.4.4, victory-voronoi-container@^35.4.8: - version "35.4.8" - resolved "https://registry.yarnpkg.com/victory-voronoi-container/-/victory-voronoi-container-35.4.8.tgz#ab25bcc5b34cacf08fe8d738b88d89c8f9c98d1c" - integrity sha512-+rQRr2SwdixwxvUSF4NUsPj7yWpkeQcQZWcPz8NNNpaCBxN1HNVQ41W7DmAZ98Spta2gkrk6888Q31zQeiGDXw== +victory-voronoi-container@^35.4.4, victory-voronoi-container@^35.8.1: + version "35.8.1" + resolved "https://registry.yarnpkg.com/victory-voronoi-container/-/victory-voronoi-container-35.8.1.tgz#710547f407a9a12b46719ac07f11ad231d19db46" + integrity sha512-rRSdRDiVM4ihtWcq6R+p5HUJ1e3WeEUahRyIttoJxdaH7EqMa09O8eGetWnwRPdC0x/NFfa4QgcTzNsFoohInA== dependencies: - delaunay-find "0.0.5" + delaunay-find "0.0.6" lodash "^4.17.19" prop-types "^15.5.8" react-fast-compare "^2.0.0" - victory-core "^35.4.8" - victory-tooltip "^35.4.8" + victory-core "^35.8.1" + victory-tooltip "^35.8.1" -victory-voronoi-container@^35.5.1: - version "35.5.1" - resolved "https://registry.yarnpkg.com/victory-voronoi-container/-/victory-voronoi-container-35.5.1.tgz#fb3b427ad36f5d48bcb976434fe2802e49988569" - integrity sha512-BuOv4WQxC/eJvqU7y7ZzMVQo034I8OZX0kqimLEnoBPep+GsK9W0uKqRzeB01O5H/onUyEmdcXs+wVEvbAYfJQ== +victory-voronoi-container@^35.8.4: + version "35.8.4" + resolved "https://registry.yarnpkg.com/victory-voronoi-container/-/victory-voronoi-container-35.8.4.tgz#11957a97f80a2363c64c06089ae6eb2c0372886b" + integrity sha512-2wBZfyIpBv2dftWRZi1vZCmB3pjpigULj+xtoavVWSqK/E3cLeczV/bcA+sjEulqIh/AGVkhF8B3DlNO6NnGFQ== dependencies: - delaunay-find "0.0.5" + delaunay-find "0.0.6" lodash "^4.17.19" prop-types "^15.5.8" react-fast-compare "^2.0.0" - victory-core "^35.5.1" - victory-tooltip "^35.5.1" - -victory-zoom-container@^35.4.4, victory-zoom-container@^35.4.8: - version "35.4.8" - resolved "https://registry.yarnpkg.com/victory-zoom-container/-/victory-zoom-container-35.4.8.tgz#4e9a86bf79245a3937b7a60163b47bc8e5ff15ae" - integrity sha512-jLHm0/wttiRIzCEdxK3SL/emNUkfc9Rt64I2Yp+9OuP+YJP+5/MkuavjjnYaVowBD3sbn6ByGBMkJ8e+Q/U7dA== - dependencies: - lodash "^4.17.19" - prop-types "^15.5.8" - victory-core "^35.4.8" + victory-core "^35.8.1" + victory-tooltip "^35.8.1" -victory-zoom-container@^35.5.1: - version "35.5.1" - resolved "https://registry.yarnpkg.com/victory-zoom-container/-/victory-zoom-container-35.5.1.tgz#f80f9c53222e4a5934dca8b18bf66724b5f3a2fb" - integrity sha512-UuMhIqv/NzYKlibiY5l3hluCdKftw0GCHDiXAmPRfyfodc1qDolysPMSwxpUSBQ9RT+XzPHJAatZH2Nw8G5ZIQ== +victory-zoom-container@^35.4.4, victory-zoom-container@^35.8.1: + version "35.8.1" + resolved "https://registry.yarnpkg.com/victory-zoom-container/-/victory-zoom-container-35.8.1.tgz#ac58df9583d56aedc39ea79b0f07a52bc790a1c6" + integrity sha512-oj5etFgaMv0p+TZG2lDIkTxvKe1GReq/hs+rlvk3QWT9qVfek7a3Si1nA6/NCtdvzsSe75+++G+clwjjvuz/Pg== dependencies: lodash "^4.17.19" prop-types "^15.5.8" - victory-core "^35.5.1" + victory-core "^35.8.1" vm-browserify@^1.0.1: version "1.1.2" @@ -14784,7 +14428,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@1, which@^1.2.9, which@^1.3.1: +which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -14798,13 +14442,6 @@ which@^2.0.1, which@^2.0.2: dependencies: isexe "^2.0.0" -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - widest-line@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" @@ -15096,11 +14733,6 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18" integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg== -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" @@ -15178,7 +14810,7 @@ yargs@^15.4.1: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^16.0.0, yargs@^16.2.0: +yargs@^16.0.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== @@ -15191,6 +14823,19 @@ yargs@^16.0.0, yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yargs@^17.0.1: + version "17.0.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.0.1.tgz#6a1ced4ed5ee0b388010ba9fd67af83b9362e0bb" + integrity sha512-xBBulfCc8Y6gLFcrPvtqKz9hz8SO0l1Ni8GgDekvBX2ro0HRQImDGnikfc33cgzcYUSncapnNcZDjVFIH3f6KQ== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"