diff --git a/.eslintrc b/.eslintrc index 58767d6d5..7a05daac8 100644 --- a/.eslintrc +++ b/.eslintrc @@ -46,7 +46,8 @@ "mockWindowLocation": "readonly", "shallowHook": "readonly", "shallowHookComponent": "readonly", - "shallowHookWrapper": "readonly" + "shallowHookWrapper": "readonly", + "skipIt": "readonly" }, "rules": { "arrow-parens": [ @@ -74,6 +75,10 @@ "import/no-named-as-default": 0, "import/no-named-as-default-member": 0, "jest/no-done-callback": 0, + "jest/no-standalone-expect": [ + 2, + { "additionalTestBlockFunctions": ["skipIt"] } + ], "jest/prefer-to-have-length": 0, "jsdoc/check-tag-names": [ 2, diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 8e47e9302..08702c2eb 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -41,7 +41,7 @@ jobs: } - name: Code coverage if: ${{ success() }} - uses: codecov/codecov-action@v2.1.0 + uses: codecov/codecov-action@v3.1.0 - name: Confirm beta integration if: ${{ success() }} uses: actions/github-script@v6 diff --git a/config/build.plugins.js b/config/build.plugins.js index cee330ee4..c19413022 100644 --- a/config/build.plugins.js +++ b/config/build.plugins.js @@ -6,11 +6,6 @@ const fedModulePlugin = require('@redhat-cloud-services/frontend-components-conf const { setupWebpackDotenvFilesForEnv } = require('./build.dotenv'); const { dependencies } = require('../package.json'); -const setHtmlPlugin = () => ({ - title: process.env.REACT_APP_UI_DISPLAY_NAME, - template: join(process.env._BUILD_STATIC_DIR, 'index.html') -}); - const setReplacePlugin = () => [ { pattern: /%([A-Z_]+)%/g, @@ -62,6 +57,5 @@ const setCommonPlugins = () => { module.exports = { setCommonPlugins, - setHtmlPlugin, setReplacePlugin }; diff --git a/config/jest.setupTests.js b/config/jest.setupTests.js index 74ee6503c..dd6cee87b 100644 --- a/config/jest.setupTests.js +++ b/config/jest.setupTests.js @@ -17,6 +17,17 @@ setupDotenvFilesForEnv({ env: process.env.NODE_ENV }); */ configure({ adapter: new Adapter() }); +/** + * Conditionally skip "it" test statements. + * Ex: + * skipIt(true)('should do a thing...', () => { ... }); + * + * @param {*|boolean} value Any truthy value, typically used with environment variables + * + * @returns {*|jest.It} + */ +global.skipIt = value => (value && it?.skip) || it; + /** * Emulate for component checks */ diff --git a/config/webpack.dev.config.js b/config/webpack.dev.config.js index e5af81a42..2cf8d8c84 100644 --- a/config/webpack.dev.config.js +++ b/config/webpack.dev.config.js @@ -1,5 +1,5 @@ const config = require('@redhat-cloud-services/frontend-components-config'); -const { setHtmlPlugin, setReplacePlugin, setCommonPlugins } = require('./build.plugins'); +const { setReplacePlugin, setCommonPlugins } = require('./build.plugins'); const { setupDotenvFilesForEnv } = require('./build.dotenv'); const { setDevRoutes } = require('./spandx.config'); @@ -16,7 +16,6 @@ const { config: webpackConfig, plugins } = config({ routes: setDevRoutes(), standalone: true, useProxy: false, - htmlPlugin: setHtmlPlugin(), replacePlugin: setReplacePlugin() }); diff --git a/config/webpack.prod.config.js b/config/webpack.prod.config.js index 8b8842690..2e98ccbd3 100644 --- a/config/webpack.prod.config.js +++ b/config/webpack.prod.config.js @@ -1,6 +1,6 @@ const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); const config = require('@redhat-cloud-services/frontend-components-config'); -const { setHtmlPlugin, setReplacePlugin, setCommonPlugins } = require('./build.plugins'); +const { setReplacePlugin, setCommonPlugins } = require('./build.plugins'); const { setupDotenvFilesForEnv } = require('./build.dotenv'); const { @@ -12,7 +12,6 @@ const { const { config: webpackConfig, plugins } = config({ rootFolder: _BUILD_RELATIVE_DIRNAME, deployment: (/beta/.test(BETA_PREFIX) && 'beta/apps') || 'apps', - htmlPlugin: setHtmlPlugin(), replacePlugin: setReplacePlugin() }); diff --git a/config/webpack.proxy.config.js b/config/webpack.proxy.config.js index 61afda5d1..b85c7a38a 100644 --- a/config/webpack.proxy.config.js +++ b/config/webpack.proxy.config.js @@ -1,5 +1,5 @@ const config = require('@redhat-cloud-services/frontend-components-config'); -const { setHtmlPlugin, setReplacePlugin, setCommonPlugins } = require('./build.plugins'); +const { setReplacePlugin, setCommonPlugins } = require('./build.plugins'); const { setupDotenvFilesForEnv } = require('./build.dotenv'); const { setProxyRoutes } = require('./spandx.config'); @@ -28,7 +28,6 @@ const { config: webpackConfig, plugins } = config({ routes: setProxyRoutes({ DEV_PORT, BETA_PREFIX }), standalone: false, useProxy: true, - htmlPlugin: setHtmlPlugin(), replacePlugin: setReplacePlugin() }); diff --git a/deploy/build_deploy.sh b/deploy/build_deploy.sh new file mode 100755 index 000000000..7d356f566 --- /dev/null +++ b/deploy/build_deploy.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# -------------------------------------------- +# Export vars for helper scripts to use +# -------------------------------------------- +# name of app-sre "application" folder this component lives in; needs to match for quay +export COMPONENT="rhsm" +# IMAGE should match the quay repo set by app.yaml in app-interface +export IMAGE="quay.io/cloudservices/curiosity-frontend" +export APP_NAME=`node -e 'console.log(require("./package.json").insights.appname)'` +export APP_ROOT=$(pwd) +export NODE_BUILD_VERSION=`node -e 'console.log(require("./package.json").engines.node.match(/(\d+)\.\d+\.\d+/)[1])'` +COMMON_BUILDER=https://raw.githubusercontent.com/RedHatInsights/insights-frontend-builder-common/master + +# -------------------------------------------- +# Options that must be configured by app owner +# -------------------------------------------- +IQE_PLUGINS="curiosity" +IQE_MARKER_EXPRESSION="smoke" +IQE_FILTER_EXPRESSION="" + +set -exv +# source is preferred to | bash -s in this case to avoid a subshell +source <(curl -sSL $COMMON_BUILDER/src/frontend-build.sh) +BUILD_RESULTS=$? + +# Stubbed out for now +mkdir -p $WORKSPACE/artifacts +cat << EOF > $WORKSPACE/artifacts/junit-dummy.xml + + + +EOF + +# teardown_docker +exit $BUILD_RESULTS diff --git a/deploy/frontend.yaml b/deploy/frontend.yaml new file mode 100644 index 000000000..d96537a06 --- /dev/null +++ b/deploy/frontend.yaml @@ -0,0 +1,82 @@ +apiVersion: v1 +kind: Template +metadata: + name: rhsm-frontend +objects: + - apiVersion: cloud.redhat.com/v1alpha1 + kind: Frontend + metadata: + # this must match appList value in frontend-configs/deploy/deploy.yaml + name: subscriptions + spec: + envName: ${ENV_NAME} + title: rhsm + deploymentRepo: https://github.com/RedHatInsights/curiosity-frontend + API: + versions: + - v1 + frontend: + paths: + - /apps/subscriptions + image: ${IMAGE}:${IMAGE_TAG} + navItems: + # use *-navigation.json in cloud-services-config for reference + - title: "Subscriptions" + expandable: true + routes: + - appId: "subscriptions" + title: "All RHEL" + href: "/insights/subscriptions/rhel" + product: "Subscription Watch" + - appId: "subscriptions" + title: "ARM" + href: "/insights/subscriptions/rhel-arm" + product: "Subscription Watch" + - appId: "subscriptions" + title: "IBM Power" + href: "/insights/subscriptions/rhel-ibmpower" + product: "Subscription Watch" + - appId: "subscriptions" + title: "IBM Z systems" + href: "/insights/subscriptions/rhel-ibmz" + product: "Subscription Watch" + - appId: "subscriptions" + title: "X86" + href: "/insights/subscriptions/rhel-x86" + product: "Subscription Watch" + - appId: "subscriptions" + title: "OpenShift Subscriptions" + href: "/openshift/subscriptions/openshift-container" + product: "Subscription Watch" + - appId: "subscriptions" + title: "Dedicated (On-Demand)" + href: "/openshift/subscriptions/openshift-dedicated" + product: "Subscription Watch" + - appId: "subscriptions" + title: "Streams for Apache Kafka" + href: "/application-services/subscriptions/streams" + product: "Subscription Watch" + module: + # this should match chrome/fed-modules.json in cloud-services-config + manifestLocation: "/apps/subscriptions/fed-mods.json" + modules: + - id: "application-services-subscriptions" + module: "./RootApp" + routes: + - pathname: "/application-services/subscriptions" + - id: "insights-subscriptions" + module: "./RootApp" + routes: + - pathname: "/insights/subscriptions" + - id: "openshift-subscriptions" + module: "./RootApp" + routes: + - pathname: "/openshift/subscriptions" + +parameters: + - name: ENV_NAME + required: true + - name: IMAGE_TAG + required: true + - name: IMAGE + value: quay.io/cloudservices/rhsm-frontend diff --git a/deploy/pr_check.sh b/deploy/pr_check.sh new file mode 100755 index 000000000..acdd4dfdf --- /dev/null +++ b/deploy/pr_check.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# -------------------------------------------- +# Export vars for helper scripts to use +# -------------------------------------------- +# name of app-sre "application" folder this component lives in; needs to match for quay +export COMPONENT="rhsm" +# IMAGE should match the quay repo set by app.yaml in app-interface +export IMAGE="quay.io/cloudservices/curiosity-frontend" +export WORKSPACE=${WORKSPACE:-$APP_ROOT} # if running in jenkins, use the build's workspace +export APP_ROOT=$(pwd) +export NODE_BUILD_VERSION=`node -e 'console.log(require("./package.json").engines.node.match(/(\d+)\.\d+\.\d+/)[1])'` +COMMON_BUILDER=https://raw.githubusercontent.com/RedHatInsights/insights-frontend-builder-common/master + +# -------------------------------------------- +# Options that must be configured by app owner +# -------------------------------------------- +IQE_PLUGINS="curiosity" +IQE_MARKER_EXPRESSION="smoke" +IQE_FILTER_EXPRESSION="" + +set -exv +# source is preferred to | bash -s in this case to avoid a subshell +source <(curl -sSL $COMMON_BUILDER/src/frontend-build.sh) +BUILD_RESULTS=$? + +# Stubbed out for now +mkdir -p $WORKSPACE/artifacts +cat << EOF > $WORKSPACE/artifacts/junit-dummy.xml + + + +EOF + +# teardown_docker +exit $BUILD_RESULTS diff --git a/package.json b/package.json index f76a3f4e2..8c134bd40 100644 --- a/package.json +++ b/package.json @@ -54,10 +54,13 @@ "api:docs": "node ./scripts/openapi.docs.js", "api:proxy-hosts": "bash ./scripts/proxy.api.sh", "build": "run-s -l build:pre build:js build:post test:integration", + "build:deps": "bash ./scripts/dependencies.sh --doctor -u --doctorInstall \"yarn\" --doctorTest \"yarn test:deps\" --reject \"@patternfly/*, @redhat-cloud-services/frontend*, victory*\"", + "build:deps-core": "bash ./scripts/dependencies.sh --doctor -u --doctorInstall \"yarn\" --doctorTest \"yarn test:deps\" --filter \"@patternfly/*, @redhat-cloud-services/frontend*, victory*\"", + "build:ephemeral": "run-s -l build:pre build:js build:post test:integration-ephemeral", "build:js": "export NODE_ENV=production; webpack --config config/webpack.prod.config.js", "build:post": "bash ./scripts/post.sh", "build:pre": "bash ./scripts/pre.sh", - "build:deps": "bash ./scripts/dependencies.sh --doctor -u --doctorInstall \"yarn\" --doctorTest \"yarn test:deps\" --reject \"@patternfly/*, @redhat-cloud-services/frontend*, victory*\"", + "build:prod": "run-s build:ephemeral", "dev:chrome": "bash ./scripts/dev.chrome.sh -b prod-stable", "release": "standard-version", "start": "run-p -l api:dev start:js", @@ -66,48 +69,52 @@ "start:proxy": "run-s -l api:proxy-hosts start:js-proxy", "test": "export NODE_ENV=test; run-s test:spell* test:lint test:ci", "test:ci": "export CI=true; jest ./src --coverage", + "test:ci-ephemeral": "export CI=true; TZ=UTC jest ./src --coverage --no-cache", + "test:ephemeral": "export NODE_ENV=test; run-s test:spell* test:lint test:ci-ephemeral", "test:clearCache": "jest --clearCache", "test:dev": "export NODE_ENV=test; run-s test:spell test:lint test:local", "test:deps": "run-s test build", "test:integration": "jest ./tests", + "test:integration-ephemeral": "TZ=UTC jest ./tests --no-cache --testPathIgnorePatterns ./tests/dist.test.js", "test:integration-dev": "jest --roots=./tests --watch", "test:lint": "eslint --ext=json --ext=js --ext=jsx src", "test:spell-support": "cspell ./README.md ./config/README.md ./CONTRIBUTING.md --config ./config/cspell.config.json", "test:spell": "cspell './public/locales/**/en*json' './src/**/*.js' --config ./config/cspell.config.json", - "test:local": "jest --roots=./src --watch" + "test:local": "jest --roots=./src --watch", + "verify": "run-s test:ephemeral build:ephemeral" }, "dependencies": { "@joi/date": "^2.1.0", - "@patternfly/patternfly": "4.183.1", + "@patternfly/patternfly": "4.192.1", "@patternfly/react-charts": "6.51.19", "@patternfly/react-core": "4.198.19", "@patternfly/react-icons": "4.49.19", "@patternfly/react-styles": "4.48.19", "@patternfly/react-table": "4.67.19", "@patternfly/react-tokens": "4.50.19", - "@redhat-cloud-services/frontend-components": "3.8.3", + "@redhat-cloud-services/frontend-components": "3.8.12", "@redhat-cloud-services/frontend-components-notifications": "3.2.5", - "@redhat-cloud-services/frontend-components-utilities": "3.2.12", + "@redhat-cloud-services/frontend-components-utilities": "3.2.16", "axios": "^0.26.1", "classnames": "^2.3.1", - "i18next": "^21.6.14", + "i18next": "^21.6.16", "i18next-xhr-backend": "^3.2.2", "joi": "^17.6.0", "js-cookie": "^3.0.1", "locale-code": "^2.0.2", "lodash": "^4.17.21", - "lru-cache": "^7.7.1", + "lru-cache": "^7.9.0", "moment": "^2.29.1", "numbro": "^2.3.6", "prop-types": "^15.8.1", "react": "^17.0.2", "react-dom": "^17.0.2", - "react-i18next": "^11.16.2", + "react-i18next": "^11.16.7", "react-redux": "^7.2.6", - "react-router": "^5.2.1", - "react-router-dom": "^5.3.0", + "react-router": "5.3.1", + "react-router-dom": "5.3.0", "react-use": "^17.3.2", - "redux": "^4.1.2", + "redux": "^4.2.0", "redux-logger": "^3.0.6", "redux-promise-middleware": "^6.1.2", "redux-thunk": "^2.4.1", @@ -116,43 +123,43 @@ "victory-create-container": "36.3.1" }, "devDependencies": { - "@babel/core": "7.17.8", + "@babel/core": "7.17.10", "@babel/eslint-parser": "^7.17.0", - "@redhat-cloud-services/frontend-components-config": "4.6.6", - "@wojtekmaj/enzyme-adapter-react-17": "^0.6.6", - "apidoc-mock": "^4.0.2", - "babel-jest": "^27.5.1", + "@redhat-cloud-services/frontend-components-config": "4.6.11", + "@wojtekmaj/enzyme-adapter-react-17": "^0.6.7", + "apidoc-mock": "^4.0.3", + "babel-jest": "^28.0.3", "babel-preset-react-app": "^10.0.1", "copy-webpack-plugin": "^10.2.4", - "cspell": "^5.19.3", + "cspell": "^5.20.0", "dotenv": "^16.0.0", "dotenv-expand": "^8.0.3", "dotenv-webpack": "^7.1.0", "enzyme": "^3.11.0", "enzyme-to-json": "^3.6.2", - "eslint": "8.11.0", + "eslint": "8.14.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-prettier": "^8.5.0", - "eslint-config-react-app": "^7.0.0", + "eslint-config-react-app": "^7.0.1", "eslint-plugin-flowtype": "^8.0.3", "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.3", - "eslint-plugin-jsdoc": "^38.0.6", + "eslint-plugin-jest": "^26.1.5", + "eslint-plugin-jsdoc": "^39.2.9", "eslint-plugin-json": "^3.1.0", "eslint-plugin-jsx-a11y": "^6.5.1", "eslint-plugin-prettier": "^4.0.0", "eslint-plugin-react": "^7.28.0", "eslint-plugin-react-hooks": "^4.3.0", "eslint-webpack-plugin": "^3.1.1", - "express": "^4.17.3", - "glob": "^7.2.0", + "express": "^4.18.1", + "glob": "^8.0.1", "jest": "27.5.1", - "jest-resolve": "27.5.1", - "jest-watch-typeahead": "1.0.0", + "jest-resolve": "28.0.3", + "jest-watch-typeahead": "1.1.0", "moxios": "^0.4.0", - "npm-check-updates": "^12.5.4", + "npm-check-updates": "^12.5.11", "npm-run-all": "^4.1.5", - "prettier": "^2.6.1", + "prettier": "^2.6.2", "redux-mock-store": "^1.5.4", "standard-version": "^9.3.2", "swagger-ui-express": "^4.3.0", diff --git a/public/index.html b/public/index.html deleted file mode 100644 index 447aeeb74..000000000 --- a/public/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - %REACT_APP_UI_DISPLAY_NAME% - - - - - - diff --git a/public/locales/en-US.json b/public/locales/en-US.json index ea4a90844..193aa859d 100644 --- a/public/locales/en-US.json +++ b/public/locales/en-US.json @@ -16,6 +16,7 @@ "cardHeading_sockets": "CPU socket usage", "cardHeading_Instance-hours": "Instance hours", "cardHeading_Storage-gibibytes": "Data storage", + "cardHeading_Storage-gibibyte-months": "Data storage", "cardHeading_Transfer-gibibytes": "Data transfer", "cardHeading_OpenShift Container Platform": "Annual subscriptions", "cardHeading_OpenShift-metrics": "On-Demand subscriptions", @@ -31,6 +32,7 @@ "cardHeadingDescription": "...", "cardHeadingDescription_Instance-hours": "Instance hours usage in hours", "cardHeadingDescription_Storage-gibibytes": "Data storage usage in binary gigabyte hours", + "cardHeadingDescription_Storage-gibibyte-months": "Data storage usage in binary gigabyte months", "cardHeadingDescription_Transfer-gibibytes": "Data transfer usage in binary gigabytes", "cardHeadingDescription_OpenShift Container Platform": "A pre-paid subscription model that offers a designated maximum quota of units within a set time frame.", "cardHeadingDescription_OpenShift-metrics": "A subscription model that offers purchasing options to match your usage patterns.", @@ -38,19 +40,23 @@ "cardHeadingMetric_dailyTotal": "Daily total", "cardHeadingMetric_dailyTotal_Instance-hours": "Daily instance hours", "cardHeadingMetric_dailyTotal_Storage-gibibytes": "Daily data storage", + "cardHeadingMetric_dailyTotal_Storage-gibibyte-months": "Daily data storage", "cardHeadingMetric_dailyTotal_Transfer-gibibytes": "Daily data transfer", "cardHeadingMetric_monthlyTotal": "Monthly total", "cardHeadingMetric_monthlyTotal_Instance-hours": "Monthly instance hours", "cardHeadingMetric_monthlyTotal_Storage-gibibytes": "Monthly data storage", + "cardHeadingMetric_monthlyTotal_Storage-gibibyte-months": "Monthly data storage", "cardHeadingMetric_monthlyTotal_Transfer-gibibytes": "Monthly data transfer", "cardBodyMetric_total": "No data", "cardBodyMetric_total_Instance-hours": "<0>{{total}} Instance hours", "cardBodyMetric_total_Storage-gibibytes": "<0>{{total}} Binary gigabyte hours", + "cardBodyMetric_total_Storage-gibibyte-months": "<0>{{total}} Binary gigabyte months", "cardBodyMetric_total_Transfer-gibibytes": "<0>{{total}} Binary gigabytes", "cardFooterMetric": "Last update {{date}}", "label_axisX_Daily": "Day of the month", "label_axisY_Instance-hours": "Instance hours", "label_axisY_Storage-gibibytes": "Binary gigabyte hours", + "label_axisY_Storage-gibibyte-months": "Binary gigabyte months", "label_axisY_Transfer-gibibytes": "Binary gigabytes", "label_cores": "Cores", "label_coreHours": "Core hours", @@ -66,6 +72,7 @@ "label_noData": "no data", "label_noData_error": "No data", "label_Storage-gibibytes": "Data storage", + "label_Storage-gibibyte-months": "Data storage", "label_threshold": "Subscription threshold", "label_threshold_infinite": "unlimited", "label_Transfer-gibibytes": "Data transfer", @@ -84,6 +91,7 @@ "legendTooltip_physicalSockets_RHEL": "Physical {{product}} CPU usage, per socket pair. Each system's socket count is rounded upwards to the next even number.", "legendTooltip_sockets": "{{product}} CPU usage, per CPU socket pair.", "legendTooltip_Storage-gibibytes": "Data storage usage", + "legendTooltip_Storage-gibibyte-months": "Data storage usage", "legendTooltip_threshold_thresholdSockets": "Maximum capacity, based on total {{product}} subscriptions in this account.", "legendTooltip_threshold_thresholdSockets_RHEL": "Maximum capacity, as CPU sockets, based on total {{product}} subscriptions in this account.", "legendTooltip_threshold_thresholdCores_OpenShift Container Platform": "Maximum capacity, as CPU cores, based on total {{product}} Annual subscriptions in this account.", @@ -106,10 +114,13 @@ "tableEmptyInventoryTitle": "No results found", "tableEmptyInventoryMessage": "No results match the filter criteria. Remove filters or clear all filters to show results.", "tableSkeletonAriaLabel": "Loading", - "label_hasInfiniteQuantity_cores": "Unlimited cores", - "label_hasInfiniteQuantity_sockets": "Unlimited sockets", + "label_has_infinite_quantity_cores": "Unlimited cores", + "label_has_infinite_quantity_sockets": "Unlimited sockets", "label_numberOfGuests_one": "<0>{{count}} guest", "label_numberOfGuests_other": "<0>{{count}} guests", + "label_subscription_type": "{{context}}", + "label_subscription_type_Annual": "Annual", + "label_subscription_type_On-demand": "On-Demand", "cloudProvider": "{{context}}", "cloudProvider_alibaba": "Alibaba", "cloudProvider_aws": "AWS", @@ -122,6 +133,7 @@ "hardwareType_physical": "Physical", "hardwareType_virtualized": "Virtual", "header": "{{context}}", + "header_billing_provider": "Purchased through", "header_cores": "Subscribed cores", "header_cores_OpenShift Container Platform": "Cores", "header_cores_OpenShift-metrics": "Cores", @@ -141,19 +153,30 @@ "header_sockets_OpenShift-dedicated-metrics": "Sockets", "header_lastSeen": "Last seen", "header_last_seen": "Last seen", - "header_nextEventDate": "Next renewal", - "header_productName": "Product", + "header_next_event_date": "Next renewal", + "header_product_name": "Product", "header_quantity": "Quantity", - "header_serviceLevel": "Service level", + "header_service_level": "Service level", "header_Storage-gibibytes": "Data storage", + "header_Storage-gibibyte-months": "Data storage", "header_subscriptions": "Sockets", "header_subscriptions_cores": "Cores", "header_subscriptions_sockets": "Sockets", + "header_subscription_type": "Subscription type", "header_Transfer-gibibytes": "Data transfer", "header_tooltip_Storage-gibibytes": "Measurements in binary gigabyte hours", + "header_tooltip_Storage-gibibyte-months": "Measurements in binary gigabyte months", "header_tooltip_Transfer-gibibytes": "Measurements in binary gigabytes", + "measurement_billing_provider": "Unknown", + "measurement_billing_provider_aws": "AWS", + "measurement_billing_provider_azure": "Azure", + "measurement_billing_provider_gcp": "GCP", + "measurement_billing_provider_none": "None", + "measurement_billing_provider_oracle": "Oracle", + "measurement_billing_provider_red hat": "Red Hat", "measurement_Instance-hours": "{{total}} hours", "measurement_Storage-gibibytes": "{{total}} GB hours", + "measurement_Storage-gibibyte-months": "{{total}} GB months", "measurement_Transfer-gibibytes": "{{total}} GB", "measurementType": "{{context}}", "measurementType_cloud": "Public cloud", @@ -168,6 +191,7 @@ }, "curiosity-toolbar": { "category": "Filter by", + "category_billing_provider": "Purchased through", "category_granularity": "Granularity", "category_rangedMonthly": "Monthly", "category_sla": "SLA", @@ -176,18 +200,26 @@ "clearFilters": "Reset filters", "button_displayName": "Search button for name", "placeholder": "Select", + "placeholder_billing_provider": "Select purchased through", "placeholder_granularity": "Select date range", "placeholder_rangedMonthly": "Select a month", "placeholder_sla": "Select SLA", "placeholder_uom": "Select unit", "placeholder_usage": "Select usage", "placeholder_filter": "Filter by", + "placeholder_filter_billing_provider": "Filter by purchased through", "placeholder_filter_displayName": "Filter by name", "placeholder_filter_granularity": "Filter by date", "placeholder_filter_rangedMonthly": "Filter by month", "placeholder_filter_sla": "Filter by SLA", "placeholder_filter_uom": "Filter by unit", "placeholder_filter_usage": "Filter by usage", + "billing_provider": "None", + "billing_provider_aws": "Amazon Web Services", + "billing_provider_azure": "Microsoft Azure", + "billing_provider_gcp": "Google Cloud Platform", + "billing_provider_oracle": "Oracle Cloud Infrastructure", + "billing_provider_red hat": "Red Hat Marketplace", "granularity_Daily": "Daily", "granularity_Weekly": "Weekly", "granularity_Monthly": "Monthly", diff --git a/scripts/pre.sh b/scripts/pre.sh index 6ac6b4681..c5c1596b0 100644 --- a/scripts/pre.sh +++ b/scripts/pre.sh @@ -36,6 +36,7 @@ version() clean() { echo "Cleaning build directories, files..." + rm -rf -- ./dist rm -rf -- ./build rm -rf -- ./public/apps rm -f ./.env.production.local diff --git a/src/components/authentication/__tests__/__snapshots__/authentication.test.js.snap b/src/components/authentication/__tests__/__snapshots__/authentication.test.js.snap index ff5310afa..37c975ee6 100644 --- a/src/components/authentication/__tests__/__snapshots__/authentication.test.js.snap +++ b/src/components/authentication/__tests__/__snapshots__/authentication.test.js.snap @@ -49,16 +49,9 @@ exports[`Authentication Component should render a basic component: basic 1`] = ` exports[`Authentication Component should render a component authorized: authorized 1`] = ` { it('should render a component error', async () => { const props = { - useAuth: () => ({ + useGetAuthorization: () => ({ error: true, pending: false, data: { @@ -50,7 +50,7 @@ describe('Authentication Component', () => { it('should return a redirect on 418 error', async () => { const props = { - useAuth: () => ({ + useGetAuthorization: () => ({ error: true, pending: false, data: { @@ -71,7 +71,7 @@ describe('Authentication Component', () => { it('should return a redirect on a specific 403 error and error code', async () => { const props = { - useAuth: () => ({ + useGetAuthorization: () => ({ error: true, pending: false, data: { @@ -101,7 +101,7 @@ describe('Authentication Component', () => { it('should return a message on 401 error', async () => { const props = { - useAuth: () => ({ + useGetAuthorization: () => ({ error: true, pending: false, data: { @@ -122,7 +122,7 @@ describe('Authentication Component', () => { it('should render a component pending', async () => { const props = { - useAuth: () => ({ + useGetAuthorization: () => ({ error: false, pending: true, data: { @@ -143,7 +143,7 @@ describe('Authentication Component', () => { it('should render a component authorized', async () => { const props = { - useAuth: () => ({ + useGetAuthorization: () => ({ error: false, pending: false, data: { diff --git a/src/components/authentication/__tests__/authenticationContext.test.js b/src/components/authentication/__tests__/authenticationContext.test.js index 917a07587..c0e1eebc5 100644 --- a/src/components/authentication/__tests__/authenticationContext.test.js +++ b/src/components/authentication/__tests__/authenticationContext.test.js @@ -1,4 +1,4 @@ -import { context, useAuth, useSession } from '../authenticationContext'; +import { context, useGetAuthorization, useSession } from '../authenticationContext'; import { rhsmConstants } from '../../../services/rhsm/rhsmConstants'; describe('AuthenticationContext', () => { @@ -8,7 +8,7 @@ describe('AuthenticationContext', () => { it('should apply a hook for retrieving auth data from multiple selectors', () => { const { result: errorResponse } = shallowHook(() => - useAuth({ + useGetAuthorization({ useSelectorsResponse: () => ({ error: true, data: { @@ -30,7 +30,7 @@ describe('AuthenticationContext', () => { expect(errorResponse).toMatchSnapshot('error response'); const { result: successResponse } = shallowHook(() => - useAuth({ + useGetAuthorization({ useSelectorsResponse: () => ({ fulfilled: true, data: { @@ -49,7 +49,7 @@ describe('AuthenticationContext', () => { expect(successResponse).toMatchSnapshot('success response'); - const { result: mockStoreSuccessResponse } = shallowHook(() => useAuth(), { + const { result: mockStoreSuccessResponse } = shallowHook(() => useGetAuthorization(), { state: { user: { auth: { @@ -85,7 +85,7 @@ describe('AuthenticationContext', () => { expect(mockStoreSuccessResponse).toMatchSnapshot('mock store success response'); - const { result: mockStoreErrorResponse } = shallowHook(() => useAuth(), { + const { result: mockStoreErrorResponse } = shallowHook(() => useGetAuthorization(), { state: { user: { auth: { diff --git a/src/components/authentication/authentication.js b/src/components/authentication/authentication.js index a091fa30b..ec33f8453 100644 --- a/src/components/authentication/authentication.js +++ b/src/components/authentication/authentication.js @@ -1,71 +1,31 @@ -import React, { useState } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import { BinocularsIcon } from '@patternfly/react-icons'; import { Maintenance } from '@redhat-cloud-services/frontend-components/Maintenance'; import { NotAuthorized } from '@redhat-cloud-services/frontend-components/NotAuthorized'; -import { useMount, useUnmount } from 'react-use'; -import { reduxActions, storeHooks } from '../../redux'; -import { routerHooks } from '../../hooks/useRouter'; import { routerHelpers, Redirect } from '../router'; import { rhsmConstants } from '../../services/rhsm/rhsmConstants'; import { helpers } from '../../common'; import MessageView from '../messageView/messageView'; import { translate } from '../i18n/i18n'; -import { AuthenticationContext, useAuth } from './authenticationContext'; +import { AuthenticationContext, useGetAuthorization } from './authenticationContext'; /** * An authentication pass-through component. * * @param {object} props * @param {string} props.appName - * @param {Function} props.authorizeUser * @param {React.ReactNode} props.children - * @param {Function} props.hideGlobalFilter - * @param {Function} props.initializeChrome * @param {boolean} props.isDisabled - * @param {Function} props.onNavigation - * @param {Function} props.setAppName * @param {Function} props.t - * @param {Function} props.useAuth - * @param {Function} props.useDispatch - * @param {Function} props.useHistory + * @param {Function} props.useGetAuthorization * @returns {React.ReactNode} */ -const Authentication = ({ - appName, - authorizeUser, - children, - hideGlobalFilter, - initializeChrome, - isDisabled, - onNavigation, - setAppName, - t, - useAuth: useAliasAuth, - useDispatch: useAliasDispatch, - useHistory: useAliasHistory -}) => { - const [unregister, setUnregister] = useState(() => helpers.noop); - const dispatch = useAliasDispatch(); - const history = useAliasHistory(); - - const { pending, data: authData = {} } = useAliasAuth(); - const { authorized = {}, errorCodes, errorStatus } = authData; +const Authentication = ({ appName, children, isDisabled, t, useGetAuthorization: useAliasGetAuthorization }) => { + const { pending, data = {} } = useAliasGetAuthorization(); + const { authorized = {}, errorCodes, errorStatus } = data; const { [appName]: isAuthorized } = authorized; - useMount(async () => { - if (!isAuthorized) { - await dispatch(authorizeUser()); - } - - dispatch([initializeChrome(), setAppName(appName), hideGlobalFilter()]); - setUnregister(() => dispatch(onNavigation(event => history.push(event.navId)))); - }); - - useUnmount(() => { - unregister(); - }); - const renderContent = () => { if (isDisabled) { return ( @@ -97,50 +57,32 @@ const Authentication = ({ ); }; - return {renderContent()}; + return {renderContent()}; }; /** * Prop types. * - * @type {{authorizeUser: Function, onNavigation: Function, useHistory: Function, setAppName: Function, t: Function, - * children: React.ReactNode, appName: string, initializeChrome: Function, useDispatch: Function, - * isDisabled: boolean, useAuth: Function,hideGlobalFilter: Function}} + * @type {{useGetAuthorization: Function, children: React.ReactNode, appName: string, isDisabled: boolean}} */ Authentication.propTypes = { appName: PropTypes.string, - authorizeUser: PropTypes.func, children: PropTypes.node.isRequired, - hideGlobalFilter: PropTypes.func, - initializeChrome: PropTypes.func, isDisabled: PropTypes.bool, - onNavigation: PropTypes.func, - setAppName: PropTypes.func, t: PropTypes.func, - useDispatch: PropTypes.func, - useHistory: PropTypes.func, - useAuth: PropTypes.func + useGetAuthorization: PropTypes.func }; /** * Default props. * - * @type {{authorizeUser: Function, onNavigation: Function, useHistory: Function, setAppName: Function, t: Function, - * appName: string, initializeChrome: Function, useDispatch: Function, isDisabled: boolean, useAuth: Function, - * hideGlobalFilter: Function}} + * @type {{useGetAuthorization: Function, t: Function, appName: string, isDisabled: boolean}} */ Authentication.defaultProps = { appName: routerHelpers.appName, - authorizeUser: reduxActions.platform.authorizeUser, - hideGlobalFilter: reduxActions.platform.hideGlobalFilter, - initializeChrome: reduxActions.platform.initializeChrome, isDisabled: helpers.UI_DISABLED, - onNavigation: reduxActions.platform.onNavigation, - setAppName: reduxActions.platform.setAppName, t: translate, - useDispatch: storeHooks.reactRedux.useDispatch, - useHistory: routerHooks.useHistory, - useAuth + useGetAuthorization }; export { Authentication as default, Authentication }; diff --git a/src/components/authentication/authenticationContext.js b/src/components/authentication/authenticationContext.js index cda1a2085..252d8c0c9 100644 --- a/src/components/authentication/authenticationContext.js +++ b/src/components/authentication/authenticationContext.js @@ -1,6 +1,9 @@ -import React, { useContext } from 'react'; -import { storeHooks } from '../../redux'; +import React, { useContext, useState } from 'react'; +import { useMount, useUnmount } from 'react-use'; +import { reduxActions, storeHooks } from '../../redux'; +import { routerHooks } from '../../hooks/useRouter'; import { helpers } from '../../common'; +import { routerHelpers } from '../router'; /** * Base context. @@ -19,14 +22,34 @@ const AuthenticationContext = React.createContext(DEFAULT_CONTEXT); const useAuthContext = () => useContext(AuthenticationContext); /** - * Return a combined state store that includes authorization, locale, and API errors + * Initialize an app, and return a combined state store that includes authorization, locale, and API errors * - * @param {Function} useSelectorsAllSettledResponse + * @param {object} options + * @param {string} options.appName + * @param {Function} options.authorizeUser + * @param {Function} options.hideGlobalFilter + * @param {Function} options.initializeChrome + * @param {Function} options.onNavigation + * @param {Function} options.setAppName + * @param {Function} options.useDispatch + * @param {Function} options.useHistory + * @param {Function} options.useSelectorsResponse * @returns {{data: {errorCodes, errorStatus: *, locale}, pending: boolean, fulfilled: boolean, error: boolean}} */ -const useAuth = ({ +const useGetAuthorization = ({ + appName = routerHelpers.appName, + authorizeUser = reduxActions.platform.authorizeUser, + hideGlobalFilter = reduxActions.platform.hideGlobalFilter, + initializeChrome = reduxActions.platform.initializeChrome, + onNavigation = reduxActions.platform.onNavigation, + setAppName = reduxActions.platform.setAppName, + useDispatch: useAliasDispatch = storeHooks.reactRedux.useDispatch, + useHistory: useAliasHistory = routerHooks.useHistory, useSelectorsResponse: useAliasSelectorsResponse = storeHooks.reactRedux.useSelectorsResponse } = {}) => { + const [unregister, setUnregister] = useState(() => helpers.noop); + const history = useAliasHistory(); + const dispatch = useAliasDispatch(); const { data, error, fulfilled, pending, responses } = useAliasSelectorsResponse([ { id: 'auth', selector: ({ user }) => user?.auth }, { id: 'locale', selector: ({ user }) => user?.locale }, @@ -36,6 +59,16 @@ const useAuth = ({ } ]); + useMount(async () => { + await dispatch(authorizeUser()); + dispatch([initializeChrome(), setAppName(appName), hideGlobalFilter()]); + setUnregister(() => dispatch(onNavigation(event => history.push(event.navId)))); + }); + + useUnmount(() => { + unregister(); + }); + const [user = {}, app = {}] = (Array.isArray(data.auth) && data.auth) || []; const errorStatus = (error && responses?.id?.errors?.status) || null; @@ -70,8 +103,16 @@ const context = { AuthenticationContext, DEFAULT_CONTEXT, useAuthContext, - useAuth, + useGetAuthorization, useSession }; -export { context as default, context, AuthenticationContext, DEFAULT_CONTEXT, useAuthContext, useAuth, useSession }; +export { + context as default, + context, + AuthenticationContext, + DEFAULT_CONTEXT, + useAuthContext, + useGetAuthorization, + useSession +}; diff --git a/src/components/bannerMessages/__tests__/__snapshots__/bannerMessages.test.js.snap b/src/components/bannerMessages/__tests__/__snapshots__/bannerMessages.test.js.snap index fa995f2da..bb4a52d27 100644 --- a/src/components/bannerMessages/__tests__/__snapshots__/bannerMessages.test.js.snap +++ b/src/components/bannerMessages/__tests__/__snapshots__/bannerMessages.test.js.snap @@ -13,8 +13,7 @@ exports[`BannerMessages Component should handle closing messages from state: sta }, ] } - useAppMessages={[Function]} - useRouteDetail={[Function]} + useGetAppMessages={[Function]} >
`; -exports[`BannerMessages Component should render a non-connected component: non-connected 1`] = ` +exports[`BannerMessages Component should render a basic component: basic 1`] = `
`; - -exports[`BannerMessages Component should render specific messages when the appMessages prop is used: specific messages, OFF, ON 1`] = ` - -
- - } - key="dolorSit" - title="Dolor sit title" - variant="info" - > -
- -
- - - - - -
-
-

- - Info alert: - - Dolor sit title -

-
- - - - - -
-
- Dolor sit message -
-
-
-
-
-`; diff --git a/src/components/bannerMessages/__tests__/__snapshots__/bannerMessagesContext.test.js.snap b/src/components/bannerMessages/__tests__/__snapshots__/bannerMessagesContext.test.js.snap new file mode 100644 index 000000000..0a12654f4 --- /dev/null +++ b/src/components/bannerMessages/__tests__/__snapshots__/bannerMessagesContext.test.js.snap @@ -0,0 +1,51 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`BannerMessagesContext should apply a hook for retrieving messages data from a selectors: error response 1`] = ` +Object { + "data": Object { + "cloudigradeMismatch": false, + }, + "error": true, + "fulfilled": undefined, + "pending": undefined, +} +`; + +exports[`BannerMessagesContext should apply a hook for retrieving messages data from a selectors: mock store error response 1`] = ` +Object { + "data": Object { + "cloudigradeMismatch": false, + }, + "error": true, + "fulfilled": false, + "pending": false, +} +`; + +exports[`BannerMessagesContext should apply a hook for retrieving messages data from a selectors: mock store success response 1`] = ` +Object { + "data": Object { + "cloudigradeMismatch": true, + }, + "error": false, + "fulfilled": true, + "pending": false, +} +`; + +exports[`BannerMessagesContext should apply a hook for retrieving messages data from a selectors: success response 1`] = ` +Object { + "data": Object { + "cloudigradeMismatch": false, + }, + "error": undefined, + "fulfilled": true, + "pending": undefined, +} +`; + +exports[`BannerMessagesContext should return specific properties: specific properties 1`] = ` +Object { + "useGetAppMessages": [Function], +} +`; diff --git a/src/components/bannerMessages/__tests__/bannerMessages.test.js b/src/components/bannerMessages/__tests__/bannerMessages.test.js index 8bd2bc442..844f2ac5e 100644 --- a/src/components/bannerMessages/__tests__/bannerMessages.test.js +++ b/src/components/bannerMessages/__tests__/bannerMessages.test.js @@ -3,7 +3,7 @@ import { AlertActionCloseButton } from '@patternfly/react-core'; import { BannerMessages } from '../bannerMessages'; describe('BannerMessages Component', () => { - it('should render a non-connected component', async () => { + it('should render a basic component', async () => { const props = { messages: [ { @@ -12,52 +12,15 @@ describe('BannerMessages Component', () => { message: 'Lorem ipsum message' } ], - useAppMessages: () => ({ appMessages: { loremIpsum: true } }), - useRouteDetail: () => ({}) - }; - - const component = await mountHookComponent(); - expect(component).toMatchSnapshot('non-connected'); - }); - - it('should attempt to check reports on product update', async () => { - const props = { - messages: [ - { - id: 'loremIpsum', - title: 'Lorem ipsum title', - message: 'Lorem ipsum message' - } - ], - useAppMessages: jest.fn(() => ({})), - useRouteDetail: () => ({ productConfig: [{ productId: 'lorem' }] }) - }; - - const component = await shallowHookComponent(); - component.setProps({ useRouteDetail: () => ({ productConfig: [{ productId: 'dolor' }] }) }); - expect(props.useAppMessages).toHaveBeenCalledTimes(2); - }); - - it('should render specific messages when the appMessages prop is used', async () => { - const props = { - messages: [ - { - id: 'loremIpsum', - title: 'Lorem ipsum title', - message: 'Lorem ipsum message' - }, - { - id: 'dolorSit', - title: 'Dolor sit title', - message: 'Dolor sit message' + useGetAppMessages: () => ({ + data: { + loremIpsum: true } - ], - useAppMessages: () => ({ appMessages: { loremIpsum: false, dolorSit: true } }), - useRouteDetail: () => ({}) + }) }; - const component = await mountHookComponent(); - expect(component).toMatchSnapshot('specific messages, OFF, ON'); + + expect(component).toMatchSnapshot('basic'); }); it('should handle closing messages from state', async () => { @@ -69,8 +32,7 @@ describe('BannerMessages Component', () => { message: 'Dolor sit message' } ], - useAppMessages: () => ({ appMessages: { dolorSit: true } }), - useRouteDetail: () => ({}) + useGetAppMessages: () => ({ data: { dolorSit: true } }) }; const component = await mountHookComponent(); diff --git a/src/components/bannerMessages/__tests__/bannerMessagesContext.test.js b/src/components/bannerMessages/__tests__/bannerMessagesContext.test.js new file mode 100644 index 000000000..563ccb19b --- /dev/null +++ b/src/components/bannerMessages/__tests__/bannerMessagesContext.test.js @@ -0,0 +1,86 @@ +import { context, useGetAppMessages } from '../bannerMessagesContext'; +import { rhsmConstants } from '../../../services/rhsm/rhsmConstants'; + +describe('BannerMessagesContext', () => { + it('should return specific properties', () => { + expect(context).toMatchSnapshot('specific properties'); + }); + + it('should apply a hook for retrieving messages data from a selectors', () => { + const { result: errorResponse } = shallowHook(() => + useGetAppMessages({ + useSelectorsResponse: () => ({ + error: true, + data: { + messages: {} + } + }) + }) + ); + + expect(errorResponse).toMatchSnapshot('error response'); + + const { result: successResponse } = shallowHook(() => + useGetAppMessages({ + useSelectorsResponse: () => ({ + fulfilled: true, + data: { + messages: {} + } + }) + }) + ); + + expect(successResponse).toMatchSnapshot('success response'); + + const { result: mockStoreSuccessResponse } = shallowHook( + () => + useGetAppMessages({ + useProduct: () => ({ productId: 'loremIpsum' }) + }), + { + state: { + messages: { + report: { + loremIpsum: { + fulfilled: true, + data: { + data: [ + { + [rhsmConstants.RHSM_API_RESPONSE_TALLY_META_TYPES.HAS_CLOUDIGRADE_MISMATCH]: true + } + ] + } + } + } + } + } + } + ); + + expect(mockStoreSuccessResponse).toMatchSnapshot('mock store success response'); + + const { result: mockStoreErrorResponse } = shallowHook( + () => + useGetAppMessages({ + useProduct: () => ({ productId: 'loremIpsum' }) + }), + { + state: { + messages: { + report: { + loremIpsum: { + error: true, + data: { + data: [] + } + } + } + } + } + } + ); + + expect(mockStoreErrorResponse).toMatchSnapshot('mock store error response'); + }); +}); diff --git a/src/components/bannerMessages/bannerMessages.js b/src/components/bannerMessages/bannerMessages.js index fa28b59d7..59fa9045e 100644 --- a/src/components/bannerMessages/bannerMessages.js +++ b/src/components/bannerMessages/bannerMessages.js @@ -3,42 +3,22 @@ import PropTypes from 'prop-types'; import { Alert, AlertActionCloseButton, AlertVariant, Button } from '@patternfly/react-core'; import { ExternalLinkAltIcon } from '@patternfly/react-icons'; import { useShallowCompareEffect } from 'react-use'; -import { apiQueries, storeHooks } from '../../redux'; +import { useGetAppMessages } from './bannerMessagesContext'; +import { helpers } from '../../common'; import { translate } from '../i18n/i18n'; -import { dateHelpers, helpers } from '../../common'; -import { RHSM_API_QUERY_GRANULARITY_TYPES as GRANULARITY_TYPES, RHSM_API_QUERY_TYPES } from '../../types/rhsmApiTypes'; -import { useRouteDetail } from '../../hooks/useRouter'; /** * Render banner messages. * * @param {object} props * @param {Array} props.messages - * @param {Function} props.useRouteDetail - * @param {Function} props.useAppMessages - * @returns {Node} + * @param {Function} props.useGetAppMessages + * @returns {React.ReactNode} */ -const BannerMessages = ({ messages, useRouteDetail: useAliasRouteDetail, useAppMessages: useAliasAppMessages }) => { +const BannerMessages = ({ messages, useGetAppMessages: useAliasGetAppMessages }) => { const [hideAlerts, setHideAlerts] = useState({}); const [alerts, setAlerts] = useState([]); - const { pathParameter: productId, productConfig } = useAliasRouteDetail() || {}; - const isProductConfig = productConfig?.length === 1 && productConfig?.[0]; - const { query } = apiQueries.parseRhsmQuery(productConfig?.[0]?.query || {}); - const { appMessages } = useAliasAppMessages(); - - useShallowCompareEffect(() => { - if (productId && isProductConfig) { - const { startDate, endDate } = dateHelpers.getRangedDateTime('CURRENT'); - const updatedGraphQuery = { - ...query, - [RHSM_API_QUERY_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY, - [RHSM_API_QUERY_TYPES.START_DATE]: startDate.toISOString(), - [RHSM_API_QUERY_TYPES.END_DATE]: endDate.toISOString() - }; - - storeHooks.rhsmActions.useGetMessageReports(productId, updatedGraphQuery); - } - }, [productId, isProductConfig, query]); + const { data: appMessages } = useAliasGetAppMessages(); useShallowCompareEffect(() => { const updatedMessages = []; @@ -81,7 +61,7 @@ const BannerMessages = ({ messages, useRouteDetail: useAliasRouteDetail, useAppM /** * Prop types. * - * @type {{useAppMessages: Function, messages: Array, useRouteDetail: Function}} + * @type {{useGetAppMessages: Function, messages: Array}} */ BannerMessages.propTypes = { messages: PropTypes.arrayOf( @@ -92,14 +72,13 @@ BannerMessages.propTypes = { variant: PropTypes.oneOf([...Object.values(AlertVariant)]) }) ), - useAppMessages: PropTypes.func, - useRouteDetail: PropTypes.func + useGetAppMessages: PropTypes.func }; /** * Default props. * - * @type {{useAppMessages: Function, messages: Array, useRouteDetail: Function}} + * @type {{useGetAppMessages: Function, messages: Array}} */ BannerMessages.defaultProps = { messages: [ @@ -126,8 +105,7 @@ BannerMessages.defaultProps = { ) } ], - useAppMessages: storeHooks.rhsmSelectors.useAppMessages, - useRouteDetail + useGetAppMessages }; export { BannerMessages as default, BannerMessages }; diff --git a/src/components/bannerMessages/bannerMessagesContext.js b/src/components/bannerMessages/bannerMessagesContext.js new file mode 100644 index 000000000..15b709860 --- /dev/null +++ b/src/components/bannerMessages/bannerMessagesContext.js @@ -0,0 +1,86 @@ +import { useShallowCompareEffect } from 'react-use'; +import { reduxActions, storeHooks } from '../../redux'; +import { useProduct, useProductQuery } from '../productView/productViewContext'; +import { dateHelpers } from '../../common'; +import { + rhsmConstants, + RHSM_API_QUERY_GRANULARITY_TYPES as GRANULARITY_TYPES, + RHSM_API_QUERY_SET_TYPES +} from '../../services/rhsm/rhsmConstants'; + +/** + * ToDo: useGetAppMessages is setup to work with existing Tally response, pre-metrics + * Banner messages scans the returned Tally listing for the HAS_CLOUDIGRADE_MISMATCH. In the future + * this may need to be updated to pull from the "meta" object part of the Tally response. + */ +/** + * Get app messages. + * + * @param {object} options + * @param {Function} options.getMessageReports + * @param {Function} options.useDispatch + * @param {Function} options.useProduct + * @param {Function} options.useProductQuery + * @param {Function} options.useSelectorsResponse + * @returns {object} + */ +const useGetAppMessages = ({ + getMessageReports = reduxActions.rhsm.getMessageReports, + useDispatch: useAliasDispatch = storeHooks.reactRedux.useDispatch, + useProduct: useAliasProduct = useProduct, + useProductQuery: useAliasProductQuery = useProductQuery, + useSelectorsResponse: useAliasSelectorsResponse = storeHooks.reactRedux.useSelectorsResponse +} = {}) => { + const { productId } = useAliasProduct(); + const query = useAliasProductQuery(); + const dispatch = useAliasDispatch(); + const { error, fulfilled, pending, data } = useAliasSelectorsResponse({ + id: 'messages', + selector: ({ messages }) => messages?.report?.[productId] + }); + + useShallowCompareEffect(() => { + if (productId) { + const { startDate, endDate } = dateHelpers.getRangedDateTime('CURRENT'); + const updatedQuery = { + ...query, + [RHSM_API_QUERY_SET_TYPES.GRANULARITY]: GRANULARITY_TYPES.DAILY, + [RHSM_API_QUERY_SET_TYPES.START_DATE]: startDate.toISOString(), + [RHSM_API_QUERY_SET_TYPES.END_DATE]: endDate.toISOString() + }; + + getMessageReports(productId, updatedQuery)(dispatch); + } + }, [productId, query]); + + const updatedData = { + cloudigradeMismatch: false + }; + + if (fulfilled) { + const { messages = {} } = data || {}; + + updatedData.cloudigradeMismatch = + messages?.data + ?.reverse() + ?.find( + ({ [rhsmConstants.RHSM_API_RESPONSE_TALLY_META_TYPES.HAS_CLOUDIGRADE_MISMATCH]: mismatch }) => + mismatch === true + ) !== undefined; + } + + return { + error, + fulfilled, + pending, + data: { + ...updatedData + } + }; +}; + +const context = { + useGetAppMessages +}; + +export { context as default, context, useGetAppMessages }; diff --git a/src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap b/src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap index 5e2962525..24615c7fb 100644 --- a/src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap +++ b/src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap @@ -4,6 +4,8 @@ exports[`I18n Component should attempt to perform a component translate: transla exports[`I18n Component should attempt to perform a string replace: translate 1`] = ` Object { + "emptyContext": "t(lorem.ipsum, {\\"context\\":\\" \\"})", + "emptyPartialContext": "t(lorem.ipsum, {\\"context\\":\\"hello_ \\"})", "localeKey": "t(lorem.ipsum)", "multiContext": "t(lorem.ipsum, {\\"context\\":\\"hello_world\\"})", "multiContextWithEmptyValue": "t(lorem.ipsum, {\\"context\\":\\"hello_world\\"})", @@ -397,6 +399,23 @@ Array [ }, ], }, + Object { + "file": "./src/components/toolbar/toolbarFieldBillingProvider.js", + "keys": Array [ + Object { + "key": "curiosity-toolbar.billing_provider", + "match": "translate('curiosity-toolbar.billing_provider', { context: (type === '' && 'none')", + }, + Object { + "key": "", + "match": "t(\`curiosity-toolbar.placeholder\${(isFilter && '_filter')", + }, + Object { + "key": "", + "match": "t(\`curiosity-toolbar.placeholder\${(isFilter && '_filter')", + }, + ], + }, Object { "file": "./src/components/toolbar/toolbarFieldDisplayName.js", "keys": Array [ @@ -455,6 +474,10 @@ Array [ "key": "curiosity-toolbar.category", "match": "translate('curiosity-toolbar.category', { context: RHSM_API_QUERY_TYPES.UOM })", }, + Object { + "key": "curiosity-toolbar.category", + "match": "translate('curiosity-toolbar.category', { context: RHSM_API_QUERY_TYPES.BILLING_PROVIDER })", + }, Object { "key": "curiosity-toolbar.category", "match": "translate('curiosity-toolbar.category', { context: RHSM_API_QUERY_TYPES.SLA })", @@ -545,11 +568,11 @@ Array [ }, Object { "key": "curiosity-inventory.header", - "match": "translate('curiosity-inventory.header', { context: ['subscriptions', data?.uom?.value] })", + "match": "translate('curiosity-inventory.header', { context: ['subscriptions', uom?.value] })", }, Object { - "key": "curiosity-inventory.label", - "match": "translate('curiosity-inventory.label', { context: ['hasInfiniteQuantity', uom?.value] })", + "key": "", + "match": "translate( \`curiosity-inventory.label_\${SUBSCRIPTIONS_INVENTORY_TYPES.HAS_INFINITE_QUANTITY}\`, { context: uom?.value } )", }, ], }, @@ -600,11 +623,11 @@ Array [ }, Object { "key": "curiosity-inventory.header", - "match": "translate('curiosity-inventory.header', { context: ['subscriptions', data?.uom?.value] })", + "match": "translate('curiosity-inventory.header', { context: ['subscriptions', uom?.value] })", }, Object { - "key": "curiosity-inventory.label", - "match": "translate('curiosity-inventory.label', { context: ['hasInfiniteQuantity', uom?.value] })", + "key": "", + "match": "translate( \`curiosity-inventory.label_\${SUBSCRIPTIONS_INVENTORY_TYPES.HAS_INFINITE_QUANTITY}\`, { context: uom?.value } )", }, ], }, @@ -627,6 +650,10 @@ Array [ "key": "curiosity-graph.label_axisX", "match": "translate('curiosity-graph.label_axisX', { context: GRANULARITY_TYPES.DAILY })", }, + Object { + "key": "", + "match": "translate(\`curiosity-inventory.measurement_\${INVENTORY_TYPES.BILLING_PROVIDER}\`, { context: provider?.value || 'none' })", + }, Object { "key": "curiosity-inventory.header", "match": "translate('curiosity-inventory.header', { context: ['tooltip', RHSM_API_PATH_METRIC_TYPES.TRANSFER_GIBIBYTES] })", @@ -637,23 +664,19 @@ Array [ }, Object { "key": "curiosity-inventory.header", - "match": "translate('curiosity-inventory.header', { context: ['tooltip', RHSM_API_PATH_METRIC_TYPES.STORAGE_GIBIBYTES] })", + "match": "translate('curiosity-inventory.header', { context: ['tooltip', RHSM_API_PATH_METRIC_TYPES.STORAGE_GIBIBYTE_MONTHS] })", }, Object { "key": "curiosity-inventory.measurement", - "match": "translate('curiosity-inventory.measurement', { context: RHSM_API_PATH_METRIC_TYPES.STORAGE_GIBIBYTES, total: helpers.numberDisplay(total?.value)", + "match": "translate('curiosity-inventory.measurement', { context: RHSM_API_PATH_METRIC_TYPES.STORAGE_GIBIBYTE_MONTHS, total: helpers.numberDisplay(total?.value)", }, Object { "key": "curiosity-inventory.measurement", "match": "translate('curiosity-inventory.measurement', { context: RHSM_API_PATH_METRIC_TYPES.INSTANCE_HOURS, total: helpers.numberDisplay(total?.value)", }, Object { - "key": "curiosity-inventory.header", - "match": "translate('curiosity-inventory.header', { context: ['subscriptions', data?.uom?.value] })", - }, - Object { - "key": "curiosity-inventory.label", - "match": "translate('curiosity-inventory.label', { context: ['hasInfiniteQuantity', uom?.value] })", + "key": "", + "match": "translate(\`curiosity-inventory.label_\${SUBSCRIPTIONS_INVENTORY_META_TYPES.SUBSCRIPTION_TYPE}\`, { context: subscriptionType || EMPTY_CONTEXT })", }, ], }, @@ -740,10 +763,6 @@ Array [ "file": "./src/config/product.openshiftContainer.js", "key": "curiosity-inventory.label", }, - Object { - "file": "./src/config/product.openshiftContainer.js", - "key": "curiosity-inventory.label", - }, Object { "file": "./src/config/product.openshiftDedicated.js", "key": "curiosity-inventory.label", @@ -756,10 +775,6 @@ Array [ "file": "./src/config/product.rhel.js", "key": "curiosity-inventory.label", }, - Object { - "file": "./src/config/product.rhel.js", - "key": "curiosity-inventory.label", - }, Object { "file": "./src/config/product.rhosak.js", "key": "curiosity-graph.label_axisY", @@ -788,10 +803,6 @@ Array [ "file": "./src/config/product.rhosak.js", "key": "curiosity-inventory.measurement", }, - Object { - "file": "./src/config/product.rhosak.js", - "key": "curiosity-inventory.label", - }, Object { "file": "./src/config/product.satellite.js", "key": "curiosity-inventory.label", diff --git a/src/components/i18n/__tests__/i18n.test.js b/src/components/i18n/__tests__/i18n.test.js index 56ef165a9..104243ded 100644 --- a/src/components/i18n/__tests__/i18n.test.js +++ b/src/components/i18n/__tests__/i18n.test.js @@ -5,7 +5,7 @@ import PropTypes from 'prop-types'; import { shallow } from 'enzyme'; import _get from 'lodash/get'; import enLocales from '../../../../public/locales/en-US.json'; -import { I18n, translate, translateComponent } from '../i18n'; +import { EMPTY_CONTEXT, I18n, translate, translateComponent } from '../i18n'; /** * Get translation keys. @@ -97,6 +97,8 @@ describe('I18n Component', () => { }); it('should attempt to perform a string replace', () => { + const emptyContext = translate('lorem.ipsum', { context: EMPTY_CONTEXT }); + const emptyPartialContext = translate('lorem.ipsum', { context: ['hello', EMPTY_CONTEXT] }); const localeKey = translate('lorem.ipsum'); const placeholder = translate('lorem.ipsum', 'hello world'); const multiContext = translate('lorem.ipsum', { context: ['hello', 'world'] }); @@ -104,6 +106,8 @@ describe('I18n Component', () => { const multiKey = translate(['lorem.ipsum', undefined, null, '', 'lorem.fallback']); expect({ + emptyContext, + emptyPartialContext, localeKey, placeholder, multiContext, diff --git a/src/components/i18n/i18n.js b/src/components/i18n/i18n.js index d7267b4fb..44dc09266 100644 --- a/src/components/i18n/i18n.js +++ b/src/components/i18n/i18n.js @@ -6,6 +6,13 @@ import { initReactI18next, Trans } from 'react-i18next'; import { useMount } from 'react-use'; import { helpers } from '../../common/helpers'; +/** + * Check to help provide an empty context. + * + * @type {string} + */ +const EMPTY_CONTEXT = 'LOCALE_EMPTY_CONTEXT'; + /** * Apply a string towards a key. Optional replacement values and component/nodes. * See, https://react.i18next.com/ @@ -13,9 +20,11 @@ import { helpers } from '../../common/helpers'; * @param {string|Array} translateKey A key reference, or an array of a primary key with fallback keys. * @param {string|object|Array} values A default string if the key can't be found. An object with i18next settings. Or an array of objects (key/value) pairs used to replace string tokes. i.e. "[{ hello: 'world' }]" * @param {Array} components An array of HTML/React nodes used to replace string tokens. i.e. "[, ]" + * @param {object} options + * @param {string} options.emptyContextValue Check to allow an empty context value. * @returns {string|React.ReactNode} */ -const translate = (translateKey, values = null, components) => { +const translate = (translateKey, values = null, components, { emptyContextValue = EMPTY_CONTEXT } = {}) => { const updatedValues = values; let updatedTranslateKey = translateKey; @@ -25,8 +34,11 @@ const translate = (translateKey, values = null, components) => { if (Array.isArray(updatedValues?.context)) { updatedValues.context = updatedValues.context + .map(value => (value === emptyContextValue && ' ') || value) .filter(value => typeof value === 'string' && value.length > 0) .join('_'); + } else if (updatedValues?.context === emptyContextValue) { + updatedValues.context = ' '; } if (helpers.TEST_MODE) { @@ -143,4 +155,4 @@ I18n.defaultProps = { locale: null }; -export { I18n as default, I18n, i18next, translate, translateComponent }; +export { I18n as default, I18n, i18next, translate, translateComponent, EMPTY_CONTEXT }; diff --git a/src/components/inventoryCard/__tests__/__snapshots__/inventoryCardContext.test.js.snap b/src/components/inventoryCard/__tests__/__snapshots__/inventoryCardContext.test.js.snap index ae09ea97c..875683cc4 100644 --- a/src/components/inventoryCard/__tests__/__snapshots__/inventoryCardContext.test.js.snap +++ b/src/components/inventoryCard/__tests__/__snapshots__/inventoryCardContext.test.js.snap @@ -2,6 +2,7 @@ exports[`InventoryCardContext should expect specific sort properties: sort properties 1`] = ` Object { + "BILLING_PROVIDER": "billing_provider", "CORES": "Cores", "CORE_SECONDS": "Core-seconds", "INSTANCE_HOURS": "Instance-hours", @@ -9,6 +10,7 @@ Object { "NAME": "display_name", "SOCKETS": "Sockets", "STORAGE_GIBIBYTES": "Storage-gibibytes", + "STORAGE_GIBIBYTE_MONTHS": "Storage-gibibyte-months", "TRANSFER_GIBIBYTES": "Transfer-gibibytes", } `; diff --git a/src/components/inventoryCard/__tests__/__snapshots__/inventoryCardHelpers.test.js.snap b/src/components/inventoryCard/__tests__/__snapshots__/inventoryCardHelpers.test.js.snap index 0666d0567..2ee801ef4 100644 --- a/src/components/inventoryCard/__tests__/__snapshots__/inventoryCardHelpers.test.js.snap +++ b/src/components/inventoryCard/__tests__/__snapshots__/inventoryCardHelpers.test.js.snap @@ -146,6 +146,32 @@ Object { } `; +exports[`InventoryListHelpers parseRowCellsListData should parse and return formatted/filtered table cells.: basic standalone data 1`] = ` +Object { + "cells": Array [ + Object { + "title": "world", + }, + ], + "columnHeaders": Array [ + Object { + "title": "hello", + "transforms": Array [], + }, + ], + "data": Object { + "dolor": Object { + "title": "t(curiosity-inventory.header, {\\"context\\":\\"dolor\\"})", + "value": "sit", + }, + "lorem": Object { + "title": "t(curiosity-inventory.header, {\\"context\\":\\"lorem\\"})", + "value": "ipsum", + }, + }, +} +`; + exports[`InventoryListHelpers parseRowCellsListData should parse and return formatted/filtered table cells.: custom and generated transforms 1`] = ` Object { "cells": Array [ @@ -364,6 +390,32 @@ Object { } `; +exports[`InventoryListHelpers parseRowCellsListData should parse and return formatted/filtered table cells.: custom standalone data 1`] = ` +Object { + "cells": Array [ + Object { + "title": "custom ipsum/sit", + }, + ], + "columnHeaders": Array [ + Object { + "title": "custom t(curiosity-inventory.header, {\\"context\\":\\"lorem\\"})/t(curiosity-inventory.header, {\\"context\\":\\"dolor\\"})", + "transforms": Array [], + }, + ], + "data": Object { + "dolor": Object { + "title": "t(curiosity-inventory.header, {\\"context\\":\\"dolor\\"})", + "value": "sit", + }, + "lorem": Object { + "title": "t(curiosity-inventory.header, {\\"context\\":\\"lorem\\"})", + "value": "ipsum", + }, + }, +} +`; + exports[`InventoryListHelpers parseRowCellsListData should parse and return formatted/filtered table cells.: custom transforms 1`] = ` Object { "cells": Array [ diff --git a/src/components/inventoryCard/__tests__/inventoryCardHelpers.test.js b/src/components/inventoryCard/__tests__/inventoryCardHelpers.test.js index d559d0778..da1755cfc 100644 --- a/src/components/inventoryCard/__tests__/inventoryCardHelpers.test.js +++ b/src/components/inventoryCard/__tests__/inventoryCardHelpers.test.js @@ -121,6 +121,22 @@ describe('InventoryListHelpers', () => { }; expect(parseRowCellsListData({ filters, cellData })).toMatchSnapshot('custom callback data'); + + filters[0] = { + isStandalone: true, + header: 'hello', + cell: 'world' + }; + + expect(parseRowCellsListData({ filters, cellData })).toMatchSnapshot('basic standalone data'); + + filters[0] = { + isStandalone: true, + header: ({ lorem, dolor }) => `custom ${lorem.title}/${dolor.title}`, + cell: ({ lorem, dolor }) => `custom ${lorem.value}/${dolor.value}` + }; + + expect(parseRowCellsListData({ filters, cellData })).toMatchSnapshot('custom standalone data'); }); it('parseInventoryFilters should parse and return updated filters for table cells', () => { diff --git a/src/components/inventoryCard/inventoryCard.js b/src/components/inventoryCard/inventoryCard.js index 3cd223849..e76dfca9d 100644 --- a/src/components/inventoryCard/inventoryCard.js +++ b/src/components/inventoryCard/inventoryCard.js @@ -95,6 +95,7 @@ const InventoryCard = ({ query }), cellData, + meta, session: sessionData }); diff --git a/src/components/inventoryCard/inventoryCardHelpers.js b/src/components/inventoryCard/inventoryCardHelpers.js index a8504489f..271cc3d92 100644 --- a/src/components/inventoryCard/inventoryCardHelpers.js +++ b/src/components/inventoryCard/inventoryCardHelpers.js @@ -41,20 +41,33 @@ const applyConfigProperty = (prop, { params = [] } = {}) => { /** * Generate header and row cell configuration from filters. * - * @param {Array<{id: string, cell:React.ReactNode|{ title: string }, cellWidth: number, - * header:React.ReactNode|{ title: string }, onSort: Function, showEmptyCell: boolean, - * sortId: string, sortActive: boolean, sortDirection: string, - * transforms: Array}>} filters - * @param {object} cellData - * @param {object} session + * @param {object} params + * @param {Array<{id: string, isStandalone: boolean, cell:React.ReactNode|{ title: string }, cellWidth: number, + * header:React.ReactNode|{ title: string }, onSort: Function, showEmptyCell: boolean, sortId: string, + * sortActive: boolean, sortDirection: string, transforms: Array}>} params.filters + * @param {object} params.cellData + * @param {object} params.meta + * @param {object} params.session * @returns {{bodyCells: { title: React.ReactNode }[], headerCells: { title: React.ReactNode }[]}} */ -const applyHeaderRowCellFilters = (filters = [], cellData = {}, session = {}) => { +const applyHeaderRowCellFilters = ({ filters = [], cellData = {}, meta = {}, session = {} } = {}) => { const headerCells = []; const bodyCells = []; filters.forEach( - ({ id, cell, cellWidth, header, onSort, showEmptyCell = true, sortId, sortActive, sortDirection, transforms }) => { + ({ + isStandalone, + id, + cell, + cellWidth, + header, + onSort, + showEmptyCell = true, + sortId, + sortActive, + sortDirection, + transforms + }) => { const headerCellUpdated = { title: translate('curiosity-inventory.header', { context: id }), transforms: [] }; const bodyCellUpdated = { title: '' }; @@ -62,6 +75,9 @@ const applyHeaderRowCellFilters = (filters = [], cellData = {}, session = {}) => if (cellData[id]) { headerCellUpdated.title = cellData[id]?.title ?? id; bodyCellUpdated.title = cellData[id]?.value ?? ''; + } else if (isStandalone === true) { + headerCellUpdated.title = ''; + bodyCellUpdated.title = ''; } else { if (helpers.DEV_MODE || helpers.REVIEW_MODE) { console.warn(`Warning: Filter "${id}" not found in "table row" response data.`, cellData); @@ -73,7 +89,9 @@ const applyHeaderRowCellFilters = (filters = [], cellData = {}, session = {}) => // set header cell title if (header) { - const updatedHeaderCellTitle = applyConfigProperty(header, { params: [{ ...cellData }, { ...session }] }); + const updatedHeaderCellTitle = applyConfigProperty(header, { + params: [{ ...cellData }, { ...session }, { ...meta }] + }); if (updatedHeaderCellTitle) { headerCellUpdated.title = updatedHeaderCellTitle; } else if (_isPlainObject(header)) { @@ -83,7 +101,7 @@ const applyHeaderRowCellFilters = (filters = [], cellData = {}, session = {}) => // set header cell tooltip if (header.tooltip && headerCellUpdated.title) { const updatedHeaderCellTooltip = applyConfigProperty(header.tooltip, { - params: [{ ...cellData }, { ...session }] + params: [{ ...cellData }, { ...session }, { ...meta }] }); if (updatedHeaderCellTooltip) { headerCellUpdated.title = {headerCellUpdated.title}; @@ -113,7 +131,9 @@ const applyHeaderRowCellFilters = (filters = [], cellData = {}, session = {}) => // set body cell title if (cell) { - const updatedBodyCellTitle = applyConfigProperty(cell, { params: [{ ...cellData }, { ...session }] }); + const updatedBodyCellTitle = applyConfigProperty(cell, { + params: [{ ...cellData }, { ...session }, { ...meta }] + }); if (updatedBodyCellTitle) { bodyCellUpdated.title = updatedBodyCellTitle; } else if (_isPlainObject(cell)) { @@ -123,7 +143,7 @@ const applyHeaderRowCellFilters = (filters = [], cellData = {}, session = {}) => // set body cell tooltip if (cell.tooltip && bodyCellUpdated.title) { const updatedBodyCellTooltip = applyConfigProperty(cell.tooltip, { - params: [{ ...cellData }, { ...session }] + params: [{ ...cellData }, { ...session }, { ...meta }] }); if (updatedBodyCellTooltip) { bodyCellUpdated.title = {bodyCellUpdated.title}; @@ -257,10 +277,11 @@ const parseInventoryFilters = ({ filters = [], onSort, query = {} } = {}) => * sortId: string, sortActive: boolean, sortDirection: string, * transforms: Array}>} params.filters * @param {object} params.cellData + * @param {object} params.meta * @param {object} params.session * @returns {{columnHeaders: { title: React.ReactNode }[], cells: { title: React.ReactNode }[], data: {}}} */ -const parseRowCellsListData = ({ filters = [], cellData = {}, session = {} } = {}) => { +const parseRowCellsListData = ({ filters = [], cellData = {}, meta = {}, session = {} } = {}) => { const updatedColumnHeaders = []; const updatedCells = []; const allCells = {}; @@ -281,7 +302,12 @@ const parseRowCellsListData = ({ filters = [], cellData = {}, session = {} } = { updatedColumnHeaders.length = 0; updatedCells.length = 0; - const { headerCells = [], bodyCells = [] } = applyHeaderRowCellFilters(filters, allCells, session); + const { headerCells = [], bodyCells = [] } = applyHeaderRowCellFilters({ + filters, + cellData: allCells, + meta, + session + }); updatedColumnHeaders.push(...headerCells); updatedCells.push(...bodyCells); diff --git a/src/components/productView/__tests__/__snapshots__/productView.test.js.snap b/src/components/productView/__tests__/__snapshots__/productView.test.js.snap index 9af6a6229..5325d9bfd 100644 --- a/src/components/productView/__tests__/__snapshots__/productView.test.js.snap +++ b/src/components/productView/__tests__/__snapshots__/productView.test.js.snap @@ -10,23 +10,6 @@ exports[`ProductView Component should allow custom inventory displays via config > t(curiosity-view.title, {"appName":"Subscriptions","context":"lorem ipsum product label"}) - - - @@ -41,6 +24,22 @@ exports[`ProductView Component should allow custom inventory displays via config } } > + + + @@ -52,6 +51,7 @@ exports[`ProductView Component should allow custom inventory displays via config useToolbarFieldClear={[Function]} useToolbarFieldClearAll={[Function]} useToolbarFieldQueries={[Function]} + useToolbarSecondaryFields={[Function]} /> t(curiosity-view.title, {"appName":"Subscriptions","context":"lorem ipsum product label"}) - - - @@ -192,6 +175,22 @@ exports[`ProductView Component should allow custom product views via props: cust } } > + + + @@ -203,6 +202,7 @@ exports[`ProductView Component should allow custom product views via props: cust useToolbarFieldClear={[Function]} useToolbarFieldClearAll={[Function]} useToolbarFieldQueries={[Function]} + useToolbarSecondaryFields={[Function]} /> t(curiosity-view.title, {"appName":"Subscriptions","context":"lorem ipsum product label"}) - - - @@ -328,6 +311,22 @@ exports[`ProductView Component should allow custom product views via props: cust } } > + + + @@ -339,6 +338,7 @@ exports[`ProductView Component should allow custom product views via props: cust useToolbarFieldClear={[Function]} useToolbarFieldClearAll={[Function]} useToolbarFieldQueries={[Function]} + useToolbarSecondaryFields={[Function]} /> t(curiosity-view.title, {"appName":"Subscriptions","context":"lorem ipsum product label"}) - - - @@ -412,6 +395,22 @@ exports[`ProductView Component should render a basic component: basic 1`] = ` } } > + + + @@ -423,6 +422,7 @@ exports[`ProductView Component should render a basic component: basic 1`] = ` useToolbarFieldClear={[Function]} useToolbarFieldClearAll={[Function]} useToolbarFieldQueries={[Function]} + useToolbarSecondaryFields={[Function]} /> t(curiosity-view.title, {"appName":"Subscriptions"}) - - - diff --git a/src/components/productView/__tests__/__snapshots__/productViewContext.test.js.snap b/src/components/productView/__tests__/__snapshots__/productViewContext.test.js.snap index 4e569d5af..63f931500 100644 --- a/src/components/productView/__tests__/__snapshots__/productViewContext.test.js.snap +++ b/src/components/productView/__tests__/__snapshots__/productViewContext.test.js.snap @@ -84,13 +84,13 @@ Object { "initialOption": "cores", "initialSubscriptionsInventoryFilters": Array [ Object { - "id": "productName", + "id": "product_name", "isSortable": true, "isWrappable": true, }, Object { "cellWidth": 15, - "id": "serviceLevel", + "id": "service_level", "isSortable": true, "isWrappable": true, }, @@ -104,14 +104,14 @@ Object { "cell": [Function], "cellWidth": 15, "header": [Function], - "id": "totalCapacity", + "id": "total_capacity", "isSortable": true, "isWrappable": true, }, Object { "cell": [Function], "cellWidth": 15, - "id": "nextEventDate", + "id": "next_event_date", "isSortable": true, "isWrappable": true, }, @@ -207,13 +207,13 @@ Object { "initialOption": "cores", "initialSubscriptionsInventoryFilters": Array [ Object { - "id": "productName", + "id": "product_name", "isSortable": true, "isWrappable": true, }, Object { "cellWidth": 15, - "id": "serviceLevel", + "id": "service_level", "isSortable": true, "isWrappable": true, }, @@ -227,14 +227,14 @@ Object { "cell": [Function], "cellWidth": 15, "header": [Function], - "id": "totalCapacity", + "id": "total_capacity", "isSortable": true, "isWrappable": true, }, Object { "cell": [Function], "cellWidth": 15, - "id": "nextEventDate", + "id": "next_event_date", "isSortable": true, "isWrappable": true, }, @@ -368,6 +368,11 @@ Object { "ipsum": "dolor", }, ], + "secondaryFilters": Array [ + Object { + "hello": "world", + }, + ], "settings": Object { "ipsum": "dolor", }, diff --git a/src/components/productView/__tests__/__snapshots__/productViewOpenShiftContainer.test.js.snap b/src/components/productView/__tests__/__snapshots__/productViewOpenShiftContainer.test.js.snap index e0cf65f18..5784e85c0 100644 --- a/src/components/productView/__tests__/__snapshots__/productViewOpenShiftContainer.test.js.snap +++ b/src/components/productView/__tests__/__snapshots__/productViewOpenShiftContainer.test.js.snap @@ -97,13 +97,13 @@ exports[`ProductViewOpenShiftContainer Component should render a basic component "initialOption": "cores", "initialSubscriptionsInventoryFilters": Array [ Object { - "id": "productName", + "id": "product_name", "isSortable": true, "isWrappable": true, }, Object { "cellWidth": 15, - "id": "serviceLevel", + "id": "service_level", "isSortable": true, "isWrappable": true, }, @@ -117,14 +117,14 @@ exports[`ProductViewOpenShiftContainer Component should render a basic component "cell": [Function], "cellWidth": 15, "header": [Function], - "id": "totalCapacity", + "id": "total_capacity", "isSortable": true, "isWrappable": true, }, Object { "cell": [Function], "cellWidth": 15, - "id": "nextEventDate", + "id": "next_event_date", "isSortable": true, "isWrappable": true, }, @@ -170,6 +170,7 @@ exports[`ProductViewOpenShiftContainer Component should render a basic component useToolbarFieldClear={[Function]} useToolbarFieldClearAll={[Function]} useToolbarFieldQueries={[Function]} + useToolbarSecondaryFields={[Function]} /> { sit: 'amet' }, initialToolbarFilters: [{ ipsum: 'dolor' }], + initialSecondaryToolbarFilters: [{ hello: 'world' }], initialToolbarSettings: { ipsum: 'dolor' } diff --git a/src/components/productView/productView.js b/src/components/productView/productView.js index 04d796022..2cdf7b956 100644 --- a/src/components/productView/productView.js +++ b/src/components/productView/productView.js @@ -42,7 +42,7 @@ import { translate } from '../i18n/i18n'; * @returns {Node} */ const ProductView = ({ t, toolbarGraph, toolbarGraphDescription, useRouteDetail: useAliasRouteDetail }) => { - const { pathParameter: routeProductId, productParameter: routeProductLabel, productConfig } = useAliasRouteDetail(); + const { productParameter: routeProductLabel, productConfig } = useAliasRouteDetail(); const renderProduct = config => { const { @@ -93,6 +93,7 @@ const ProductView = ({ t, toolbarGraph, toolbarGraphDescription, useRouteDetail: return ( + {productId !== RHSM_API_PATH_PRODUCT_TYPES.RHOSAK && } @@ -168,7 +169,6 @@ const ProductView = ({ t, toolbarGraph, toolbarGraphDescription, useRouteDetail: {t(`curiosity-view.title`, { appName: helpers.UI_DISPLAY_NAME, context: routeProductLabel })} - {routeProductId !== RHSM_API_PATH_PRODUCT_TYPES.RHOSAK && } {productConfig.map(config => renderProduct(config))} ); diff --git a/src/components/productView/productViewContext.js b/src/components/productView/productViewContext.js index 1f4706853..19cb84ddd 100644 --- a/src/components/productView/productViewContext.js +++ b/src/components/productView/productViewContext.js @@ -295,9 +295,14 @@ const useProductInventorySubscriptionsConfig = ({ * @returns {{settings: object, filters: Array}} */ const useProductToolbarConfig = ({ useProductContext: useAliasProductContext = useProductContext } = {}) => { - const { initialToolbarFilters, initialToolbarSettings = {} } = useAliasProductContext(); + const { + initialToolbarFilters, + initialToolbarSettings = {}, + initialSecondaryToolbarFilters + } = useAliasProductContext(); return { filters: initialToolbarFilters, + secondaryFilters: initialSecondaryToolbarFilters, settings: initialToolbarSettings }; }; diff --git a/src/components/router/__tests__/__snapshots__/redirect.test.js.snap b/src/components/router/__tests__/__snapshots__/redirect.test.js.snap index 8631c5184..9293abb11 100644 --- a/src/components/router/__tests__/__snapshots__/redirect.test.js.snap +++ b/src/components/router/__tests__/__snapshots__/redirect.test.js.snap @@ -115,13 +115,13 @@ Object { "initialOption": "cores", "initialSubscriptionsInventoryFilters": Array [ Object { - "id": "productName", + "id": "product_name", "isSortable": true, "isWrappable": true, }, Object { "cellWidth": 15, - "id": "serviceLevel", + "id": "service_level", "isSortable": true, "isWrappable": true, }, @@ -135,14 +135,14 @@ Object { "cell": [Function], "cellWidth": 15, "header": [Function], - "id": "totalCapacity", + "id": "total_capacity", "isSortable": true, "isWrappable": true, }, Object { "cell": [Function], "cellWidth": 15, - "id": "nextEventDate", + "id": "next_event_date", "isSortable": true, "isWrappable": true, }, diff --git a/src/components/toolbar/__tests__/__snapshots__/toolbar.test.js.snap b/src/components/toolbar/__tests__/__snapshots__/toolbar.test.js.snap index 670f32515..3e9dddf2b 100644 --- a/src/components/toolbar/__tests__/__snapshots__/toolbar.test.js.snap +++ b/src/components/toolbar/__tests__/__snapshots__/toolbar.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Toolbar Component should handle updating toolbar chips: chips 1`] = ` +exports[`Toolbar Component should handle displaying secondary components, fields: secondary 1`] = ` - + + + lorem ipsum + + `; +exports[`Toolbar Component should handle updating toolbar chips: chips 1`] = ` +Object { + "categoryName": "t(curiosity-toolbar.category, {\\"context\\":\\"sla\\"})", + "children": , + "chips": Array [ + "t(curiosity-toolbar.sla, {\\"context\\":\\"Premium\\"})", + ], + "deleteChip": [Function], + "showToolbarItem": true, +} +`; + +exports[`Toolbar Component should handle updating toolbar chips: chips, not clearable 1`] = ` +Object { + "categoryName": "t(curiosity-toolbar.category, {\\"context\\":\\"sla\\"})", + "children": , + "chips": Array [], + "showToolbarItem": true, +} +`; + exports[`Toolbar Component should hide categories when a single filter is available: single filter 1`] = ` - + `; @@ -185,37 +168,8 @@ exports[`Toolbar Component should render a basic component: basic 1`] = ` key="sla" showToolbarItem={false} > - - + `; @@ -267,3 +199,46 @@ exports[`Toolbar Component should render a basic component: basic 1`] = ` exports[`Toolbar Component should return an empty render when disabled or missing filters: disabled component 1`] = `""`; exports[`Toolbar Component should return an empty render when disabled or missing filters: missing filters 1`] = `""`; + +exports[`Toolbar Component should return an empty render when disabled or missing filters: missing primary, has secondary filters 1`] = ` + + + + } + > + + + + + lorem ipsum + + + + +`; diff --git a/src/components/toolbar/__tests__/__snapshots__/toolbarContext.test.js.snap b/src/components/toolbar/__tests__/__snapshots__/toolbarContext.test.js.snap index 370123b1c..1eff61b73 100644 --- a/src/components/toolbar/__tests__/__snapshots__/toolbarContext.test.js.snap +++ b/src/components/toolbar/__tests__/__snapshots__/toolbarContext.test.js.snap @@ -28,11 +28,37 @@ Array [ }, ], ], + Array [ + Array [ + Object { + "type": "SET_QUERY_RESET_INVENTORY_LIST", + "viewId": undefined, + }, + Object { + "billing_provider": null, + "type": "SET_QUERY_RHSM_billing_provider", + "viewId": undefined, + }, + ], + ], ] `; exports[`ToolbarContext should apply a hook for clearing specific active toolbar fields through redux: clear all fields 1`] = ` Array [ + Array [ + Array [ + Object { + "type": "SET_QUERY_RESET_INVENTORY_LIST", + "viewId": undefined, + }, + Object { + "billing_provider": null, + "type": "SET_QUERY_RHSM_billing_provider", + "viewId": undefined, + }, + ], + ], Array [ Array [ Object { @@ -59,6 +85,19 @@ Array [ }, ], ], + Array [ + Array [ + Object { + "type": "SET_QUERY_RESET_INVENTORY_LIST", + "viewId": undefined, + }, + Object { + "billing_provider": null, + "type": "SET_QUERY_RHSM_billing_provider", + "viewId": undefined, + }, + ], + ], Array [ Array [ Object { @@ -99,17 +138,28 @@ Array [ exports[`ToolbarContext should apply a hook for retrieving api queries specific to toolbar: query 1`] = ` Object { + "billing_provider": "testProvider", "granularity": "testGranularity", "sla": "testSla", "uom": undefined, - "usage": undefined, + "usage": "testUsage", } `; +exports[`ToolbarContext should apply a hook for retrieving secondary toolbar field components: secondary field, rangedMonthly 1`] = ` +Array [ + , +] +`; + exports[`ToolbarContext should return specific properties: specific properties 1`] = ` Object { "useToolbarFieldClear": [Function], "useToolbarFieldClearAll": [Function], "useToolbarFieldQueries": [Function], + "useToolbarSecondaryFields": [Function], } `; diff --git a/src/components/toolbar/__tests__/__snapshots__/toolbarFieldBillingProvider.test.js.snap b/src/components/toolbar/__tests__/__snapshots__/toolbarFieldBillingProvider.test.js.snap new file mode 100644 index 000000000..3c3b7bb93 --- /dev/null +++ b/src/components/toolbar/__tests__/__snapshots__/toolbarFieldBillingProvider.test.js.snap @@ -0,0 +1,97 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ToolbarFieldBillingProvider Component should export select options: toolbarFieldOptions 1`] = ` +Array [ + Object { + "selected": false, + "title": "t(curiosity-toolbar.billing_provider, {\\"context\\":\\"red hat\\"})", + "value": "red hat", + }, + Object { + "selected": false, + "title": "t(curiosity-toolbar.billing_provider, {\\"context\\":\\"aws\\"})", + "value": "aws", + }, + Object { + "selected": false, + "title": "t(curiosity-toolbar.billing_provider, {\\"context\\":\\"none\\"})", + "value": "", + }, +] +`; + +exports[`ToolbarFieldBillingProvider Component should handle updating sla through redux state with component: dispatch billing provider, component 1`] = ` +Array [ + Array [ + Array [ + Object { + "type": "SET_QUERY_RESET_INVENTORY_LIST", + "viewId": undefined, + }, + Object { + "billing_provider": "red hat", + "type": "SET_QUERY_RHSM_billing_provider", + "viewId": undefined, + }, + ], + ], +] +`; + +exports[`ToolbarFieldBillingProvider Component should handle updating sla through redux state with hook: dispatch billing provider, hook 1`] = ` +Array [ + Array [ + Array [ + Object { + "type": "SET_QUERY_RESET_INVENTORY_LIST", + "viewId": "loremIpsum", + }, + Object { + "billing_provider": "dolor sit", + "type": "SET_QUERY_RHSM_billing_provider", + "viewId": "loremIpsum", + }, + ], + ], +] +`; + +exports[`ToolbarFieldBillingProvider Component should render a basic component: basic 1`] = ` + + ); +}; + +/** + * Prop types. + * + * @type {{useOnSelect: Function, t: Function, isFilter: boolean, options: Array, useProductQuery: Function, + * position: string}} + */ +ToolbarFieldBillingProvider.propTypes = { + isFilter: PropTypes.bool, + options: PropTypes.arrayOf( + PropTypes.shape({ + title: PropTypes.node, + value: PropTypes.any, + selected: PropTypes.bool + }) + ), + position: PropTypes.string, + t: PropTypes.func, + useOnSelect: PropTypes.func, + useProductQuery: PropTypes.func +}; + +/** + * Default props. + * + * @type {{useOnSelect: Function, t: Function, isFilter: boolean, options: Array, useProductQuery: Function, + * position: string}} + */ +ToolbarFieldBillingProvider.defaultProps = { + isFilter: false, + options: toolbarFieldOptions, + position: SelectPosition.left, + t: translate, + useOnSelect, + useProductQuery +}; + +export { ToolbarFieldBillingProvider as default, ToolbarFieldBillingProvider, toolbarFieldOptions, useOnSelect }; diff --git a/src/components/toolbar/toolbarFieldSelectCategory.js b/src/components/toolbar/toolbarFieldSelectCategory.js index feea9bbbb..f36490ec4 100644 --- a/src/components/toolbar/toolbarFieldSelectCategory.js +++ b/src/components/toolbar/toolbarFieldSelectCategory.js @@ -5,16 +5,21 @@ import { useShallowCompareEffect } from 'react-use'; import { reduxTypes, storeHooks } from '../../redux'; import { useProduct, useProductToolbarConfig } from '../productView/productViewContext'; import { Select } from '../form/select'; -import { RHSM_API_QUERY_TYPES } from '../../types/rhsmApiTypes'; +import { RHSM_API_QUERY_SET_TYPES as RHSM_API_QUERY_TYPES } from '../../services/rhsm/rhsmConstants'; import { translate } from '../i18n/i18n'; import { ToolbarFieldGranularity, toolbarFieldOptions as granularityOptions } from './toolbarFieldGranularity'; import { ToolbarFieldRangedMonthly, toolbarFieldOptions as rangedMonthlyOptions } from './toolbarFieldRangedMonthly'; +import { + ToolbarFieldBillingProvider, + toolbarFieldOptions as billingProviderOptions +} from './toolbarFieldBillingProvider'; import { ToolbarFieldSla, toolbarFieldOptions as slaOptions } from './toolbarFieldSla'; import { ToolbarFieldUom, toolbarFieldOptions as uomOptions } from './toolbarFieldUom'; import { ToolbarFieldUsage, toolbarFieldOptions as usageOptions } from './toolbarFieldUsage'; /** - * Select field options. + * Select field options. Use function instead of arrow func to help with component + * display name during testing. * * @type {{title: (string|Node), value: string, selected: boolean}[]} */ @@ -22,35 +27,54 @@ const toolbarFieldOptions = [ { title: translate('curiosity-toolbar.category', { context: RHSM_API_QUERY_TYPES.GRANULARITY }), value: RHSM_API_QUERY_TYPES.GRANULARITY, - component: , + component: function Granularity(props) { + return ; + }, options: granularityOptions, isClearable: false }, { title: translate('curiosity-toolbar.category', { context: 'rangedMonthly' }), value: 'rangedMonthly', - component: , + component: function RangedMonthly(props) { + return ; + }, options: rangedMonthlyOptions, isClearable: false }, { title: translate('curiosity-toolbar.category', { context: RHSM_API_QUERY_TYPES.UOM }), value: RHSM_API_QUERY_TYPES.UOM, - component: , + component: function Uom(props) { + return ; + }, options: uomOptions, isClearable: false }, + { + title: translate('curiosity-toolbar.category', { context: RHSM_API_QUERY_TYPES.BILLING_PROVIDER }), + value: RHSM_API_QUERY_TYPES.BILLING_PROVIDER, + component: function BillingProvider(props) { + return ; + }, + options: billingProviderOptions, + isClearable: true + }, { title: translate('curiosity-toolbar.category', { context: RHSM_API_QUERY_TYPES.SLA }), value: RHSM_API_QUERY_TYPES.SLA, - component: , + component: function Sla(props) { + return ; + }, options: slaOptions, isClearable: true }, { title: translate('curiosity-toolbar.category', { context: RHSM_API_QUERY_TYPES.USAGE }), value: RHSM_API_QUERY_TYPES.USAGE, - component: , + component: function Usage(props) { + return ; + }, options: usageOptions, isClearable: true } diff --git a/src/config/__tests__/__snapshots__/product.openshiftContainer.test.js.snap b/src/config/__tests__/__snapshots__/product.openshiftContainer.test.js.snap index e3f7682b7..677a7d43a 100644 --- a/src/config/__tests__/__snapshots__/product.openshiftContainer.test.js.snap +++ b/src/config/__tests__/__snapshots__/product.openshiftContainer.test.js.snap @@ -289,7 +289,7 @@ Object { }, Object { "title": - t(curiosity-inventory.header, {"context":"Storage-gibibytes"}) + t(curiosity-inventory.header, {"context":"Storage-gibibyte-months"}) , "transforms": Array [ [Function], @@ -109,11 +118,14 @@ Object { lorem ipsum , }, + Object { + "title": "t(curiosity-inventory.measurement_billing_provider, {\\"context\\":\\"none\\"})", + }, Object { "title": "t(curiosity-inventory.measurement, {\\"context\\":\\"Transfer-gibibytes\\",\\"total\\":\\"0.00035\\"})", }, Object { - "title": "t(curiosity-inventory.measurement, {\\"context\\":\\"Storage-gibibytes\\",\\"total\\":\\"1000.00123\\"})", + "title": "t(curiosity-inventory.measurement, {\\"context\\":\\"Storage-gibibyte-months\\",\\"total\\":0})", }, Object { "title": "t(curiosity-inventory.measurement, {\\"context\\":\\"Instance-hours\\",\\"total\\":\\"200\\"})", @@ -129,6 +141,12 @@ Object { "title": "t(curiosity-inventory.header, {\\"context\\":\\"display_name\\"})", "transforms": Array [], }, + Object { + "title": "t(curiosity-inventory.header, {\\"context\\":\\"billing_provider\\"})", + "transforms": Array [ + [Function], + ], + }, Object { "title": - t(curiosity-inventory.header, {"context":"Storage-gibibytes"}) + t(curiosity-inventory.header, {"context":"Storage-gibibyte-months"}) , "transforms": Array [ [Function], @@ -223,7 +241,7 @@ Object { "chartType": "line", "color": "#5752d1", "fill": "#b2b0ea", - "id": "Storage-gibibytes", + "id": "Storage-gibibyte-months", "isStacked": false, "isStandalone": true, "isThreshold": false, @@ -268,23 +286,7 @@ Object { "title": "", }, Object { - "title": - - , + "title": "t(curiosity-inventory.label_subscription_type, {\\"context\\":\\"dolor\\"})", }, Object { "title": "2022-01-01T00:00:00.000Z", @@ -292,11 +294,11 @@ Object { ], "columnHeaders": Array [ Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"productName\\"})", + "title": "t(curiosity-inventory.header, {\\"context\\":\\"product_name\\"})", "transforms": Array [], }, Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"serviceLevel\\"})", + "title": "t(curiosity-inventory.header, {\\"context\\":\\"service_level\\"})", "transforms": Array [ [Function], ], @@ -308,37 +310,37 @@ Object { ], }, Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"subscriptions\\"})", + "title": "t(curiosity-inventory.header, {\\"context\\":\\"subscription_type\\"})", "transforms": Array [ [Function], ], }, Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"nextEventDate\\"})", + "title": "t(curiosity-inventory.header, {\\"context\\":\\"next_event_date\\"})", "transforms": Array [ [Function], ], }, ], "data": Object { - "hasInfiniteQuantity": Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"hasInfiniteQuantity\\"})", + "has_infinite_quantity": Object { + "title": "t(curiosity-inventory.header, {\\"context\\":\\"has_infinite_quantity\\"})", "value": true, }, - "nextEventDate": Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"nextEventDate\\"})", + "next_event_date": Object { + "title": "t(curiosity-inventory.header, {\\"context\\":\\"next_event_date\\"})", "value": "2022-01-01T00:00:00.000Z", }, - "productName": Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"productName\\"})", + "product_name": Object { + "title": "t(curiosity-inventory.header, {\\"context\\":\\"product_name\\"})", "value": "lorem", }, - "serviceLevel": Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"serviceLevel\\"})", + "service_level": Object { + "title": "t(curiosity-inventory.header, {\\"context\\":\\"service_level\\"})", "value": "hello world", }, - "totalCapacity": Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"totalCapacity\\"})", + "total_capacity": Object { + "title": "t(curiosity-inventory.header, {\\"context\\":\\"total_capacity\\"})", "value": 2000, }, }, @@ -358,23 +360,7 @@ Object { "title": "", }, Object { - "title": - - , + "title": "t(curiosity-inventory.label_subscription_type, {\\"context\\":\\" \\"})", }, Object { "title": "", @@ -382,11 +368,11 @@ Object { ], "columnHeaders": Array [ Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"productName\\"})", + "title": "t(curiosity-inventory.header, {\\"context\\":\\"product_name\\"})", "transforms": Array [], }, Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"serviceLevel\\"})", + "title": "t(curiosity-inventory.header, {\\"context\\":\\"service_level\\"})", "transforms": Array [ [Function], ], @@ -398,37 +384,37 @@ Object { ], }, Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"subscriptions\\"})", + "title": "t(curiosity-inventory.header, {\\"context\\":\\"subscription_type\\"})", "transforms": Array [ [Function], ], }, Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"nextEventDate\\"})", + "title": "t(curiosity-inventory.header, {\\"context\\":\\"next_event_date\\"})", "transforms": Array [ [Function], ], }, ], "data": Object { - "hasInfiniteQuantity": Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"hasInfiniteQuantity\\"})", + "has_infinite_quantity": Object { + "title": "t(curiosity-inventory.header, {\\"context\\":\\"has_infinite_quantity\\"})", "value": true, }, - "nextEventDate": Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"nextEventDate\\"})", + "next_event_date": Object { + "title": "t(curiosity-inventory.header, {\\"context\\":\\"next_event_date\\"})", "value": null, }, - "productName": Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"productName\\"})", + "product_name": Object { + "title": "t(curiosity-inventory.header, {\\"context\\":\\"product_name\\"})", "value": "lorem", }, - "serviceLevel": Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"serviceLevel\\"})", + "service_level": Object { + "title": "t(curiosity-inventory.header, {\\"context\\":\\"service_level\\"})", "value": null, }, - "totalCapacity": Object { - "title": "t(curiosity-inventory.header, {\\"context\\":\\"totalCapacity\\"})", + "total_capacity": Object { + "title": "t(curiosity-inventory.header, {\\"context\\":\\"total_capacity\\"})", "value": 2000, }, }, diff --git a/src/config/__tests__/product.openshiftContainer.test.js b/src/config/__tests__/product.openshiftContainer.test.js index 0ef5c860c..90acf58d5 100644 --- a/src/config/__tests__/product.openshiftContainer.test.js +++ b/src/config/__tests__/product.openshiftContainer.test.js @@ -4,6 +4,7 @@ import { RHSM_API_QUERY_SORT_DIRECTION_TYPES as SORT_DIRECTION_TYPES, RHSM_API_QUERY_TYPES } from '../../types/rhsmApiTypes'; +import { RHSM_API_RESPONSE_SUBSCRIPTIONS_DATA_TYPES as SUBSCRIPTIONS_INVENTORY_TYPES } from '../../services/rhsm/rhsmConstants'; describe('Product OpenShift Container config', () => { it('should apply hosts inventory configuration', () => { @@ -50,11 +51,11 @@ describe('Product OpenShift Container config', () => { config; const inventoryData = { - productName: 'lorem', - serviceLevel: 'hello world', - nextEventDate: '2022-01-01T00:00:00.000Z', - totalCapacity: 2000, - hasInfiniteQuantity: true + [SUBSCRIPTIONS_INVENTORY_TYPES.PRODUCT_NAME]: 'lorem', + [SUBSCRIPTIONS_INVENTORY_TYPES.SERVICE_LEVEL]: 'hello world', + [SUBSCRIPTIONS_INVENTORY_TYPES.NEXT_EVENT_DATE]: '2022-01-01T00:00:00.000Z', + [SUBSCRIPTIONS_INVENTORY_TYPES.TOTAL_CAPACITY]: 2000, + [SUBSCRIPTIONS_INVENTORY_TYPES.HAS_INFINITE_QUANTITY]: true }; const filteredInventoryData = parseRowCellsListData({ @@ -66,8 +67,8 @@ describe('Product OpenShift Container config', () => { const fallbackInventoryData = { ...inventoryData, - serviceLevel: null, - nextEventDate: null + [SUBSCRIPTIONS_INVENTORY_TYPES.SERVICE_LEVEL]: null, + [SUBSCRIPTIONS_INVENTORY_TYPES.NEXT_EVENT_DATE]: null }; const fallbackFilteredInventoryData = parseRowCellsListData({ diff --git a/src/config/__tests__/product.rhel.test.js b/src/config/__tests__/product.rhel.test.js index 85627a69e..5b00351c3 100644 --- a/src/config/__tests__/product.rhel.test.js +++ b/src/config/__tests__/product.rhel.test.js @@ -4,6 +4,7 @@ import { RHSM_API_QUERY_SORT_DIRECTION_TYPES as SORT_DIRECTION_TYPES, RHSM_API_QUERY_TYPES } from '../../types/rhsmApiTypes'; +import { RHSM_API_RESPONSE_SUBSCRIPTIONS_DATA_TYPES as SUBSCRIPTIONS_INVENTORY_TYPES } from '../../services/rhsm/rhsmConstants'; describe('Product RHEL config', () => { it('should apply hosts inventory configuration', () => { @@ -50,11 +51,11 @@ describe('Product RHEL config', () => { config; const inventoryData = { - productName: 'lorem', - serviceLevel: 'hello world', - nextEventDate: '2022-01-01T00:00:00.000Z', - totalCapacity: 2000, - hasInfiniteQuantity: true + [SUBSCRIPTIONS_INVENTORY_TYPES.PRODUCT_NAME]: 'lorem', + [SUBSCRIPTIONS_INVENTORY_TYPES.SERVICE_LEVEL]: 'hello world', + [SUBSCRIPTIONS_INVENTORY_TYPES.NEXT_EVENT_DATE]: '2022-01-01T00:00:00.000Z', + [SUBSCRIPTIONS_INVENTORY_TYPES.TOTAL_CAPACITY]: 2000, + [SUBSCRIPTIONS_INVENTORY_TYPES.HAS_INFINITE_QUANTITY]: true }; const filteredInventoryData = parseRowCellsListData({ @@ -66,8 +67,8 @@ describe('Product RHEL config', () => { const fallbackInventoryData = { ...inventoryData, - serviceLevel: null, - nextEventDate: null + [SUBSCRIPTIONS_INVENTORY_TYPES.SERVICE_LEVEL]: null, + [SUBSCRIPTIONS_INVENTORY_TYPES.NEXT_EVENT_DATE]: null }; const fallbackFilteredInventoryData = parseRowCellsListData({ diff --git a/src/config/__tests__/product.rhosak.test.js b/src/config/__tests__/product.rhosak.test.js index 83f46a2e2..6cd052762 100644 --- a/src/config/__tests__/product.rhosak.test.js +++ b/src/config/__tests__/product.rhosak.test.js @@ -4,6 +4,8 @@ import { parseRowCellsListData } from '../../components/inventoryCard/inventoryC import { RHSM_API_QUERY_INVENTORY_SORT_DIRECTION_TYPES as SORT_DIRECTION_TYPES, RHSM_API_RESPONSE_INSTANCES_DATA_TYPES as INVENTORY_TYPES, + RHSM_API_RESPONSE_SUBSCRIPTIONS_DATA_TYPES as SUBSCRIPTIONS_INVENTORY_TYPES, + RHSM_API_RESPONSE_SUBSCRIPTIONS_META_TYPES as SUBSCRIPTIONS_INVENTORY_META_TYPES, RHSM_API_QUERY_SET_TYPES, RHSM_API_PATH_METRIC_TYPES } from '../../services/rhsm/rhsmConstants'; @@ -87,29 +89,35 @@ describe('Product RHOSAK config', () => { config; const inventoryData = { - productName: 'lorem', - serviceLevel: 'hello world', - nextEventDate: '2022-01-01T00:00:00.000Z', - totalCapacity: 2000, - hasInfiniteQuantity: true + [SUBSCRIPTIONS_INVENTORY_TYPES.PRODUCT_NAME]: 'lorem', + [SUBSCRIPTIONS_INVENTORY_TYPES.SERVICE_LEVEL]: 'hello world', + [SUBSCRIPTIONS_INVENTORY_TYPES.NEXT_EVENT_DATE]: '2022-01-01T00:00:00.000Z', + [SUBSCRIPTIONS_INVENTORY_TYPES.TOTAL_CAPACITY]: 2000, + [SUBSCRIPTIONS_INVENTORY_TYPES.HAS_INFINITE_QUANTITY]: true + }; + + const inventoryMeta = { + [SUBSCRIPTIONS_INVENTORY_META_TYPES.SUBSCRIPTION_TYPE]: 'dolor' }; const filteredInventoryData = parseRowCellsListData({ filters: initialFilters, - cellData: inventoryData + cellData: inventoryData, + meta: inventoryMeta }); expect(filteredInventoryData).toMatchSnapshot('filtered'); const fallbackInventoryData = { ...inventoryData, - serviceLevel: null, - nextEventDate: null + [SUBSCRIPTIONS_INVENTORY_TYPES.SERVICE_LEVEL]: null, + [SUBSCRIPTIONS_INVENTORY_TYPES.NEXT_EVENT_DATE]: null }; const fallbackFilteredInventoryData = parseRowCellsListData({ filters: initialFilters, - cellData: fallbackInventoryData + cellData: fallbackInventoryData, + meta: {} }); expect(fallbackFilteredInventoryData).toMatchSnapshot('filtered, fallback display'); diff --git a/src/config/product.openshiftContainer.js b/src/config/product.openshiftContainer.js index f48139b1d..1ebd515ee 100644 --- a/src/config/product.openshiftContainer.js +++ b/src/config/product.openshiftContainer.js @@ -12,9 +12,12 @@ import { RHSM_API_QUERY_TYPES, RHSM_API_QUERY_UOM_TYPES, RHSM_API_QUERY_SORT_TYPES, - RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES, RHSM_API_PATH_ID_TYPES } from '../types/rhsmApiTypes'; +import { + RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES, + RHSM_API_RESPONSE_SUBSCRIPTIONS_DATA_TYPES as SUBSCRIPTIONS_INVENTORY_TYPES +} from '../services/rhsm/rhsmConstants'; import { dateHelpers, helpers } from '../common'; import { Tooltip } from '../components/tooltip/tooltip'; import { ChartIcon } from '../components/chart/chartIcon'; @@ -49,7 +52,7 @@ const config = { [RHSM_API_QUERY_TYPES.OFFSET]: 0 }, inventorySubscriptionsQuery: { - [RHSM_API_QUERY_TYPES.SORT]: RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES.NEXT_EVENT_DATE, + [RHSM_API_QUERY_TYPES.SORT]: RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES.NEXT_EVENT_DATE, [RHSM_API_QUERY_TYPES.DIRECTION]: SORT_DIRECTION_TYPES.DESCENDING, [RHSM_API_QUERY_TYPES.LIMIT]: 100, [RHSM_API_QUERY_TYPES.OFFSET]: 0 @@ -178,29 +181,36 @@ const config = { initialInventorySettings: {}, initialSubscriptionsInventoryFilters: [ { - id: 'productName', + id: SUBSCRIPTIONS_INVENTORY_TYPES.PRODUCT_NAME, isSortable: true, isWrappable: true }, { - id: 'serviceLevel', + id: SUBSCRIPTIONS_INVENTORY_TYPES.SERVICE_LEVEL, isSortable: true, isWrappable: true, cellWidth: 15 }, { - id: 'quantity', + id: SUBSCRIPTIONS_INVENTORY_TYPES.QUANTITY, isSortable: true, cellWidth: 20, isWrappable: true }, { - id: 'totalCapacity', - header: data => translate('curiosity-inventory.header', { context: ['subscriptions', data?.uom?.value] }), - cell: (data = {}) => { - const { hasInfiniteQuantity, totalCapacity, uom } = data; + id: SUBSCRIPTIONS_INVENTORY_TYPES.TOTAL_CAPACITY, + header: ({ [SUBSCRIPTIONS_INVENTORY_TYPES.UOM]: uom } = {}) => + translate('curiosity-inventory.header', { context: ['subscriptions', uom?.value] }), + cell: ({ + [SUBSCRIPTIONS_INVENTORY_TYPES.HAS_INFINITE_QUANTITY]: hasInfiniteQuantity, + [SUBSCRIPTIONS_INVENTORY_TYPES.TOTAL_CAPACITY]: totalCapacity, + [SUBSCRIPTIONS_INVENTORY_TYPES.UOM]: uom + } = {}) => { if (hasInfiniteQuantity?.value === true) { - const content = translate('curiosity-inventory.label', { context: ['hasInfiniteQuantity', uom?.value] }); + const content = translate( + `curiosity-inventory.label_${SUBSCRIPTIONS_INVENTORY_TYPES.HAS_INFINITE_QUANTITY}`, + { context: uom?.value } + ); return ( @@ -214,8 +224,9 @@ const config = { isWrappable: true }, { - id: 'nextEventDate', - cell: data => (data?.nextEventDate?.value && moment.utc(data?.nextEventDate?.value).format('YYYY-MM-DD')) || '', + id: SUBSCRIPTIONS_INVENTORY_TYPES.NEXT_EVENT_DATE, + cell: ({ [SUBSCRIPTIONS_INVENTORY_TYPES.NEXT_EVENT_DATE]: nextEventDate } = {}) => + (nextEventDate?.value && moment.utc(nextEventDate?.value).format('YYYY-MM-DD')) || '', isSortable: true, isWrappable: true, cellWidth: 15 diff --git a/src/config/product.rhel.js b/src/config/product.rhel.js index 456568541..cef0446f2 100644 --- a/src/config/product.rhel.js +++ b/src/config/product.rhel.js @@ -14,11 +14,14 @@ import { RHSM_API_QUERY_GRANULARITY_TYPES as GRANULARITY_TYPES, RHSM_API_QUERY_SORT_DIRECTION_TYPES as SORT_DIRECTION_TYPES, RHSM_API_QUERY_SORT_TYPES, - RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES, RHSM_API_QUERY_TYPES, RHSM_API_QUERY_UOM_TYPES, RHSM_API_PATH_ID_TYPES } from '../types/rhsmApiTypes'; +import { + RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES, + RHSM_API_RESPONSE_SUBSCRIPTIONS_DATA_TYPES as SUBSCRIPTIONS_INVENTORY_TYPES +} from '../services/rhsm/rhsmConstants'; import { dateHelpers, helpers } from '../common'; import { Tooltip } from '../components/tooltip/tooltip'; import { ChartIcon } from '../components/chart/chartIcon'; @@ -55,7 +58,7 @@ const config = { [RHSM_API_QUERY_TYPES.OFFSET]: 0 }, inventorySubscriptionsQuery: { - [RHSM_API_QUERY_TYPES.SORT]: RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES.NEXT_EVENT_DATE, + [RHSM_API_QUERY_TYPES.SORT]: RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES.NEXT_EVENT_DATE, [RHSM_API_QUERY_TYPES.DIRECTION]: SORT_DIRECTION_TYPES.DESCENDING, [RHSM_API_QUERY_TYPES.LIMIT]: 100, [RHSM_API_QUERY_TYPES.OFFSET]: 0 @@ -194,29 +197,36 @@ const config = { initialInventorySettings: {}, initialSubscriptionsInventoryFilters: [ { - id: 'productName', + id: SUBSCRIPTIONS_INVENTORY_TYPES.PRODUCT_NAME, isSortable: true, isWrappable: true }, { - id: 'serviceLevel', + id: SUBSCRIPTIONS_INVENTORY_TYPES.SERVICE_LEVEL, isSortable: true, isWrappable: true, cellWidth: 15 }, { - id: 'quantity', + id: SUBSCRIPTIONS_INVENTORY_TYPES.QUANTITY, isSortable: true, cellWidth: 10, isWrappable: true }, { - id: 'totalCapacity', - header: data => translate('curiosity-inventory.header', { context: ['subscriptions', data?.uom?.value] }), - cell: (data = {}) => { - const { hasInfiniteQuantity, totalCapacity, uom } = data; + id: SUBSCRIPTIONS_INVENTORY_TYPES.TOTAL_CAPACITY, + header: ({ [SUBSCRIPTIONS_INVENTORY_TYPES.UOM]: uom } = {}) => + translate('curiosity-inventory.header', { context: ['subscriptions', uom?.value] }), + cell: ({ + [SUBSCRIPTIONS_INVENTORY_TYPES.HAS_INFINITE_QUANTITY]: hasInfiniteQuantity, + [SUBSCRIPTIONS_INVENTORY_TYPES.TOTAL_CAPACITY]: totalCapacity, + [SUBSCRIPTIONS_INVENTORY_TYPES.UOM]: uom + } = {}) => { if (hasInfiniteQuantity?.value === true) { - const content = translate('curiosity-inventory.label', { context: ['hasInfiniteQuantity', uom?.value] }); + const content = translate( + `curiosity-inventory.label_${SUBSCRIPTIONS_INVENTORY_TYPES.HAS_INFINITE_QUANTITY}`, + { context: uom?.value } + ); return ( @@ -230,8 +240,9 @@ const config = { isWrappable: true }, { - id: 'nextEventDate', - cell: data => (data?.nextEventDate?.value && moment.utc(data?.nextEventDate?.value).format('YYYY-MM-DD')) || '', + id: SUBSCRIPTIONS_INVENTORY_TYPES.NEXT_EVENT_DATE, + cell: ({ [SUBSCRIPTIONS_INVENTORY_TYPES.NEXT_EVENT_DATE]: nextEventDate } = {}) => + (nextEventDate?.value && moment.utc(nextEventDate?.value).format('YYYY-MM-DD')) || '', isSortable: true, isWrappable: true, cellWidth: 15 diff --git a/src/config/product.rhosak.js b/src/config/product.rhosak.js index 3dd493777..0a3e26818 100644 --- a/src/config/product.rhosak.js +++ b/src/config/product.rhosak.js @@ -10,10 +10,12 @@ import { import { Button } from '@patternfly/react-core'; import { DateFormat } from '@redhat-cloud-services/frontend-components/DateFormat'; import moment from 'moment'; -import { RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES } from '../types/rhsmApiTypes'; import { RHSM_API_QUERY_INVENTORY_SORT_DIRECTION_TYPES as SORT_DIRECTION_TYPES, RHSM_API_QUERY_INVENTORY_SORT_TYPES, + RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES, + RHSM_API_RESPONSE_SUBSCRIPTIONS_DATA_TYPES as SUBSCRIPTIONS_INVENTORY_TYPES, + RHSM_API_RESPONSE_SUBSCRIPTIONS_META_TYPES as SUBSCRIPTIONS_INVENTORY_META_TYPES, RHSM_API_RESPONSE_INSTANCES_DATA_TYPES as INVENTORY_TYPES, RHSM_API_QUERY_GRANULARITY_TYPES as GRANULARITY_TYPES, RHSM_API_QUERY_SET_TYPES, @@ -21,9 +23,7 @@ import { RHSM_API_PATH_METRIC_TYPES } from '../services/rhsm/rhsmConstants'; import { dateHelpers, helpers } from '../common'; -import { Tooltip } from '../components/tooltip/tooltip'; -import { ChartIcon } from '../components/chart/chartIcon'; -import { translate } from '../components/i18n/i18n'; +import { translate, EMPTY_CONTEXT } from '../components/i18n/i18n'; /** * ToDo: evaluate separating products/product tags into individual configs... @@ -55,7 +55,7 @@ const config = { [RHSM_API_QUERY_SET_TYPES.OFFSET]: 0 }, inventorySubscriptionsQuery: { - [RHSM_API_QUERY_SET_TYPES.SORT]: RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES.NEXT_EVENT_DATE, + [RHSM_API_QUERY_SET_TYPES.SORT]: RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES.NEXT_EVENT_DATE, [RHSM_API_QUERY_SET_TYPES.DIRECTION]: SORT_DIRECTION_TYPES.DESCENDING, [RHSM_API_QUERY_SET_TYPES.LIMIT]: 100, [RHSM_API_QUERY_SET_TYPES.OFFSET]: 0 @@ -72,7 +72,7 @@ const config = { yAxisChartLabel: ({ id }) => translate('curiosity-graph.label_axisY', { context: id }) }, { - id: RHSM_API_PATH_METRIC_TYPES.STORAGE_GIBIBYTES, + id: RHSM_API_PATH_METRIC_TYPES.STORAGE_GIBIBYTE_MONTHS, fill: chartColorPurpleLight.value, stroke: chartColorPurpleDark.value, color: chartColorPurpleDark.value, @@ -140,6 +140,16 @@ const config = { }, isSortable: true }, + { + id: INVENTORY_TYPES.BILLING_PROVIDER, + cell: ({ [INVENTORY_TYPES.BILLING_PROVIDER]: provider }) => + translate(`curiosity-inventory.measurement_${INVENTORY_TYPES.BILLING_PROVIDER}`, { + context: provider?.value || 'none' + }), + isSortable: true, + isWrappable: false, + cellWidth: 15 + }, { id: RHSM_API_PATH_METRIC_TYPES.TRANSFER_GIBIBYTES, header: { @@ -158,16 +168,16 @@ const config = { cellWidth: 15 }, { - id: RHSM_API_PATH_METRIC_TYPES.STORAGE_GIBIBYTES, + id: RHSM_API_PATH_METRIC_TYPES.STORAGE_GIBIBYTE_MONTHS, header: { tooltip: () => translate('curiosity-inventory.header', { - context: ['tooltip', RHSM_API_PATH_METRIC_TYPES.STORAGE_GIBIBYTES] + context: ['tooltip', RHSM_API_PATH_METRIC_TYPES.STORAGE_GIBIBYTE_MONTHS] }) }, - cell: ({ [RHSM_API_PATH_METRIC_TYPES.STORAGE_GIBIBYTES]: total }) => + cell: ({ [RHSM_API_PATH_METRIC_TYPES.STORAGE_GIBIBYTE_MONTHS]: total }) => translate('curiosity-inventory.measurement', { - context: RHSM_API_PATH_METRIC_TYPES.STORAGE_GIBIBYTES, + context: RHSM_API_PATH_METRIC_TYPES.STORAGE_GIBIBYTE_MONTHS, total: helpers.numberDisplay(total?.value)?.format({ mantissa: 5, trimMantissa: true }) || 0 }), isSortable: true, @@ -196,47 +206,38 @@ const config = { ], initialSubscriptionsInventoryFilters: [ { - id: 'productName', + id: SUBSCRIPTIONS_INVENTORY_TYPES.PRODUCT_NAME, isSortable: true, isWrappable: true }, { - id: 'serviceLevel', + id: SUBSCRIPTIONS_INVENTORY_TYPES.SERVICE_LEVEL, isSortable: true, isWrappable: true, cellWidth: 15 }, { - id: 'quantity', + id: SUBSCRIPTIONS_INVENTORY_TYPES.QUANTITY, isSortable: true, cellWidth: 10, isWrappable: true }, { - id: 'totalCapacity', - header: data => translate('curiosity-inventory.header', { context: ['subscriptions', data?.uom?.value] }), - cell: (data = {}) => { - const { hasInfiniteQuantity, totalCapacity, uom } = data; - if (hasInfiniteQuantity?.value === true) { - const content = translate('curiosity-inventory.label', { context: ['hasInfiniteQuantity', uom?.value] }); - return ( - - - - ); - } - return totalCapacity?.value; - }, - isSortable: true, - cellWidth: 10, + id: SUBSCRIPTIONS_INVENTORY_META_TYPES.SUBSCRIPTION_TYPE, + cell: (data, session, { [SUBSCRIPTIONS_INVENTORY_META_TYPES.SUBSCRIPTION_TYPE]: subscriptionType } = {}) => + translate(`curiosity-inventory.label_${SUBSCRIPTIONS_INVENTORY_META_TYPES.SUBSCRIPTION_TYPE}`, { + context: subscriptionType || EMPTY_CONTEXT + }), + isSortable: false, + cellWidth: 15, isWrappable: true }, { - id: 'nextEventDate', - cell: data => - (data?.nextEventDate?.value && - helpers.isDate(data?.nextEventDate?.value) && - moment.utc(data?.nextEventDate?.value).format('YYYY-MM-DD')) || + id: SUBSCRIPTIONS_INVENTORY_TYPES.NEXT_EVENT_DATE, + cell: ({ [SUBSCRIPTIONS_INVENTORY_TYPES.NEXT_EVENT_DATE]: nextEventDate } = {}) => + (nextEventDate?.value && + helpers.isDate(nextEventDate?.value) && + moment.utc(nextEventDate?.value).format('YYYY-MM-DD')) || '', isSortable: true, isWrappable: true, @@ -244,6 +245,11 @@ const config = { } ], initialToolbarFilters: [ + { + id: RHSM_API_QUERY_SET_TYPES.BILLING_PROVIDER + } + ], + initialSecondaryToolbarFilters: [ { id: 'rangedMonthly' } diff --git a/src/config/product.satellite.js b/src/config/product.satellite.js index a29df8b7c..b59641197 100644 --- a/src/config/product.satellite.js +++ b/src/config/product.satellite.js @@ -13,10 +13,10 @@ import { RHSM_API_QUERY_GRANULARITY_TYPES as GRANULARITY_TYPES, RHSM_API_QUERY_SORT_DIRECTION_TYPES as SORT_DIRECTION_TYPES, RHSM_API_QUERY_SORT_TYPES, - RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES, RHSM_API_QUERY_TYPES, RHSM_API_PATH_ID_TYPES } from '../types/rhsmApiTypes'; +import { RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES } from '../services/rhsm/rhsmConstants'; import { dateHelpers, helpers } from '../common'; import { translate } from '../components/i18n/i18n'; @@ -50,7 +50,7 @@ const config = { [RHSM_API_QUERY_TYPES.OFFSET]: 0 }, inventorySubscriptionsQuery: { - [RHSM_API_QUERY_TYPES.SORT]: RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES.NEXT_EVENT_DATE, + [RHSM_API_QUERY_TYPES.SORT]: RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES.NEXT_EVENT_DATE, [RHSM_API_QUERY_TYPES.DIRECTION]: SORT_DIRECTION_TYPES.DESCENDING, [RHSM_API_QUERY_TYPES.LIMIT]: 100, [RHSM_API_QUERY_TYPES.OFFSET]: 0 diff --git a/src/redux/hooks/__tests__/__snapshots__/useRhsmActions.test.js.snap b/src/redux/hooks/__tests__/__snapshots__/useRhsmActions.test.js.snap deleted file mode 100644 index 9196fe10f..000000000 --- a/src/redux/hooks/__tests__/__snapshots__/useRhsmActions.test.js.snap +++ /dev/null @@ -1,7 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`useRhsmActions should return specific properties: specific properties 1`] = ` -Object { - "useGetMessageReports": [Function], -} -`; diff --git a/src/redux/hooks/__tests__/__snapshots__/useRhsmSelectors.test.js.snap b/src/redux/hooks/__tests__/__snapshots__/useRhsmSelectors.test.js.snap deleted file mode 100644 index 8cc152148..000000000 --- a/src/redux/hooks/__tests__/__snapshots__/useRhsmSelectors.test.js.snap +++ /dev/null @@ -1,16 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`useRhsmSelectors should apply a hook around a selector for useAppMessages: selector 1`] = ` -Object { - "appMessages": Object { - "cloudigradeMismatch": true, - }, - "query": Object {}, -} -`; - -exports[`useRhsmSelectors should return specific properties: specific properties 1`] = ` -Object { - "useAppMessages": [Function], -} -`; diff --git a/src/redux/hooks/__tests__/useRhsmActions.test.js b/src/redux/hooks/__tests__/useRhsmActions.test.js deleted file mode 100644 index 95534787d..000000000 --- a/src/redux/hooks/__tests__/useRhsmActions.test.js +++ /dev/null @@ -1,44 +0,0 @@ -import moxios from 'moxios'; -import { rhsmActionsHooks, useGetMessageReports } from '../useRhsmActions'; -import { store } from '../../store'; -import { rhsmApiTypes } from '../../../types/rhsmApiTypes'; - -describe('useRhsmActions', () => { - beforeEach(() => { - moxios.install(); - - moxios.stubRequest(/\/(tally|capacity|hosts|subscriptions|version).*?/, { - status: 200, - responseText: 'success', - timeout: 1, - response: { - test: 'success', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: ['success'] - } - }); - }); - - afterEach(() => { - moxios.uninstall(); - }); - - it('should return specific properties', () => { - expect(rhsmActionsHooks).toMatchSnapshot('specific properties'); - }); - - it('should apply a hook and receive a response for useGetMessageReports', async () => { - await mountHook(() => useGetMessageReports()); - const { report: nullIdReport } = store.getState().messages; - expect(nullIdReport.fulfilled).toBe(true); - expect(nullIdReport.metaId).toBe(null); - expect(nullIdReport.metaQuery).toMatchObject({}); - - const mockId = 'lorem'; - const mockQuery = { dolor: 'sit' }; - await mountHook(() => useGetMessageReports(mockId, mockQuery)); - const { report: mockIdReport } = store.getState().messages; - expect(mockIdReport[mockId].fulfilled).toBe(true); - expect(mockIdReport[mockId].metaId).toBe(mockId); - expect(mockIdReport[mockId].metaQuery).toMatchObject(mockQuery); - }); -}); diff --git a/src/redux/hooks/__tests__/useRhsmSelectors.test.js b/src/redux/hooks/__tests__/useRhsmSelectors.test.js deleted file mode 100644 index cc35cee8b..000000000 --- a/src/redux/hooks/__tests__/useRhsmSelectors.test.js +++ /dev/null @@ -1,70 +0,0 @@ -import { rhsmSelectorsHooks, useAppMessages } from '../useRhsmSelectors'; -import { rhsmApiTypes } from '../../../types/rhsmApiTypes'; - -describe('useRhsmSelectors', () => { - it('should return specific properties', () => { - expect(rhsmSelectorsHooks).toMatchSnapshot('specific properties'); - }); - - it('should apply a hook around a selector for useAppMessages', () => { - const mockProductId = 'lorem'; - const mockState = { - messages: { - report: { - [mockProductId]: { - fulfilled: true, - data: { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [ - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_DATA]: true, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_DATA]: true, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_MISMATCH]: true - }, - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-05T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_DATA]: true, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_DATA]: true, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_MISMATCH]: true - }, - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-06T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 4, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 4, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: null, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_DATA]: true, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_DATA]: true, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_MISMATCH]: true - } - ] - } - } - } - } - }; - - const { result } = shallowHook(() => - useAppMessages({ - useRouteDetail: () => ({ pathParameter: mockProductId, productParameter: 'viewIpsum' }), - useSelector: value => value(mockState) - }) - ); - - expect(result).toMatchSnapshot('selector'); - }); -}); diff --git a/src/redux/hooks/index.js b/src/redux/hooks/index.js index a2a18a462..9e44f055d 100644 --- a/src/redux/hooks/index.js +++ b/src/redux/hooks/index.js @@ -1,11 +1,7 @@ import { reactReduxHooks } from './useReactRedux'; -import { rhsmActionsHooks } from './useRhsmActions'; -import { rhsmSelectorsHooks } from './useRhsmSelectors'; const storeHooks = { - reactRedux: reactReduxHooks, - rhsmActions: rhsmActionsHooks, - rhsmSelectors: rhsmSelectorsHooks + reactRedux: reactReduxHooks }; -export { storeHooks as default, storeHooks, reactReduxHooks, rhsmActionsHooks, rhsmSelectorsHooks }; +export { storeHooks as default, storeHooks, reactReduxHooks }; diff --git a/src/redux/hooks/useRhsmActions.js b/src/redux/hooks/useRhsmActions.js deleted file mode 100644 index 6ad3cce17..000000000 --- a/src/redux/hooks/useRhsmActions.js +++ /dev/null @@ -1,27 +0,0 @@ -import { reactReduxHooks } from './useReactRedux'; -import { rhsmTypes } from '../types/rhsmTypes'; -import { rhsmServices } from '../../services/rhsm/rhsmServices'; - -/** - * Get an updated store RHSM response from message reporting. - * - * @param {string} id - * @param {object} query - * @returns {Function} - */ -const useGetMessageReports = (id = null, query = {}) => - reactReduxHooks.useDispatch()({ - type: rhsmTypes.GET_MESSAGE_REPORTS_RHSM, - payload: rhsmServices.getGraphReports(id, query, { cancelId: 'messageReport' }), - meta: { - id, - query, - notifications: {} - } - }); - -const rhsmActionsHooks = { - useGetMessageReports -}; - -export { rhsmActionsHooks as default, rhsmActionsHooks, useGetMessageReports }; diff --git a/src/redux/hooks/useRhsmSelectors.js b/src/redux/hooks/useRhsmSelectors.js deleted file mode 100644 index 52c9a6d04..000000000 --- a/src/redux/hooks/useRhsmSelectors.js +++ /dev/null @@ -1,28 +0,0 @@ -import { useSelector } from 'react-redux'; -import { useRouteDetail } from '../../components/router/routerContext'; -import { reduxSelectors } from '../selectors'; - -/** - * Get app messages selector results. - * - * @param {object} options - * @param {Function} options.useRouteDetail - * @param {Function} options.useSelector - * @returns {object} - */ -const useAppMessages = ({ - useRouteDetail: useAliasRouteDetail = useRouteDetail, - useSelector: useAliasSelector = useSelector -} = {}) => { - const { pathParameter: productId, productParameter: viewId } = useAliasRouteDetail() || {}; - const result = useAliasSelector(state => reduxSelectors.appMessages.appMessages(state, { productId, viewId })); - return { - ...result - }; -}; - -const rhsmSelectorsHooks = { - useAppMessages -}; - -export { rhsmSelectorsHooks as default, rhsmSelectorsHooks, useAppMessages }; diff --git a/src/redux/reducers/__tests__/__snapshots__/viewReducer.test.js.snap b/src/redux/reducers/__tests__/__snapshots__/viewReducer.test.js.snap index adbd015b6..356a07d3a 100644 --- a/src/redux/reducers/__tests__/__snapshots__/viewReducer.test.js.snap +++ b/src/redux/reducers/__tests__/__snapshots__/viewReducer.test.js.snap @@ -470,6 +470,39 @@ Object { } `; +exports[`ViewReducer should handle specific defined types: defined type SET_QUERY_RHSM_billing_provider 1`] = ` +Object { + "result": Object { + "graphTallyQuery": Object {}, + "inventoryGuestsQuery": Object { + "test_id": Object { + "offset": 5, + }, + }, + "inventoryHostsQuery": Object { + "test_id": Object { + "dir": "dolor desc direction", + "offset": 30, + "sort": "dolor sort", + }, + }, + "inventorySubscriptionsQuery": Object { + "test_id": Object { + "dir": "ipsum desc direction", + "offset": 20, + "sort": "ipsum sort", + }, + }, + "query": Object { + "test_id": Object { + "billing_provider": "dolor provider", + }, + }, + }, + "type": "SET_QUERY_RHSM_billing_provider", +} +`; + exports[`ViewReducer should handle specific defined types: defined type SET_QUERY_RHSM_ending 1`] = ` Object { "result": Object { diff --git a/src/redux/reducers/__tests__/viewReducer.test.js b/src/redux/reducers/__tests__/viewReducer.test.js index 4fd911ca0..74be507f0 100644 --- a/src/redux/reducers/__tests__/viewReducer.test.js +++ b/src/redux/reducers/__tests__/viewReducer.test.js @@ -1,6 +1,6 @@ import viewReducer from '../viewReducer'; import { queryTypes as types } from '../../types'; -import { RHSM_API_QUERY_TYPES } from '../../../types/rhsmApiTypes'; +import { RHSM_API_QUERY_SET_TYPES as RHSM_API_QUERY_TYPES } from '../../../services/rhsm/rhsmConstants'; describe('ViewReducer', () => { it('should return the initial state', () => { @@ -46,6 +46,7 @@ describe('ViewReducer', () => { const dispatched = { type: value, + [RHSM_API_QUERY_TYPES.BILLING_PROVIDER]: 'dolor provider', [RHSM_API_QUERY_TYPES.DIRECTION]: 'lorem asc direction', [RHSM_API_QUERY_TYPES.DISPLAY_NAME]: 'lorem name', [RHSM_API_QUERY_TYPES.GRANULARITY]: 'lorem granularity', diff --git a/src/redux/reducers/viewReducer.js b/src/redux/reducers/viewReducer.js index 29af0e810..6763e6b06 100644 --- a/src/redux/reducers/viewReducer.js +++ b/src/redux/reducers/viewReducer.js @@ -1,7 +1,7 @@ import { routerHelpers } from '../../components/router'; import { reduxTypes } from '../types'; import { reduxHelpers } from '../common/reduxHelpers'; -import { RHSM_API_QUERY_TYPES } from '../../types/rhsmApiTypes'; +import { RHSM_API_QUERY_SET_TYPES as RHSM_API_QUERY_TYPES } from '../../services/rhsm/rhsmConstants'; /** * Initial state. @@ -169,6 +169,20 @@ const viewReducer = (state = initialState, action) => { reset: false } ); + case reduxTypes.query.SET_QUERY_RHSM_TYPES[RHSM_API_QUERY_TYPES.BILLING_PROVIDER]: + return reduxHelpers.setStateProp( + 'query', + { + [action.viewId]: { + ...state.query[action.viewId], + [RHSM_API_QUERY_TYPES.BILLING_PROVIDER]: action[RHSM_API_QUERY_TYPES.BILLING_PROVIDER] + } + }, + { + state, + reset: false + } + ); case reduxTypes.query.SET_QUERY_RHSM_TYPES[RHSM_API_QUERY_TYPES.SLA]: return reduxHelpers.setStateProp( 'query', diff --git a/src/redux/selectors/__tests__/__snapshots__/appMessagesSelectors.test.js.snap b/src/redux/selectors/__tests__/__snapshots__/appMessagesSelectors.test.js.snap deleted file mode 100644 index 61481ee1c..000000000 --- a/src/redux/selectors/__tests__/__snapshots__/appMessagesSelectors.test.js.snap +++ /dev/null @@ -1,71 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`AppMessagesSelectors should map a fulfilled product ID response to an aggregated output: fulfilled 1`] = ` -Object { - "appMessages": Object { - "cloudigradeMismatch": true, - }, - "query": Object {}, -} -`; - -exports[`AppMessagesSelectors should pass minimal data on a product ID without a product ID provided: no product id error 1`] = ` -Object { - "appMessages": Object { - "cloudigradeMismatch": false, - }, - "query": Object {}, -} -`; - -exports[`AppMessagesSelectors should pass minimal data on missing a reducer response: missing reducer error 1`] = ` -Object { - "appMessages": Object { - "cloudigradeMismatch": false, - }, - "query": Object {}, -} -`; - -exports[`AppMessagesSelectors should populate data from the in memory cache: cached data: cache used and pending 1`] = ` -Object { - "appMessages": Object { - "cloudigradeMismatch": true, - }, - "query": Object {}, -} -`; - -exports[`AppMessagesSelectors should populate data from the in memory cache: cached data: initial fulfilled 1`] = ` -Object { - "appMessages": Object { - "cloudigradeMismatch": true, - }, - "query": Object {}, -} -`; - -exports[`AppMessagesSelectors should populate data from the in memory cache: cached data: update and fulfilled 1`] = ` -Object { - "appMessages": Object { - "cloudigradeMismatch": true, - }, - "query": Object {}, -} -`; - -exports[`AppMessagesSelectors should populate data on a product ID when the api response is missing expected properties: data populated, missing properties 1`] = ` -Object { - "appMessages": Object { - "cloudigradeMismatch": false, - }, - "query": Object {}, -} -`; - -exports[`AppMessagesSelectors should return specific selectors: selectors 1`] = ` -Object { - "appMessages": [Function], - "makeAppMessages": [Function], -} -`; diff --git a/src/redux/selectors/__tests__/appMessagesSelectors.test.js b/src/redux/selectors/__tests__/appMessagesSelectors.test.js deleted file mode 100644 index 43987259c..000000000 --- a/src/redux/selectors/__tests__/appMessagesSelectors.test.js +++ /dev/null @@ -1,207 +0,0 @@ -import appMessagesSelectors from '../appMessagesSelectors'; -import { rhsmApiTypes } from '../../../types/rhsmApiTypes'; - -describe('AppMessagesSelectors', () => { - it('should return specific selectors', () => { - expect(appMessagesSelectors).toMatchSnapshot('selectors'); - }); - - it('should pass minimal data on missing a reducer response', () => { - const state = {}; - expect(appMessagesSelectors.appMessages(state)).toMatchSnapshot('missing reducer error'); - }); - - it('should pass minimal data on a product ID without a product ID provided', () => { - const props = { - viewId: 'test', - productId: undefined - }; - const state = { - messages: { - report: { - fulfilled: true, - data: { [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [] } - } - } - }; - - expect(appMessagesSelectors.appMessages(state, props)).toMatchSnapshot('no product id error'); - }); - - it('should populate data on a product ID when the api response is missing expected properties', () => { - const props = { - viewId: 'test', - productId: 'Lorem Ipsum missing expected properties' - }; - const state = { - messages: { - report: { - 'Lorem Ipsum missing expected properties': { - fulfilled: true, - data: { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [ - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1 - }, - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-05T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1 - }, - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-06T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 4, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 2 - } - ] - } - } - } - } - }; - - expect(appMessagesSelectors.appMessages(state, props)).toMatchSnapshot('data populated, missing properties'); - }); - - it('should map a fulfilled product ID response to an aggregated output', () => { - const props = { - viewId: 'test', - productId: 'Lorem Ipsum fulfilled aggregated output' - }; - const state = { - messages: { - report: { - 'Lorem Ipsum fulfilled aggregated output': { - fulfilled: true, - data: { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [ - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_DATA]: true, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_DATA]: true, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_MISMATCH]: true - }, - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-05T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_DATA]: true, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_DATA]: true, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_MISMATCH]: true - }, - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-06T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 4, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 4, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: null, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_DATA]: true, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_DATA]: true, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_MISMATCH]: true - } - ] - } - } - } - } - }; - - expect(appMessagesSelectors.appMessages(state, props)).toMatchSnapshot('fulfilled'); - }); - - it('should populate data from the in memory cache', () => { - const props = { - viewId: 'cache-test', - productId: 'Lorem Ipsum ID cached' - }; - const stateInitialFulfilled = { - messages: { - report: { - 'Lorem Ipsum ID cached': { - fulfilled: true, - data: { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [ - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_DATA]: true, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_DATA]: true, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_MISMATCH]: true - } - ] - } - } - } - } - }; - - expect(appMessagesSelectors.appMessages(stateInitialFulfilled, props)).toMatchSnapshot( - 'cached data: initial fulfilled' - ); - - const statePending = { - messages: { - report: { - 'Lorem Ipsum ID cached': { - ...stateInitialFulfilled.messages.report['Lorem Ipsum ID cached'], - pending: true - } - } - } - }; - - expect(appMessagesSelectors.appMessages(statePending, props)).toMatchSnapshot( - 'cached data: cache used and pending' - ); - - const stateFulfilled = { - messages: { - report: { - 'Lorem Ipsum ID cached': { - ...stateInitialFulfilled.messages.report['Lorem Ipsum ID cached'], - fulfilled: true, - data: { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [ - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2018-07-04T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_DATA]: true, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_DATA]: true, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_MISMATCH]: false - } - ] - } - } - } - } - }; - - expect(appMessagesSelectors.appMessages(stateFulfilled, props)).toMatchSnapshot( - 'cached data: update and fulfilled' - ); - }); -}); diff --git a/src/redux/selectors/appMessagesSelectors.js b/src/redux/selectors/appMessagesSelectors.js deleted file mode 100644 index c556976c3..000000000 --- a/src/redux/selectors/appMessagesSelectors.js +++ /dev/null @@ -1,90 +0,0 @@ -import { createSelector } from 'reselect'; -import { rhsmApiTypes } from '../../types'; - -/** - * Selector cache. - * - * @private - * @type {{data: {object}}} - */ -const selectorCache = { data: {} }; - -/** - * Return a combined state, props object. - * - * @private - * @param {object} state - * @param {object} props - * @returns {object} - */ -const statePropsFilter = (state, props = {}) => ({ - report: state.messages?.report?.[props.productId], - viewId: props.viewId, - productId: props.productId -}); - -/** - * Return a combined query object. - * - * @param {object} state - * @param {object} props - * @returns {object} - */ -const queryFilter = (state, props = {}) => ({ - ...props.query, - ...state.view?.query?.[props.productId], - ...state.view?.query?.[props.viewId] -}); - -/** - * Create selector, transform combined state, props into a consumable object. - * - * @type {{appMessages: {cloudigradeMismatch: boolean}}} - */ -const selector = createSelector([statePropsFilter, queryFilter], (data, query = {}) => { - const { viewId = null, productId = null, report = {} } = data || {}; - const appMessages = { - cloudigradeMismatch: false - }; - - const cache = (viewId && productId && selectorCache.data[`${viewId}_${productId}`]) || undefined; - - Object.assign(appMessages, { ...cache }); - - // Scan Tally response for Cloud Meter flags - if (report.fulfilled && appMessages.cloudigradeMismatch !== true) { - const { [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: reportData = [] } = report.data || {}; - - const cloudigradeMismatch = reportData - .reverse() - .find( - ({ [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HAS_CLOUDIGRADE_MISMATCH]: mismatch }) => - mismatch === true - ); - - appMessages.cloudigradeMismatch = cloudigradeMismatch !== undefined; - - selectorCache.data[`${viewId}_${productId}`] = { - ...appMessages - }; - } - - return { appMessages, query }; -}); - -/** - * Expose selector instance. For scenarios where a selector is reused across component instances. - * - * @param {object} defaultProps - * @returns {{appMessages: {cloudigradeMismatch: boolean}}} - */ -const makeSelector = defaultProps => (state, props) => ({ - ...selector(state, props, defaultProps) -}); - -const appMessagesSelectors = { - appMessages: selector, - makeAppMessages: makeSelector -}; - -export { appMessagesSelectors as default, appMessagesSelectors, selector, makeSelector }; diff --git a/src/redux/selectors/index.js b/src/redux/selectors/index.js index 53a620d95..debc19620 100644 --- a/src/redux/selectors/index.js +++ b/src/redux/selectors/index.js @@ -1,11 +1,9 @@ -import appMessagesSelectors from './appMessagesSelectors'; import guestsListSelectors from './guestsListSelectors'; import graphCardSelectors from './graphCardSelectors'; import inventoryListSelectors from './inventoryListSelectors'; import userSelectors from './userSelectors'; const reduxSelectors = { - appMessages: appMessagesSelectors, guestsList: guestsListSelectors, graphCard: graphCardSelectors, inventoryList: inventoryListSelectors, diff --git a/src/redux/types/__tests__/__snapshots__/index.test.js.snap b/src/redux/types/__tests__/__snapshots__/index.test.js.snap index 96b8c3c7c..de59c0c30 100644 --- a/src/redux/types/__tests__/__snapshots__/index.test.js.snap +++ b/src/redux/types/__tests__/__snapshots__/index.test.js.snap @@ -52,6 +52,7 @@ Object { }, "SET_QUERY_RHSM_TYPES": Object { "beginning": "SET_QUERY_RHSM_beginning", + "billing_provider": "SET_QUERY_RHSM_billing_provider", "ending": "SET_QUERY_RHSM_ending", "granularity": "SET_QUERY_RHSM_granularity", "sla": "SET_QUERY_RHSM_sla", @@ -121,6 +122,7 @@ Object { }, "SET_QUERY_RHSM_TYPES": Object { "beginning": "SET_QUERY_RHSM_beginning", + "billing_provider": "SET_QUERY_RHSM_billing_provider", "ending": "SET_QUERY_RHSM_ending", "granularity": "SET_QUERY_RHSM_granularity", "sla": "SET_QUERY_RHSM_sla", @@ -174,6 +176,7 @@ Object { }, "SET_QUERY_RHSM_TYPES": Object { "beginning": "SET_QUERY_RHSM_beginning", + "billing_provider": "SET_QUERY_RHSM_billing_provider", "ending": "SET_QUERY_RHSM_ending", "granularity": "SET_QUERY_RHSM_granularity", "sla": "SET_QUERY_RHSM_sla", @@ -272,6 +275,7 @@ Object { }, "SET_QUERY_RHSM_TYPES": Object { "beginning": "SET_QUERY_RHSM_beginning", + "billing_provider": "SET_QUERY_RHSM_billing_provider", "ending": "SET_QUERY_RHSM_ending", "granularity": "SET_QUERY_RHSM_granularity", "sla": "SET_QUERY_RHSM_sla", diff --git a/src/redux/types/queryTypes.js b/src/redux/types/queryTypes.js index 8d07f23e0..390fc721b 100644 --- a/src/redux/types/queryTypes.js +++ b/src/redux/types/queryTypes.js @@ -1,11 +1,15 @@ -import { RHSM_API_QUERY_TYPES } from '../../types/rhsmApiTypes'; +import { RHSM_API_QUERY_SET_TYPES as RHSM_API_QUERY_TYPES } from '../../services/rhsm/rhsmConstants'; const SET_QUERY_CLEAR = 'SET_QUERY_CLEAR'; const SET_QUERY_CLEAR_INVENTORY_LIST = 'SET_QUERY_CLEAR_INVENTORY_LIST'; const SET_QUERY_CLEAR_INVENTORY_GUESTS_LIST = 'SET_QUERY_CLEAR_INVENTORY_GUESTS_LIST'; const SET_QUERY_RESET_INVENTORY_LIST = 'SET_QUERY_RESET_INVENTORY_LIST'; +/** + * Query types associated with across ALL queries. + */ const SET_QUERY_RHSM_TYPES = { + [RHSM_API_QUERY_TYPES.BILLING_PROVIDER]: `SET_QUERY_RHSM_${RHSM_API_QUERY_TYPES.BILLING_PROVIDER}`, [RHSM_API_QUERY_TYPES.END_DATE]: `SET_QUERY_RHSM_${RHSM_API_QUERY_TYPES.END_DATE}`, [RHSM_API_QUERY_TYPES.GRANULARITY]: `SET_QUERY_RHSM_${RHSM_API_QUERY_TYPES.GRANULARITY}`, [RHSM_API_QUERY_TYPES.SLA]: `SET_QUERY_RHSM_${RHSM_API_QUERY_TYPES.SLA}`, @@ -14,11 +18,17 @@ const SET_QUERY_RHSM_TYPES = { [RHSM_API_QUERY_TYPES.USAGE]: `SET_QUERY_RHSM_${RHSM_API_QUERY_TYPES.USAGE}` }; +/** + * Inventory query types associated with only GUESTS' queries. + */ const SET_QUERY_RHSM_GUESTS_INVENTORY_TYPES = { [RHSM_API_QUERY_TYPES.LIMIT]: `SET_QUERY_RHSM_GUESTS_INVENTORY_${RHSM_API_QUERY_TYPES.LIMIT}`, [RHSM_API_QUERY_TYPES.OFFSET]: `SET_QUERY_RHSM_GUESTS_INVENTORY_${RHSM_API_QUERY_TYPES.OFFSET}` }; +/** + * Inventory query types associated with only HOSTS' and INSTANCES' queries. + */ const SET_QUERY_RHSM_HOSTS_INVENTORY_TYPES = { [RHSM_API_QUERY_TYPES.DIRECTION]: `SET_QUERY_RHSM_HOSTS_INVENTORY_${RHSM_API_QUERY_TYPES.DIRECTION}`, [RHSM_API_QUERY_TYPES.DISPLAY_NAME]: `SET_QUERY_RHSM_HOSTS_INVENTORY_${RHSM_API_QUERY_TYPES.DISPLAY_NAME}`, @@ -27,6 +37,9 @@ const SET_QUERY_RHSM_HOSTS_INVENTORY_TYPES = { [RHSM_API_QUERY_TYPES.OFFSET]: `SET_QUERY_RHSM_HOSTS_INVENTORY_${RHSM_API_QUERY_TYPES.OFFSET}` }; +/** + * Inventory query types associated with only SUBSCRIPTIONS' queries. + */ const SET_QUERY_RHSM_SUBSCRIPTIONS_INVENTORY_TYPES = { [RHSM_API_QUERY_TYPES.DIRECTION]: `SET_QUERY_RHSM_SUBSCRIPTIONS_INVENTORY_${RHSM_API_QUERY_TYPES.DIRECTION}`, [RHSM_API_QUERY_TYPES.SORT]: `SET_QUERY_RHSM_SUBSCRIPTIONS_INVENTORY_${RHSM_API_QUERY_TYPES.SORT}`, diff --git a/src/services/rhsm/__tests__/__snapshots__/rhsmConstants.test.js.snap b/src/services/rhsm/__tests__/__snapshots__/rhsmConstants.test.js.snap index b31297b88..0f58878a4 100644 --- a/src/services/rhsm/__tests__/__snapshots__/rhsmConstants.test.js.snap +++ b/src/services/rhsm/__tests__/__snapshots__/rhsmConstants.test.js.snap @@ -8,6 +8,7 @@ Object { "INSTANCE_HOURS": "Instance-hours", "SOCKETS": "Sockets", "STORAGE_GIBIBYTES": "Storage-gibibytes", + "STORAGE_GIBIBYTE_MONTHS": "Storage-gibibyte-months", "TRANSFER_GIBIBYTES": "Transfer-gibibytes", }, "RHSM_API_PATH_PRODUCT_TYPES": Object { @@ -28,6 +29,11 @@ Object { "SATELLITE_CAPSULE": "Satellite Capsule", "SATELLITE_SERVER": "Satellite Server", }, + "RHSM_API_QUERY_BILLING_PROVIDER_TYPES": Object { + "AWS": "aws", + "NONE": "", + "RED_HAT": "red hat", + }, "RHSM_API_QUERY_GRANULARITY_TYPES": Object { "DAILY": "Daily", "MONTHLY": "Monthly", @@ -39,6 +45,7 @@ Object { "DESCENDING": "desc", }, "RHSM_API_QUERY_INVENTORY_SORT_TYPES": Object { + "BILLING_PROVIDER": "billing_provider", "CORES": "Cores", "CORE_SECONDS": "Core-seconds", "INSTANCE_HOURS": "Instance-hours", @@ -46,6 +53,7 @@ Object { "NAME": "display_name", "SOCKETS": "Sockets", "STORAGE_GIBIBYTES": "Storage-gibibytes", + "STORAGE_GIBIBYTE_MONTHS": "Storage-gibibyte-months", "TRANSFER_GIBIBYTES": "Transfer-gibibytes", }, "RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES": Object { @@ -59,6 +67,8 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_INVENTORY_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -71,6 +81,7 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_TALLY_CAPACITY_TYPES": Object { + "BILLING_PROVIDER": "billing_provider", "END_DATE": "ending", "GRANULARITY": "granularity", "SLA": "sla", @@ -78,6 +89,8 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -106,6 +119,11 @@ Object { "PRODUCTION": "Production", "UNSPECIFIED": "", }, + "RHSM_API_RESPONSE_BILLING_PROVIDER_TYPES": Object { + "AWS": "aws", + "NONE": "", + "RED_HAT": "red hat", + }, "RHSM_API_RESPONSE_DATA": "data", "RHSM_API_RESPONSE_ERRORS": "errors", "RHSM_API_RESPONSE_ERRORS_CODE_TYPES": Object { @@ -122,6 +140,8 @@ Object { "WEEKLY": "Weekly", }, "RHSM_API_RESPONSE_INSTANCES_DATA_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DISPLAY_NAME": "display_name", "INVENTORY_ID": "inventory_id", "LAST_SEEN": "last_seen", @@ -145,6 +165,32 @@ Object { "SELF": "Self-Support", "STANDARD": "Standard", }, + "RHSM_API_RESPONSE_SUBSCRIPTIONS_DATA_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", + "DISPLAY_NAME": "display_name", + "HAS_INFINITE_QUANTITY": "has_infinite_quantity", + "INVENTORY_ID": "inventory_id", + "LAST_SEEN": "last_seen", + "MEASUREMENTS": "measurements", + "NEXT_EVENT_DATE": "next_event_date", + "NUMBER_OF_GUESTS": "number_of_guests", + "PRODUCT_NAME": "product_name", + "QUANTITY": "quantity", + "SERVICE_LEVEL": "service_level", + "SUBSCRIPTION_MANAGER_ID": "subscription_manager_id", + "TOTAL_CAPACITY": "total_capacity", + "UOM": "uom", + }, + "RHSM_API_RESPONSE_SUBSCRIPTIONS_META_TYPES": Object { + "COUNT": "count", + "PRODUCT": "product", + "SUBSCRIPTION_TYPE": "subscription_type", + }, + "RHSM_API_RESPONSE_SUBSCRIPTION_TYPES": Object { + "ANNUAL": "Annual", + "ON_DEMAND": "On-demand", + }, "RHSM_API_RESPONSE_TALLY_DATA_TYPES": Object { "DATE": "date", "HAS_DATA": "has_data", @@ -178,6 +224,7 @@ Object { "INSTANCE_HOURS": "Instance-hours", "SOCKETS": "Sockets", "STORAGE_GIBIBYTES": "Storage-gibibytes", + "STORAGE_GIBIBYTE_MONTHS": "Storage-gibibyte-months", "TRANSFER_GIBIBYTES": "Transfer-gibibytes", }, "RHSM_API_PATH_PRODUCT_TYPES": Object { @@ -198,6 +245,11 @@ Object { "SATELLITE_CAPSULE": "Satellite Capsule", "SATELLITE_SERVER": "Satellite Server", }, + "RHSM_API_QUERY_BILLING_PROVIDER_TYPES": Object { + "AWS": "aws", + "NONE": "", + "RED_HAT": "red hat", + }, "RHSM_API_QUERY_GRANULARITY_TYPES": Object { "DAILY": "Daily", "MONTHLY": "Monthly", @@ -209,6 +261,7 @@ Object { "DESCENDING": "desc", }, "RHSM_API_QUERY_INVENTORY_SORT_TYPES": Object { + "BILLING_PROVIDER": "billing_provider", "CORES": "Cores", "CORE_SECONDS": "Core-seconds", "INSTANCE_HOURS": "Instance-hours", @@ -216,6 +269,7 @@ Object { "NAME": "display_name", "SOCKETS": "Sockets", "STORAGE_GIBIBYTES": "Storage-gibibytes", + "STORAGE_GIBIBYTE_MONTHS": "Storage-gibibyte-months", "TRANSFER_GIBIBYTES": "Transfer-gibibytes", }, "RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES": Object { @@ -229,6 +283,8 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_INVENTORY_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -241,6 +297,7 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_TALLY_CAPACITY_TYPES": Object { + "BILLING_PROVIDER": "billing_provider", "END_DATE": "ending", "GRANULARITY": "granularity", "SLA": "sla", @@ -248,6 +305,8 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -276,6 +335,11 @@ Object { "PRODUCTION": "Production", "UNSPECIFIED": "", }, + "RHSM_API_RESPONSE_BILLING_PROVIDER_TYPES": Object { + "AWS": "aws", + "NONE": "", + "RED_HAT": "red hat", + }, "RHSM_API_RESPONSE_DATA": "data", "RHSM_API_RESPONSE_ERRORS": "errors", "RHSM_API_RESPONSE_ERRORS_CODE_TYPES": Object { @@ -292,6 +356,8 @@ Object { "WEEKLY": "Weekly", }, "RHSM_API_RESPONSE_INSTANCES_DATA_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DISPLAY_NAME": "display_name", "INVENTORY_ID": "inventory_id", "LAST_SEEN": "last_seen", @@ -315,6 +381,32 @@ Object { "SELF": "Self-Support", "STANDARD": "Standard", }, + "RHSM_API_RESPONSE_SUBSCRIPTIONS_DATA_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", + "DISPLAY_NAME": "display_name", + "HAS_INFINITE_QUANTITY": "has_infinite_quantity", + "INVENTORY_ID": "inventory_id", + "LAST_SEEN": "last_seen", + "MEASUREMENTS": "measurements", + "NEXT_EVENT_DATE": "next_event_date", + "NUMBER_OF_GUESTS": "number_of_guests", + "PRODUCT_NAME": "product_name", + "QUANTITY": "quantity", + "SERVICE_LEVEL": "service_level", + "SUBSCRIPTION_MANAGER_ID": "subscription_manager_id", + "TOTAL_CAPACITY": "total_capacity", + "UOM": "uom", + }, + "RHSM_API_RESPONSE_SUBSCRIPTIONS_META_TYPES": Object { + "COUNT": "count", + "PRODUCT": "product", + "SUBSCRIPTION_TYPE": "subscription_type", + }, + "RHSM_API_RESPONSE_SUBSCRIPTION_TYPES": Object { + "ANNUAL": "Annual", + "ON_DEMAND": "On-demand", + }, "RHSM_API_RESPONSE_TALLY_DATA_TYPES": Object { "DATE": "date", "HAS_DATA": "has_data", @@ -349,6 +441,7 @@ Object { "INSTANCE_HOURS": "Instance-hours", "SOCKETS": "Sockets", "STORAGE_GIBIBYTES": "Storage-gibibytes", + "STORAGE_GIBIBYTE_MONTHS": "Storage-gibibyte-months", "TRANSFER_GIBIBYTES": "Transfer-gibibytes", }, "RHSM_API_PATH_PRODUCT_TYPES": Object { @@ -369,6 +462,11 @@ Object { "SATELLITE_CAPSULE": "Satellite Capsule", "SATELLITE_SERVER": "Satellite Server", }, + "RHSM_API_QUERY_BILLING_PROVIDER_TYPES": Object { + "AWS": "aws", + "NONE": "", + "RED_HAT": "red hat", + }, "RHSM_API_QUERY_GRANULARITY_TYPES": Object { "DAILY": "Daily", "MONTHLY": "Monthly", @@ -380,6 +478,7 @@ Object { "DESCENDING": "desc", }, "RHSM_API_QUERY_INVENTORY_SORT_TYPES": Object { + "BILLING_PROVIDER": "billing_provider", "CORES": "Cores", "CORE_SECONDS": "Core-seconds", "INSTANCE_HOURS": "Instance-hours", @@ -387,6 +486,7 @@ Object { "NAME": "display_name", "SOCKETS": "Sockets", "STORAGE_GIBIBYTES": "Storage-gibibytes", + "STORAGE_GIBIBYTE_MONTHS": "Storage-gibibyte-months", "TRANSFER_GIBIBYTES": "Transfer-gibibytes", }, "RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES": Object { @@ -400,6 +500,8 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_INVENTORY_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -412,6 +514,7 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_TALLY_CAPACITY_TYPES": Object { + "BILLING_PROVIDER": "billing_provider", "END_DATE": "ending", "GRANULARITY": "granularity", "SLA": "sla", @@ -419,6 +522,8 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -447,6 +552,11 @@ Object { "PRODUCTION": "Production", "UNSPECIFIED": "", }, + "RHSM_API_RESPONSE_BILLING_PROVIDER_TYPES": Object { + "AWS": "aws", + "NONE": "", + "RED_HAT": "red hat", + }, "RHSM_API_RESPONSE_DATA": "data", "RHSM_API_RESPONSE_ERRORS": "errors", "RHSM_API_RESPONSE_ERRORS_CODE_TYPES": Object { @@ -463,6 +573,8 @@ Object { "WEEKLY": "Weekly", }, "RHSM_API_RESPONSE_INSTANCES_DATA_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DISPLAY_NAME": "display_name", "INVENTORY_ID": "inventory_id", "LAST_SEEN": "last_seen", @@ -486,6 +598,32 @@ Object { "SELF": "Self-Support", "STANDARD": "Standard", }, + "RHSM_API_RESPONSE_SUBSCRIPTIONS_DATA_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", + "DISPLAY_NAME": "display_name", + "HAS_INFINITE_QUANTITY": "has_infinite_quantity", + "INVENTORY_ID": "inventory_id", + "LAST_SEEN": "last_seen", + "MEASUREMENTS": "measurements", + "NEXT_EVENT_DATE": "next_event_date", + "NUMBER_OF_GUESTS": "number_of_guests", + "PRODUCT_NAME": "product_name", + "QUANTITY": "quantity", + "SERVICE_LEVEL": "service_level", + "SUBSCRIPTION_MANAGER_ID": "subscription_manager_id", + "TOTAL_CAPACITY": "total_capacity", + "UOM": "uom", + }, + "RHSM_API_RESPONSE_SUBSCRIPTIONS_META_TYPES": Object { + "COUNT": "count", + "PRODUCT": "product", + "SUBSCRIPTION_TYPE": "subscription_type", + }, + "RHSM_API_RESPONSE_SUBSCRIPTION_TYPES": Object { + "ANNUAL": "Annual", + "ON_DEMAND": "On-demand", + }, "RHSM_API_RESPONSE_TALLY_DATA_TYPES": Object { "DATE": "date", "HAS_DATA": "has_data", @@ -524,6 +662,7 @@ Object { "INSTANCE_HOURS": "Instance-hours", "SOCKETS": "Sockets", "STORAGE_GIBIBYTES": "Storage-gibibytes", + "STORAGE_GIBIBYTE_MONTHS": "Storage-gibibyte-months", "TRANSFER_GIBIBYTES": "Transfer-gibibytes", }, "RHSM_API_PATH_PRODUCT_TYPES": Object { @@ -544,6 +683,11 @@ Object { "SATELLITE_CAPSULE": "Satellite Capsule", "SATELLITE_SERVER": "Satellite Server", }, + "RHSM_API_QUERY_BILLING_PROVIDER_TYPES": Object { + "AWS": "aws", + "NONE": "", + "RED_HAT": "red hat", + }, "RHSM_API_QUERY_GRANULARITY_TYPES": Object { "DAILY": "Daily", "MONTHLY": "Monthly", @@ -555,6 +699,7 @@ Object { "DESCENDING": "desc", }, "RHSM_API_QUERY_INVENTORY_SORT_TYPES": Object { + "BILLING_PROVIDER": "billing_provider", "CORES": "Cores", "CORE_SECONDS": "Core-seconds", "INSTANCE_HOURS": "Instance-hours", @@ -562,6 +707,7 @@ Object { "NAME": "display_name", "SOCKETS": "Sockets", "STORAGE_GIBIBYTES": "Storage-gibibytes", + "STORAGE_GIBIBYTE_MONTHS": "Storage-gibibyte-months", "TRANSFER_GIBIBYTES": "Transfer-gibibytes", }, "RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES": Object { @@ -575,6 +721,8 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_INVENTORY_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -587,6 +735,7 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_TALLY_CAPACITY_TYPES": Object { + "BILLING_PROVIDER": "billing_provider", "END_DATE": "ending", "GRANULARITY": "granularity", "SLA": "sla", @@ -594,6 +743,8 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -622,6 +773,11 @@ Object { "PRODUCTION": "Production", "UNSPECIFIED": "", }, + "RHSM_API_RESPONSE_BILLING_PROVIDER_TYPES": Object { + "AWS": "aws", + "NONE": "", + "RED_HAT": "red hat", + }, "RHSM_API_RESPONSE_DATA": "data", "RHSM_API_RESPONSE_ERRORS": "errors", "RHSM_API_RESPONSE_ERRORS_CODE_TYPES": Object { @@ -638,6 +794,8 @@ Object { "WEEKLY": "Weekly", }, "RHSM_API_RESPONSE_INSTANCES_DATA_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DISPLAY_NAME": "display_name", "INVENTORY_ID": "inventory_id", "LAST_SEEN": "last_seen", @@ -661,6 +819,32 @@ Object { "SELF": "Self-Support", "STANDARD": "Standard", }, + "RHSM_API_RESPONSE_SUBSCRIPTIONS_DATA_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", + "DISPLAY_NAME": "display_name", + "HAS_INFINITE_QUANTITY": "has_infinite_quantity", + "INVENTORY_ID": "inventory_id", + "LAST_SEEN": "last_seen", + "MEASUREMENTS": "measurements", + "NEXT_EVENT_DATE": "next_event_date", + "NUMBER_OF_GUESTS": "number_of_guests", + "PRODUCT_NAME": "product_name", + "QUANTITY": "quantity", + "SERVICE_LEVEL": "service_level", + "SUBSCRIPTION_MANAGER_ID": "subscription_manager_id", + "TOTAL_CAPACITY": "total_capacity", + "UOM": "uom", + }, + "RHSM_API_RESPONSE_SUBSCRIPTIONS_META_TYPES": Object { + "COUNT": "count", + "PRODUCT": "product", + "SUBSCRIPTION_TYPE": "subscription_type", + }, + "RHSM_API_RESPONSE_SUBSCRIPTION_TYPES": Object { + "ANNUAL": "Annual", + "ON_DEMAND": "On-demand", + }, "RHSM_API_RESPONSE_TALLY_DATA_TYPES": Object { "DATE": "date", "HAS_DATA": "has_data", diff --git a/src/services/rhsm/__tests__/__snapshots__/rhsmTransformers.test.js.snap b/src/services/rhsm/__tests__/__snapshots__/rhsmTransformers.test.js.snap index 2be437bc2..5a7d17bc7 100644 --- a/src/services/rhsm/__tests__/__snapshots__/rhsmTransformers.test.js.snap +++ b/src/services/rhsm/__tests__/__snapshots__/rhsmTransformers.test.js.snap @@ -4,6 +4,199 @@ exports[`RHSM Transformers should attempt to parse a tally response: tally 1`] = Object { "data": Array [], "meta": Object { + "cloudigradeHasMismatch": undefined, + "count": undefined, + "metricId": undefined, + "productId": undefined, + "totalMonthlyDate": undefined, + "totalMonthlyHasData": undefined, + "totalMonthlyValue": undefined, + }, +} +`; + +exports[`RHSM Transformers should attempt to parse a tally response: tally, daily like granularity 1`] = ` +Object { + "data": Array [ + Object { + "date": "2019-07-14T00:00:00Z", + "hasData": false, + "isCurrentDate": false, + "isFutureDate": false, + "x": 0, + "y": 0, + }, + Object { + "date": "2019-07-15T00:00:00Z", + "hasData": false, + "isCurrentDate": false, + "isFutureDate": false, + "x": 1, + "y": 0, + }, + Object { + "date": "2019-07-16T00:00:00Z", + "hasData": true, + "isCurrentDate": false, + "isFutureDate": false, + "x": 2, + "y": 1.4977989514668784, + }, + Object { + "date": "2019-07-17T00:00:00Z", + "hasData": true, + "isCurrentDate": false, + "isFutureDate": false, + "x": 3, + "y": 1.5547887908087836, + }, + Object { + "date": "2019-07-18T00:00:00Z", + "hasData": true, + "isCurrentDate": false, + "isFutureDate": false, + "x": 4, + "y": 4.446975872251722, + }, + Object { + "date": "2019-07-19T00:00:00Z", + "hasData": true, + "isCurrentDate": false, + "isFutureDate": false, + "x": 5, + "y": 4.69084013303121, + }, + Object { + "date": "2019-07-20T00:00:00Z", + "hasData": false, + "isCurrentDate": true, + "isFutureDate": false, + "x": 6, + "y": null, + }, + Object { + "date": "2019-07-21T00:00:00Z", + "hasData": false, + "isCurrentDate": false, + "isFutureDate": true, + "x": 7, + "y": null, + }, + Object { + "date": "2019-07-22T00:00:00Z", + "hasData": false, + "isCurrentDate": false, + "isFutureDate": true, + "x": 8, + "y": null, + }, + Object { + "date": "2019-07-23T00:00:00Z", + "hasData": false, + "isCurrentDate": false, + "isFutureDate": true, + "x": 9, + "y": null, + }, + Object { + "date": "2019-07-24T00:00:00Z", + "hasData": false, + "isCurrentDate": false, + "isFutureDate": true, + "x": 10, + "y": null, + }, + Object { + "date": "2019-07-25T00:00:00Z", + "hasData": false, + "isCurrentDate": false, + "isFutureDate": true, + "x": 11, + "y": null, + }, + ], + "meta": Object { + "cloudigradeHasMismatch": undefined, + "count": undefined, + "metricId": undefined, + "productId": undefined, + "totalMonthlyDate": undefined, + "totalMonthlyHasData": undefined, + "totalMonthlyValue": undefined, + }, +} +`; + +exports[`RHSM Transformers should attempt to parse a tally response: tally, monthly like granularity 1`] = ` +Object { + "data": Array [ + Object { + "date": "2019-01-01T00:00:00Z", + "hasData": false, + "isCurrentDate": false, + "isFutureDate": false, + "x": 0, + "y": 0, + }, + Object { + "date": "2019-02-01T00:00:00Z", + "hasData": false, + "isCurrentDate": false, + "isFutureDate": false, + "x": 1, + "y": 0, + }, + Object { + "date": "2019-03-01T00:00:00Z", + "hasData": false, + "isCurrentDate": false, + "isFutureDate": false, + "x": 2, + "y": 0, + }, + Object { + "date": "2019-04-01T00:00:00Z", + "hasData": false, + "isCurrentDate": false, + "isFutureDate": false, + "x": 3, + "y": 0, + }, + Object { + "date": "2019-05-01T00:00:00Z", + "hasData": true, + "isCurrentDate": false, + "isFutureDate": false, + "x": 4, + "y": 4.767144674723709, + }, + Object { + "date": "2019-06-01T00:00:00Z", + "hasData": true, + "isCurrentDate": false, + "isFutureDate": false, + "x": 5, + "y": 4.446975872251722, + }, + Object { + "date": "2019-07-01T00:00:00Z", + "hasData": false, + "isCurrentDate": false, + "isFutureDate": false, + "x": 6, + "y": 0, + }, + Object { + "date": "2019-08-01T00:00:00Z", + "hasData": false, + "isCurrentDate": false, + "isFutureDate": true, + "x": 7, + "y": null, + }, + ], + "meta": Object { + "cloudigradeHasMismatch": undefined, "count": undefined, "metricId": undefined, "productId": undefined, diff --git a/src/services/rhsm/__tests__/rhsmTransformers.test.js b/src/services/rhsm/__tests__/rhsmTransformers.test.js index 5bf349350..4faea8401 100644 --- a/src/services/rhsm/__tests__/rhsmTransformers.test.js +++ b/src/services/rhsm/__tests__/rhsmTransformers.test.js @@ -1,5 +1,5 @@ import { rhsmTransformers } from '../rhsmTransformers'; -import { rhsmConstants } from '../rhsmConstants'; +import { rhsmConstants, RHSM_API_RESPONSE_TALLY_DATA_TYPES as TALLY_DATA_TYPES } from '../rhsmConstants'; describe('RHSM Transformers', () => { it('should have specific response transformers', () => { @@ -22,6 +22,127 @@ describe('RHSM Transformers', () => { }); it('should attempt to parse a tally response', () => { - expect(rhsmTransformers.tally()).toMatchSnapshot('tally'); + const baseTallyResponse = { + [rhsmConstants.RHSM_API_RESPONSE_DATA]: [], + [rhsmConstants.RHSM_API_RESPONSE_META]: {} + }; + + expect(rhsmTransformers.tally(baseTallyResponse)).toMatchSnapshot('tally'); + + const dailyTallyResponse = { + [rhsmConstants.RHSM_API_RESPONSE_DATA]: [ + { + [TALLY_DATA_TYPES.DATE]: '2019-07-14T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 0.0, + [TALLY_DATA_TYPES.HAS_DATA]: false + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-07-15T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 0.0, + [TALLY_DATA_TYPES.HAS_DATA]: false + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-07-16T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 1.4977989514668784, + [TALLY_DATA_TYPES.HAS_DATA]: true + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-07-17T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 1.5547887908087836, + [TALLY_DATA_TYPES.HAS_DATA]: true + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-07-18T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 4.446975872251722, + [TALLY_DATA_TYPES.HAS_DATA]: true + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-07-19T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 4.69084013303121, + [TALLY_DATA_TYPES.HAS_DATA]: true + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-07-20T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 0.0, + [TALLY_DATA_TYPES.HAS_DATA]: false + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-07-21T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 0.0, + [TALLY_DATA_TYPES.HAS_DATA]: false + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-07-22T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 0.0, + [TALLY_DATA_TYPES.HAS_DATA]: false + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-07-23T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 0.0, + [TALLY_DATA_TYPES.HAS_DATA]: false + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-07-24T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 0.0, + [TALLY_DATA_TYPES.HAS_DATA]: false + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-07-25T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 0.0, + [TALLY_DATA_TYPES.HAS_DATA]: false + } + ], + [rhsmConstants.RHSM_API_RESPONSE_META]: {} + }; + + expect(rhsmTransformers.tally(dailyTallyResponse)).toMatchSnapshot('tally, daily like granularity'); + + const monthlyTallyResponse = { + [rhsmConstants.RHSM_API_RESPONSE_DATA]: [ + { + [TALLY_DATA_TYPES.DATE]: '2019-01-01T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 0.0, + [TALLY_DATA_TYPES.HAS_DATA]: false + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-02-01T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 0.0, + [TALLY_DATA_TYPES.HAS_DATA]: false + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-03-01T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 0.0, + [TALLY_DATA_TYPES.HAS_DATA]: false + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-04-01T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 0.0, + [TALLY_DATA_TYPES.HAS_DATA]: false + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-05-01T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 4.767144674723709, + [TALLY_DATA_TYPES.HAS_DATA]: true + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-06-01T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 4.446975872251722, + [TALLY_DATA_TYPES.HAS_DATA]: true + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-07-01T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 0.0, + [TALLY_DATA_TYPES.HAS_DATA]: false + }, + { + [TALLY_DATA_TYPES.DATE]: '2019-08-01T00:00:00Z', + [TALLY_DATA_TYPES.VALUE]: 0.0, + [TALLY_DATA_TYPES.HAS_DATA]: false + } + ], + [rhsmConstants.RHSM_API_RESPONSE_META]: {} + }; + + expect(rhsmTransformers.tally(monthlyTallyResponse)).toMatchSnapshot('tally, monthly like granularity'); }); }); diff --git a/src/services/rhsm/rhsmConstants.js b/src/services/rhsm/rhsmConstants.js index e6dc7d251..ff738410c 100644 --- a/src/services/rhsm/rhsmConstants.js +++ b/src/services/rhsm/rhsmConstants.js @@ -33,7 +33,7 @@ const RHSM_API_PATH_PRODUCT_TYPES = { /** * RHSM path IDs for metrics. * - * @type {{CORES: string, STORAGE_GIBIBYTES: string, SOCKETS: string, INSTANCE_HOURS: string, + * @type {{CORES: string, STORAGE_GIBIBYTES: string, SOCKETS: string, INSTANCE_HOURS: string, STORAGE_GIBIBYTE_MONTHS: string, * TRANSFER_GIBIBYTES: string, CORE_SECONDS: string}} */ const RHSM_API_PATH_METRIC_TYPES = { @@ -42,6 +42,7 @@ const RHSM_API_PATH_METRIC_TYPES = { CORE_SECONDS: 'Core-seconds', INSTANCE_HOURS: 'Instance-hours', STORAGE_GIBIBYTES: 'Storage-gibibytes', + STORAGE_GIBIBYTE_MONTHS: 'Storage-gibibyte-months', TRANSFER_GIBIBYTES: 'Transfer-gibibytes' }; @@ -95,13 +96,20 @@ const RHSM_API_RESPONSE_ERRORS_CODE_TYPES = { OPTIN: 'SUBSCRIPTIONS1004' }; +/** + * FixMe: Appears we combined future guests used with instances. Investigate moving "INVENTORY_ID" and "SUBSCRIPTION_MANAGER_ID". + * They're current associated with "hosts" guests. Need to also determine if this is something that needs to be added to "instances" + * or if keeping them added to guests only is enough. + */ /** * RHSM response Instance DATA types. * - * @type {{MEASUREMENTS: string, SUBSCRIPTION_MANAGER_ID: string, INVENTORY_ID: string, NUMBER_OF_GUESTS: string, - * DISPLAY_NAME: string, LAST_SEEN: string}} + * @type {{MEASUREMENTS: string, BILLING_ACCOUNT_ID: string, SUBSCRIPTION_MANAGER_ID: string, INVENTORY_ID: string, + * NUMBER_OF_GUESTS: string, BILLING_PROVIDER: string, DISPLAY_NAME: string, LAST_SEEN: string}} */ const RHSM_API_RESPONSE_INSTANCES_DATA_TYPES = { + BILLING_PROVIDER: 'billing_provider', + BILLING_ACCOUNT_ID: 'billing_account_id', DISPLAY_NAME: 'display_name', INVENTORY_ID: 'inventory_id', LAST_SEEN: 'last_seen', @@ -120,6 +128,35 @@ const RHSM_API_RESPONSE_INSTANCES_META_TYPES = { MEASUREMENTS: 'measurements' }; +/** + * RHSM response Subscriptions DATA types. + * + * @type {{BILLING_ACCOUNT_ID: string, QUANTITY: string, SUBSCRIPTION_MANAGER_ID: string, INVENTORY_ID: string, + * NUMBER_OF_GUESTS: string, HAS_INFINITE_QUANTITY: string, TOTAL_CAPACITY: string, PRODUCT_NAME: string, + * SERVICE_LEVEL: string, DISPLAY_NAME: string, MEASUREMENTS: string, UOM: string, NEXT_EVENT_DATE: string, + * BILLING_PROVIDER: string, LAST_SEEN: string}} + */ +const RHSM_API_RESPONSE_SUBSCRIPTIONS_DATA_TYPES = { + ...RHSM_API_RESPONSE_INSTANCES_DATA_TYPES, + HAS_INFINITE_QUANTITY: 'has_infinite_quantity', + NEXT_EVENT_DATE: 'next_event_date', + PRODUCT_NAME: 'product_name', + QUANTITY: 'quantity', + SERVICE_LEVEL: 'service_level', + TOTAL_CAPACITY: 'total_capacity', + UOM: 'uom' +}; + +/** + * RHSM response Subscriptions META types. + * + * @type {{PRODUCT: string, SUBSCRIPTION_TYPE: string, COUNT: string}} + */ +const RHSM_API_RESPONSE_SUBSCRIPTIONS_META_TYPES = { + ...RHSM_API_RESPONSE_META_TYPES, + SUBSCRIPTION_TYPE: 'subscription_type' +}; + /** * RHSM response Tally DATA types. * @@ -160,6 +197,24 @@ const RHSM_API_RESPONSE_GRANULARITY_TYPES = { QUARTERLY: 'Quarterly' }; +/** + * ToDo: Activate available provider type as it becomes available 202205 + * (just uncomment) + */ +/** + * RHSM response, query parameters for BILLING_PROVIDER + * + * @type {{AZURE: string, GCP: string, RED_HAT: string, NONE: string, AWS: string, ORACLE: string}} + */ +const RHSM_API_RESPONSE_BILLING_PROVIDER_TYPES = { + RED_HAT: 'red hat', + AWS: 'aws', + // GCP: 'gcp', + // AZURE: 'azure', + // ORACLE: 'oracle', + NONE: '' +}; + /** * RHSM response, query parameters for SLA. * @@ -172,6 +227,16 @@ const RHSM_API_RESPONSE_SLA_TYPES = { NONE: '' }; +/** + * RHSM response, general parameters for subscription types + * + * @type {{ANNUAL: string, ON_DEMAND: string}} + */ +const RHSM_API_RESPONSE_SUBSCRIPTION_TYPES = { + ANNUAL: 'Annual', + ON_DEMAND: 'On-demand' +}; + /** * RHSM response, query parameters for UOM. * @@ -205,11 +270,12 @@ const RHSM_API_QUERY_GRANULARITY_TYPES = RHSM_API_RESPONSE_GRANULARITY_TYPES; /** * RHSM API query/search parameter SORT type values for HOSTS. * - * @type {{CORES: string, CORE_HOURS: string, HARDWARE: string, SOCKETS: string, MEASUREMENT: string, - * LAST_SEEN: string, NAME: string}} + * @type {{CORES: string, STORAGE_GIBIBYTES: string, SOCKETS: string, INSTANCE_HOURS: string, + * TRANSFER_GIBIBYTES: string, BILLING_PROVIDER: string, CORE_SECONDS: string, LAST_SEEN: string, NAME: string}} */ const RHSM_API_QUERY_INVENTORY_SORT_TYPES = { ...RHSM_API_PATH_METRIC_TYPES, + BILLING_PROVIDER: 'billing_provider', LAST_SEEN: 'last_seen', NAME: 'display_name' }; @@ -241,6 +307,8 @@ const RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES = { USAGE: 'usage' }; +const RHSM_API_QUERY_BILLING_PROVIDER_TYPES = RHSM_API_RESPONSE_BILLING_PROVIDER_TYPES; + const RHSM_API_QUERY_SLA_TYPES = RHSM_API_RESPONSE_SLA_TYPES; const RHSM_API_QUERY_UOM_TYPES = RHSM_API_RESPONSE_UOM_TYPES; @@ -250,10 +318,13 @@ const RHSM_API_QUERY_USAGE_TYPES = RHSM_API_RESPONSE_USAGE_TYPES; /** * RHSM API query/search parameter INVENTORY type values. * - * @type {{UOM: string, USAGE: string, DIRECTION: string, SORT: string, END_DATE: string, OFFSET: string, - * SLA: string, LIMIT: string, START_DATE: string, DISPLAY_NAME: string}} + * @type {{UOM: string, BILLING_ACCOUNT_ID: string, USAGE: string, DIRECTION: string, SORT: string, + * END_DATE: string, OFFSET: string, SLA: string, LIMIT: string, START_DATE: string, + * BILLING_PROVIDER: string, DISPLAY_NAME: string}} */ const RHSM_API_QUERY_SET_INVENTORY_TYPES = { + BILLING_PROVIDER: 'billing_provider', + BILLING_ACCOUNT_ID: 'billing_account_id', DIRECTION: 'dir', DISPLAY_NAME: 'display_name_contains', END_DATE: 'ending', @@ -269,9 +340,10 @@ const RHSM_API_QUERY_SET_INVENTORY_TYPES = { /** * RHSM query parameter options for TALLY, CAPACITY endpoints. * - * @type {{GRANULARITY: string, USAGE: string, END_DATE: string, SLA: string, START_DATE: string}} + * @type {{GRANULARITY: string, USAGE: string, END_DATE: string, SLA: string, START_DATE: string, BILLING_PROVIDER: string}} */ const RHSM_API_QUERY_SET_TALLY_CAPACITY_TYPES = { + BILLING_PROVIDER: 'billing_provider', END_DATE: 'ending', GRANULARITY: 'granularity', SLA: 'sla', @@ -293,36 +365,42 @@ const RHSM_API_QUERY_SET_TYPES = { /** * RHSM constants. * - * @type {{RHSM_API_QUERY_SET_TALLY_CAPACITY_TYPES: {GRANULARITY: string, USAGE: string, END_DATE: string, SLA: string, - * START_DATE: string}, RHSM_API_RESPONSE_DATA: string, RHSM_API_PATH_METRIC_TYPES: {CORES: string, STORAGE_GIBIBYTES: string, - * SOCKETS: string, INSTANCE_HOURS: string, TRANSFER_GIBIBYTES: string, CORE_SECONDS: string}, + * @type {{RHSM_API_QUERY_SET_TALLY_CAPACITY_TYPES: {GRANULARITY: string, USAGE: string, END_DATE: string, SLA: string, START_DATE: string, + * BILLING_PROVIDER: string}, RHSM_API_RESPONSE_DATA: string, RHSM_API_RESPONSE_SUBSCRIPTIONS_META_TYPES: {PRODUCT: string, + * SUBSCRIPTION_TYPE: string, COUNT: string}, RHSM_API_PATH_METRIC_TYPES: {CORES: string, STORAGE_GIBIBYTES: string, SOCKETS: string, + * INSTANCE_HOURS: string, STORAGE_GIBIBYTE_MONTHS: string, TRANSFER_GIBIBYTES: string, CORE_SECONDS: string}, * RHSM_API_RESPONSE_TALLY_DATA_TYPES: {DATE: string, HAS_DATA: string, VALUE: string}, * RHSM_API_RESPONSE_INSTANCES_META_TYPES: {MEASUREMENTS: string, PRODUCT: string, COUNT: string}, - * RHSM_API_RESPONSE_INSTANCES_DATA_TYPES: {MEASUREMENTS: string, SUBSCRIPTION_MANAGER_ID: string, INVENTORY_ID: string, - * NUMBER_OF_GUESTS: string, DISPLAY_NAME: string, LAST_SEEN: string}, RHSM_API_RESPONSE_SLA_TYPES: {PREMIUM: string, - * SELF: string, NONE: string, STANDARD: string}, RHSM_API_RESPONSE_META_TYPES: {PRODUCT: string, COUNT: string}, - * RHSM_API_RESPONSE_ERRORS_CODE_TYPES: {GENERIC: string, OPTIN: string}, RHSM_API_QUERY_GRANULARITY_TYPES: {WEEKLY: string, + * RHSM_API_RESPONSE_INSTANCES_DATA_TYPES: {MEASUREMENTS: string, BILLING_ACCOUNT_ID: string, SUBSCRIPTION_MANAGER_ID: string, + * INVENTORY_ID: string, NUMBER_OF_GUESTS: string, BILLING_PROVIDER: string, DISPLAY_NAME: string, LAST_SEEN: string}, + * RHSM_API_RESPONSE_SLA_TYPES: {PREMIUM: string, SELF: string, NONE: string, STANDARD: string}, RHSM_API_RESPONSE_META_TYPES: {PRODUCT: string, + * COUNT: string}, RHSM_API_RESPONSE_ERRORS_CODE_TYPES: {GENERIC: string, OPTIN: string}, RHSM_API_QUERY_GRANULARITY_TYPES: {WEEKLY: string, * QUARTERLY: string, DAILY: string, MONTHLY: string}, RHSM_API_RESPONSE_UOM_TYPES: {CORES: string, SOCKETS: string}, - * RHSM_API_QUERY_INVENTORY_SORT_DIRECTION_TYPES: {ASCENDING: string, DESCENDING: string}, - * RHSM_API_QUERY_INVENTORY_SORT_TYPES: {CORES: string, CORE_HOURS: string, HARDWARE: string, SOCKETS: string, - * MEASUREMENT: string, LAST_SEEN: string, NAME: string}, RHSM_API_PATH_PRODUCT_TYPES: {RHEL_ARM: string, - * OPENSHIFT_METRICS: string, SATELLITE: string, RHEL_WORKSTATION: string, RHOSAK: 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_RESPONSE_ERRORS_TYPES: {CODE: string}, + * RHSM_API_RESPONSE_SUBSCRIPTIONS_DATA_TYPES: {BILLING_ACCOUNT_ID: string, QUANTITY: string, SUBSCRIPTION_MANAGER_ID: string, + * INVENTORY_ID: string, NUMBER_OF_GUESTS: string, HAS_INFINITE_QUANTITY: string, TOTAL_CAPACITY: string, PRODUCT_NAME: string, + * SERVICE_LEVEL: string, DISPLAY_NAME: string, MEASUREMENTS: string, UOM: string, NEXT_EVENT_DATE: string, BILLING_PROVIDER: string, + * LAST_SEEN: string}, RHSM_API_QUERY_INVENTORY_SORT_DIRECTION_TYPES: {ASCENDING: string, DESCENDING: string}, + * RHSM_API_RESPONSE_SUBSCRIPTION_TYPES: {ANNUAL: string, ON_DEMAND: string}, RHSM_API_QUERY_INVENTORY_SORT_TYPES: {CORES: string, + * STORAGE_GIBIBYTES: string, SOCKETS: string, INSTANCE_HOURS: string, TRANSFER_GIBIBYTES: string, BILLING_PROVIDER: string, + * CORE_SECONDS: string, LAST_SEEN: string, NAME: string}, RHSM_API_PATH_PRODUCT_TYPES: {RHEL_ARM: string, OPENSHIFT_METRICS: string, + * SATELLITE: string, RHEL_WORKSTATION: string, RHOSAK: 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_RESPONSE_BILLING_PROVIDER_TYPES: {AZURE: string, GCP: string, + * RED_HAT: string, NONE: string, AWS: string, ORACLE: string}, RHSM_API_RESPONSE_ERRORS_TYPES: {CODE: string}, + * RHSM_API_QUERY_BILLING_PROVIDER_TYPES: {AZURE: string, GCP: string, RED_HAT: string, NONE: string, AWS: string, ORACLE: 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, END_DATE: string, + * RHSM_API_QUERY_SET_INVENTORY_TYPES: {UOM: string, BILLING_ACCOUNT_ID: string, USAGE: string, DIRECTION: string, SORT: string, + * END_DATE: string, OFFSET: string, SLA: string, LIMIT: string, START_DATE: string, BILLING_PROVIDER: string, DISPLAY_NAME: string}, + * RHSM_API_RESPONSE_ERRORS: string, RHSM_API_RESPONSE_TALLY_META_TYPES: {TOTAL_MONTHLY: string, DATE: string, PRODUCT: string, + * HAS_CLOUDIGRADE_DATA: string, HAS_CLOUDIGRADE_MISMATCH: string, HAS_DATA: string, METRIC_ID: string, COUNT: string, VALUE: string}, + * RHSM_API_QUERY_UOM_TYPES: {CORES: string, SOCKETS: string}, RHSM_API_RESPONSE_META: string, + * RHSM_API_RESPONSE_GRANULARITY_TYPES: {WEEKLY: string, QUARTERLY: string, DAILY: string, MONTHLY: string}, + * RHSM_API_QUERY_SET_TYPES: {UOM: string, GRANULARITY: string, USAGE: string, DIRECTION: string, SORT: string, END_DATE: string, * OFFSET: string, SLA: string, LIMIT: string, START_DATE: string, DISPLAY_NAME: string}, - * RHSM_API_RESPONSE_ERRORS: string, RHSM_API_RESPONSE_TALLY_META_TYPES: {TOTAL_MONTHLY: string, DATE: string, - * PRODUCT: string, HAS_CLOUDIGRADE_DATA: string, HAS_CLOUDIGRADE_MISMATCH: string, HAS_DATA: string, METRIC_ID: string, - * COUNT: string, VALUE: string}, RHSM_API_QUERY_UOM_TYPES: {CORES: string, SOCKETS: string}, - * RHSM_API_RESPONSE_META: string, RHSM_API_RESPONSE_GRANULARITY_TYPES: {WEEKLY: string, QUARTERLY: string, DAILY: string, - * MONTHLY: string}, RHSM_API_QUERY_SET_TYPES: {UOM: string, GRANULARITY: string, USAGE: string, DIRECTION: string, - * SORT: string, END_DATE: string, OFFSET: string, SLA: string, LIMIT: string, START_DATE: string, DISPLAY_NAME: string}, - * RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES: {QUANTITY: string, USAGE: string, NEXT_EVENT_TYPE: string, - * NEXT_EVENT_DATE: string, TOTAL_CAPACITY: string, PRODUCT_NAME: string, SKU: string, SERVICE_LEVEL: string}, - * RHSM_API_RESPONSE_USAGE_TYPES: {UNSPECIFIED: string, DISASTER: string, DEVELOPMENT: string, PRODUCTION: string}}} + * RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES: {QUANTITY: string, USAGE: string, NEXT_EVENT_TYPE: string, NEXT_EVENT_DATE: string, + * TOTAL_CAPACITY: string, PRODUCT_NAME: string, SKU: string, SERVICE_LEVEL: string}, RHSM_API_RESPONSE_USAGE_TYPES: {UNSPECIFIED: string, + * DISASTER: string, DEVELOPMENT: string, PRODUCTION: string}}} */ const rhsmConstants = { RHSM_API_PATH_PRODUCT_TYPES, @@ -335,16 +413,21 @@ const rhsmConstants = { RHSM_API_RESPONSE_ERRORS_CODE_TYPES, RHSM_API_RESPONSE_INSTANCES_DATA_TYPES, RHSM_API_RESPONSE_INSTANCES_META_TYPES, + RHSM_API_RESPONSE_SUBSCRIPTIONS_DATA_TYPES, + RHSM_API_RESPONSE_SUBSCRIPTIONS_META_TYPES, RHSM_API_RESPONSE_TALLY_DATA_TYPES, RHSM_API_RESPONSE_TALLY_META_TYPES, RHSM_API_RESPONSE_GRANULARITY_TYPES, + RHSM_API_RESPONSE_BILLING_PROVIDER_TYPES, RHSM_API_RESPONSE_SLA_TYPES, + RHSM_API_RESPONSE_SUBSCRIPTION_TYPES, RHSM_API_RESPONSE_UOM_TYPES, RHSM_API_RESPONSE_USAGE_TYPES, RHSM_API_QUERY_GRANULARITY_TYPES, RHSM_API_QUERY_INVENTORY_SORT_TYPES, RHSM_API_QUERY_INVENTORY_SORT_DIRECTION_TYPES, RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES, + RHSM_API_QUERY_BILLING_PROVIDER_TYPES, RHSM_API_QUERY_SLA_TYPES, RHSM_API_QUERY_UOM_TYPES, RHSM_API_QUERY_USAGE_TYPES, @@ -366,16 +449,21 @@ export { RHSM_API_RESPONSE_ERRORS_CODE_TYPES, RHSM_API_RESPONSE_INSTANCES_DATA_TYPES, RHSM_API_RESPONSE_INSTANCES_META_TYPES, + RHSM_API_RESPONSE_SUBSCRIPTIONS_DATA_TYPES, + RHSM_API_RESPONSE_SUBSCRIPTIONS_META_TYPES, RHSM_API_RESPONSE_TALLY_DATA_TYPES, RHSM_API_RESPONSE_TALLY_META_TYPES, RHSM_API_RESPONSE_GRANULARITY_TYPES, + RHSM_API_RESPONSE_BILLING_PROVIDER_TYPES, RHSM_API_RESPONSE_SLA_TYPES, + RHSM_API_RESPONSE_SUBSCRIPTION_TYPES, RHSM_API_RESPONSE_UOM_TYPES, RHSM_API_RESPONSE_USAGE_TYPES, RHSM_API_QUERY_GRANULARITY_TYPES, RHSM_API_QUERY_INVENTORY_SORT_TYPES, RHSM_API_QUERY_INVENTORY_SORT_DIRECTION_TYPES, RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES, + RHSM_API_QUERY_BILLING_PROVIDER_TYPES, RHSM_API_QUERY_SLA_TYPES, RHSM_API_QUERY_UOM_TYPES, RHSM_API_QUERY_USAGE_TYPES, diff --git a/src/services/rhsm/rhsmSchemas.js b/src/services/rhsm/rhsmSchemas.js index 5bbb20daf..e2fb72e79 100644 --- a/src/services/rhsm/rhsmSchemas.js +++ b/src/services/rhsm/rhsmSchemas.js @@ -97,6 +97,8 @@ const instancesMetaSchema = metaResponseSchema const instancesItem = Joi.object({ inventory_id: Joi.string().optional().allow(null), display_name: Joi.string().optional().allow(null), + billing_provider: Joi.string().optional().allow(null), + billing_account_id: Joi.string().optional().allow(null), measurements: Joi.array().default([]), subscription_manager_id: Joi.string().optional().allow(null), last_seen: Joi.date().utc().allow(null) @@ -120,7 +122,11 @@ const instancesResponseSchema = Joi.object().keys({ * * @type {*} Joi schema */ -const subscriptionsMetaSchema = metaResponseSchema; +const subscriptionsMetaSchema = metaResponseSchema + .keys({ + subscription_type: Joi.string().valid(null, ...Object.values(rhsmConstants.RHSM_API_RESPONSE_SUBSCRIPTION_TYPES)) + }) + .unknown(true); /** * Subscriptions response item. @@ -195,7 +201,7 @@ const rhsmSchemas = { guests: response => schemaResponse({ response, casing: 'camel', schema: guestsResponseSchema, id: 'RHSM guests' }), instances: response => schemaResponse({ response, schema: instancesResponseSchema, id: 'RHSM instances' }), subscriptions: response => - schemaResponse({ response, casing: 'camel', schema: subscriptionsResponseSchema, id: 'RHSM subscriptions' }), + schemaResponse({ response, schema: subscriptionsResponseSchema, id: 'RHSM subscriptions' }), tally: response => schemaResponse({ response, schema: tallyResponseSchema, id: 'RHSM tally' }) }; diff --git a/src/services/rhsm/rhsmServices.js b/src/services/rhsm/rhsmServices.js index ccec0ff23..98e992b97 100644 --- a/src/services/rhsm/rhsmServices.js +++ b/src/services/rhsm/rhsmServices.js @@ -1290,7 +1290,7 @@ const getGraphReports = (id, params = {}, options = {}) => { * "granularity": "daily", * "has_cloudigrade_data": true, * "has_cloudigrade_mismatch": true, - * "metric_id": "Storage-gibibytes", + * "metric_id": "Storage-gibibyte-months", * "product": "RHEL", * "service_level": "", * "total_monthly": { @@ -2183,6 +2183,8 @@ const getHostsInventoryGuests = (id, params = {}, options = {}) => { * "data" : [ * { * "number_of_guests": 70, + * "billing_provider": "red hat", + * "billing_account_id": "xxxxx-xxxx-xxxx-xxxx-xxxx01", * "inventory_id": "d6214a0b-b344-4778-831c-d53dcacb2da3", * "subscription_manager_id": "adafd9d5-5b00-42fa-a6c9-75801d45cc6d", * "display_name": "rhv.example.com", @@ -2194,6 +2196,8 @@ const getHostsInventoryGuests = (id, params = {}, options = {}) => { * "last_seen": "2020-04-01T00:00:00Z" * }, * { + * "billing_provider": "azure", + * "billing_account_id": "xxxxx-xxxx-xxxx-xxxx-xxxx02", * "inventory_id": "XXXXXX-b344-4778-831c-XXXXXXXX", * "subscription_manager_id": "XXXXXX-5b00-42fa-XXXX-75801d45cc6d", * "display_name": "dolor.example.com", @@ -2205,6 +2209,8 @@ const getHostsInventoryGuests = (id, params = {}, options = {}) => { * "last_seen": "2020-04-02T00:00:00Z" * }, * { + * "billing_provider": "Unknown", + * "billing_account_id": "xxxxx-xxxx-xxxx-xxxx-xxxx03", * "inventory_id": "BBBBB-b344-4778-831c-BBBBBBB", * "subscription_manager_id": "BBBBB-5b00-42fa-BBBBB-75801d45cc6d", * "display_name": "lorem.example.com", @@ -2221,7 +2227,7 @@ const getHostsInventoryGuests = (id, params = {}, options = {}) => { * "count": 3, * "measurements": [ * "Instance-hours", - * "Storage-gibibytes", + * "Storage-gibibyte-months", * "Transfer-gibibytes" * ], * "product": "RHEL", @@ -2342,7 +2348,8 @@ const getInstancesInventory = (id, params = {}, options = {}) => { * ], * "links": {}, * "meta": { - * "count": 3 + * "count": 3, + * "subscription_type": "On-demand" * } * } * diff --git a/src/services/rhsm/rhsmTransformers.js b/src/services/rhsm/rhsmTransformers.js index d703c41c7..f682a955d 100644 --- a/src/services/rhsm/rhsmTransformers.js +++ b/src/services/rhsm/rhsmTransformers.js @@ -62,23 +62,31 @@ const rhsmTally = response => { const updatedResponse = {}; const { [rhsmConstants.RHSM_API_RESPONSE_DATA]: data = [], [rhsmConstants.RHSM_API_RESPONSE_META]: meta = {} } = response || {}; - const currentDay = moment.utc(dateHelpers.getCurrentDate()).format('MM-D-YYYY'); + const currentDate = moment.utc(dateHelpers.getCurrentDate()).format('MM-D-YYYY'); updatedResponse.data = data.map( ( { [TALLY_DATA_TYPES.DATE]: date, [TALLY_DATA_TYPES.VALUE]: value, [TALLY_DATA_TYPES.HAS_DATA]: hasData }, index - ) => ({ - x: index, - y: value, - date, - hasData, - isCurrentDate: moment.utc(date).format('MM-D-YYYY') === currentDay - }) + ) => { + const updatedDate = moment.utc(date); + const isCurrentDate = updatedDate.format('MM-D-YYYY') === currentDate; + const isFutureDate = updatedDate.diff(currentDate) > 0; + + return { + x: index, + y: (hasData === false && isFutureDate) || (hasData === false && isCurrentDate) ? null : value, + date, + hasData, + isCurrentDate, + isFutureDate + }; + } ); updatedResponse.meta = { count: meta[TALLY_META_TYPES.COUNT], + cloudigradeHasMismatch: meta[TALLY_META_TYPES.HAS_CLOUDIGRADE_MISMATCH], metricId: meta[TALLY_META_TYPES.METRIC_ID], productId: meta[TALLY_META_TYPES.PRODUCT], totalMonthlyDate: meta[TALLY_META_TYPES.TOTAL_MONTHLY]?.[TALLY_META_TYPES.DATE], diff --git a/src/types/__tests__/__snapshots__/index.test.js.snap b/src/types/__tests__/__snapshots__/index.test.js.snap index 3661c1623..8efefdf80 100644 --- a/src/types/__tests__/__snapshots__/index.test.js.snap +++ b/src/types/__tests__/__snapshots__/index.test.js.snap @@ -29,6 +29,8 @@ Object { "WEEKLY": "Weekly", }, "RHSM_API_QUERY_SET_INVENTORY_GUESTS_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -41,6 +43,8 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_INVENTORY_SUBSCRIPTIONS_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -53,6 +57,8 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_INVENTORY_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -70,6 +76,7 @@ Object { "TALLY_SYNC": "enable_tally_sync", }, "RHSM_API_QUERY_SET_REPORT_CAPACITY_TYPES": Object { + "BILLING_PROVIDER": "billing_provider", "END_DATE": "ending", "GRANULARITY": "granularity", "SLA": "sla", @@ -96,17 +103,9 @@ Object { "NAME": "display_name", "SOCKETS": "sockets", }, - "RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES": Object { - "NEXT_EVENT_DATE": "next_event_date", - "NEXT_EVENT_TYPE": "next_event_type", - "PRODUCT_NAME": "product_name", - "QUANTITY": "quantity", - "SERVICE_LEVEL": "service_level", - "SKU": "sku", - "TOTAL_CAPACITY": "total_capacity", - "USAGE": "usage", - }, "RHSM_API_QUERY_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "CONDUIT_SYNC": "enable_conduit_sync", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", @@ -236,6 +235,8 @@ Object { "WEEKLY": "Weekly", }, "RHSM_API_QUERY_SET_INVENTORY_GUESTS_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -248,6 +249,8 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_INVENTORY_SUBSCRIPTIONS_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -260,6 +263,8 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_INVENTORY_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -277,6 +282,7 @@ Object { "TALLY_SYNC": "enable_tally_sync", }, "RHSM_API_QUERY_SET_REPORT_CAPACITY_TYPES": Object { + "BILLING_PROVIDER": "billing_provider", "END_DATE": "ending", "GRANULARITY": "granularity", "SLA": "sla", @@ -303,17 +309,9 @@ Object { "NAME": "display_name", "SOCKETS": "sockets", }, - "RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES": Object { - "NEXT_EVENT_DATE": "next_event_date", - "NEXT_EVENT_TYPE": "next_event_type", - "PRODUCT_NAME": "product_name", - "QUANTITY": "quantity", - "SERVICE_LEVEL": "service_level", - "SKU": "sku", - "TOTAL_CAPACITY": "total_capacity", - "USAGE": "usage", - }, "RHSM_API_QUERY_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "CONDUIT_SYNC": "enable_conduit_sync", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", @@ -442,6 +440,8 @@ Object { "WEEKLY": "Weekly", }, "RHSM_API_QUERY_SET_INVENTORY_GUESTS_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -454,6 +454,8 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_INVENTORY_SUBSCRIPTIONS_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -466,6 +468,8 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_INVENTORY_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -483,6 +487,7 @@ Object { "TALLY_SYNC": "enable_tally_sync", }, "RHSM_API_QUERY_SET_REPORT_CAPACITY_TYPES": Object { + "BILLING_PROVIDER": "billing_provider", "END_DATE": "ending", "GRANULARITY": "granularity", "SLA": "sla", @@ -509,17 +514,9 @@ Object { "NAME": "display_name", "SOCKETS": "sockets", }, - "RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES": Object { - "NEXT_EVENT_DATE": "next_event_date", - "NEXT_EVENT_TYPE": "next_event_type", - "PRODUCT_NAME": "product_name", - "QUANTITY": "quantity", - "SERVICE_LEVEL": "service_level", - "SKU": "sku", - "TOTAL_CAPACITY": "total_capacity", - "USAGE": "usage", - }, "RHSM_API_QUERY_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "CONDUIT_SYNC": "enable_conduit_sync", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", @@ -652,6 +649,8 @@ Object { "WEEKLY": "Weekly", }, "RHSM_API_QUERY_SET_INVENTORY_GUESTS_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -664,6 +663,8 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_INVENTORY_SUBSCRIPTIONS_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -676,6 +677,8 @@ Object { "USAGE": "usage", }, "RHSM_API_QUERY_SET_INVENTORY_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", "END_DATE": "ending", @@ -693,6 +696,7 @@ Object { "TALLY_SYNC": "enable_tally_sync", }, "RHSM_API_QUERY_SET_REPORT_CAPACITY_TYPES": Object { + "BILLING_PROVIDER": "billing_provider", "END_DATE": "ending", "GRANULARITY": "granularity", "SLA": "sla", @@ -719,17 +723,9 @@ Object { "NAME": "display_name", "SOCKETS": "sockets", }, - "RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES": Object { - "NEXT_EVENT_DATE": "next_event_date", - "NEXT_EVENT_TYPE": "next_event_type", - "PRODUCT_NAME": "product_name", - "QUANTITY": "quantity", - "SERVICE_LEVEL": "service_level", - "SKU": "sku", - "TOTAL_CAPACITY": "total_capacity", - "USAGE": "usage", - }, "RHSM_API_QUERY_TYPES": Object { + "BILLING_ACCOUNT_ID": "billing_account_id", + "BILLING_PROVIDER": "billing_provider", "CONDUIT_SYNC": "enable_conduit_sync", "DIRECTION": "dir", "DISPLAY_NAME": "display_name_contains", diff --git a/src/types/rhsmApiTypes.js b/src/types/rhsmApiTypes.js index 4de286692..e5e0e5f73 100644 --- a/src/types/rhsmApiTypes.js +++ b/src/types/rhsmApiTypes.js @@ -251,16 +251,6 @@ const RHSM_API_QUERY_SORT_TYPES = { SOCKETS: 'sockets' }; -/** - * RHSM API query/search parameter SORT type values for SUBSCRIPTIONS. - * - * @type {{QUANTITY: string, USAGE: string, NEXT_EVENT_TYPE: string, NEXT_EVENT_DATE: string, SKU: string, - * SERVICE_LEVEL: string}} - */ -const RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES = { - ...rhsmConstants.RHSM_API_QUERY_INVENTORY_SUBSCRIPTIONS_SORT_TYPES -}; - /** * RHSM API query/search parameter SORT DIRECTION type values. * @@ -368,22 +358,19 @@ 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_DATA: 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, + * SLA: string, LIMIT: string}, RHSM_API_RESPONSE_DATA: 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: {QUANTITY: string, USAGE: string, NEXT_EVENT_TYPE: string, NEXT_EVENT_DATE: string, - * SKU: string, SERVICE_LEVEL: string}, RHSM_API_RESPONSE_META_TYPES: {COUNT: string, TOTAL_INSTANCE_HOURS: 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, RHOSAK: 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_RESPONSE_META_TYPES: {COUNT: string, TOTAL_INSTANCE_HOURS: 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, RHOSAK: 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}, @@ -392,14 +379,12 @@ const RHSM_API_QUERY_TYPES = { * MEASUREMENT: string, LAST_SEEN: string, NAME: string}, RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES: {HYPERVISOR_SOCKETS: string, * CORES: string, INSTANCE_HOURS: 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, SUBSCRIPTION_ID: string, INVENTORY_ID: string, MEASUREMENT: string, - * ID: string, GUESTS: string, CLOUD_PROVIDER: string, LAST_SEEN: string, NAME: string}, - * RHSM_API_QUERY_SET_REPORT_CAPACITY_TYPES: {GRANULARITY: string, USAGE: string, END_DATE: string, SLA: string, - * START_DATE: 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, SUBSCRIPTION_ID: string, + * INVENTORY_ID: string, MEASUREMENT: string, ID: string, GUESTS: string, CLOUD_PROVIDER: string, LAST_SEEN: string, NAME: string}, + * RHSM_API_QUERY_SET_REPORT_CAPACITY_TYPES: {GRANULARITY: string, USAGE: string, END_DATE: string, SLA: string, START_DATE: string}}} */ const rhsmApiTypes = { RHSM_API_RESPONSE_ERROR_DATA, @@ -420,7 +405,6 @@ const rhsmApiTypes = { RHSM_API_PATH_ID_TYPES, RHSM_API_QUERY_GRANULARITY_TYPES, RHSM_API_QUERY_SORT_TYPES, - RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES, RHSM_API_QUERY_SORT_DIRECTION_TYPES, RHSM_API_QUERY_SLA_TYPES, RHSM_API_QUERY_UOM_TYPES, @@ -454,7 +438,6 @@ export { RHSM_API_PATH_ID_TYPES, RHSM_API_QUERY_GRANULARITY_TYPES, RHSM_API_QUERY_SORT_TYPES, - RHSM_API_QUERY_SUBSCRIPTIONS_SORT_TYPES, RHSM_API_QUERY_SORT_DIRECTION_TYPES, RHSM_API_QUERY_SLA_TYPES, RHSM_API_QUERY_UOM_TYPES, diff --git a/tests/__snapshots__/code.test.js.snap b/tests/__snapshots__/code.test.js.snap index c882fa249..1ac69ae64 100644 --- a/tests/__snapshots__/code.test.js.snap +++ b/tests/__snapshots__/code.test.js.snap @@ -3,7 +3,7 @@ exports[`General code checks should only have specific console.[warn|log|info|error] methods: console methods 1`] = ` Array [ "components/inventoryCard/inventoryCardContext.js:127: console.warn(\`Sorting can only be performed on select fields, confirm field \${id} is allowed.\`);", - "components/inventoryCard/inventoryCardHelpers.js:67: console.warn(\`Warning: Filter \\"\${id}\\" not found in \\"table row\\" response data.\`, cellData);", + "components/inventoryCard/inventoryCardHelpers.js:83: console.warn(\`Warning: Filter \\"\${id}\\" not found in \\"table row\\" response data.\`, cellData);", "components/inventoryCard/inventoryList.deprecated.js:62: console.warn(\`Sorting can only be performed on select fields, confirm field \${id} is allowed.\`);", "components/inventoryCardSubscriptions/inventoryCardSubscriptionsContext.js:127: console.warn(\`Sorting can only be performed on select fields, confirm field \${id} is allowed.\`);", "redux/common/reduxHelpers.js:282: console.error(\`Error: Property \${prop} does not exist within the passed state.\`, state);", diff --git a/tests/__snapshots__/dist.test.js.snap b/tests/__snapshots__/dist.test.js.snap index 0c4673cfc..440152665 100644 --- a/tests/__snapshots__/dist.test.js.snap +++ b/tests/__snapshots__/dist.test.js.snap @@ -5,38 +5,43 @@ Array [ "", "./dist/css/1064*css", "./dist/css/2085*css", - "./dist/css/2130*css", + "./dist/css/2251*css", "./dist/css/2331*css", - "./dist/css/4486*css", + "./dist/css/265*css", + "./dist/css/3769*css", "./dist/css/6402*css", - "./dist/css/7191*css", "./dist/css/8485*css", "./dist/css/8731*css", - "./dist/css/9373*css", + "./dist/css/90*css", "./dist/fed-mods.json", "./dist/fonts/graph2x.png", "./dist/fonts/graph4x.png", - "./dist/index.html", - "./dist/js/1014*js", "./dist/js/1026*js", "./dist/js/1064*js", "./dist/js/1233*js", "./dist/js/1339*js", "./dist/js/1355*js", "./dist/js/136*js", + "./dist/js/1663*js", "./dist/js/1799*js", + "./dist/js/1806*js", + "./dist/js/1824*js", "./dist/js/1858*js", "./dist/js/190*js", - "./dist/js/2130*js", "./dist/js/2195*js", "./dist/js/2243*js", + "./dist/js/2251*js", "./dist/js/2293*js", + "./dist/js/265*js", "./dist/js/2738*js", "./dist/js/2881*js", "./dist/js/2896*js", "./dist/js/2902*js", "./dist/js/31*js", "./dist/js/3267*js", + "./dist/js/353*js", + "./dist/js/3552*js", + "./dist/js/3769*js", "./dist/js/384*js", "./dist/js/4024*js", "./dist/js/4044*js", @@ -46,30 +51,26 @@ Array [ "./dist/js/4155*js", "./dist/js/4314*js", "./dist/js/4418*js", - "./dist/js/4486*js", "./dist/js/5020*js", "./dist/js/5068*js", "./dist/js/5242*js", "./dist/js/5394*js", "./dist/js/5473*js", "./dist/js/5876*js", + "./dist/js/6000*js", "./dist/js/608*js", "./dist/js/6395*js", "./dist/js/6402*js", "./dist/js/6816*js", - "./dist/js/6873*js", - "./dist/js/7191*js", "./dist/js/7235*js", - "./dist/js/7471*js", "./dist/js/7535*js", "./dist/js/7585*js", - "./dist/js/7891*js", + "./dist/js/7780*js", "./dist/js/8139*js", "./dist/js/8191*js", "./dist/js/8213*js", "./dist/js/8216*js", "./dist/js/8216*txt", - "./dist/js/8232*js", "./dist/js/8255*js", "./dist/js/8326*js", "./dist/js/8341*js", @@ -81,47 +82,53 @@ Array [ "./dist/js/8766*js", "./dist/js/8766*txt", "./dist/js/8900*js", + "./dist/js/90*js", "./dist/js/9051*js", "./dist/js/9175*js", "./dist/js/9270*js", - "./dist/js/9297*js", "./dist/js/930*js", "./dist/js/931*js", - "./dist/js/9373*js", "./dist/js/939*js", + "./dist/js/9407*js", "./dist/js/9517*js", "./dist/js/9669*js", "./dist/js/9709*js", + "./dist/js/9833*js", "./dist/js/9844*js", "./dist/js/9877*js", "./dist/js/9928*js", - "./dist/js/9942*js", "./dist/js/998*js", "./dist/js/App*js", "./dist/js/App*txt", "./dist/locales/en-US.json", "./dist/locales/en.json", "./dist/locales/locales.json", - "./dist/sourcemaps/1014*map", "./dist/sourcemaps/1026*map", "./dist/sourcemaps/1064*map", "./dist/sourcemaps/1233*map", "./dist/sourcemaps/1339*map", "./dist/sourcemaps/1355*map", "./dist/sourcemaps/136*map", + "./dist/sourcemaps/1663*map", "./dist/sourcemaps/1799*map", + "./dist/sourcemaps/1806*map", + "./dist/sourcemaps/1824*map", "./dist/sourcemaps/1858*map", "./dist/sourcemaps/190*map", - "./dist/sourcemaps/2130*map", "./dist/sourcemaps/2195*map", "./dist/sourcemaps/2243*map", + "./dist/sourcemaps/2251*map", "./dist/sourcemaps/2293*map", + "./dist/sourcemaps/265*map", "./dist/sourcemaps/2738*map", "./dist/sourcemaps/2881*map", "./dist/sourcemaps/2896*map", "./dist/sourcemaps/2902*map", "./dist/sourcemaps/31*map", "./dist/sourcemaps/3267*map", + "./dist/sourcemaps/353*map", + "./dist/sourcemaps/3552*map", + "./dist/sourcemaps/3769*map", "./dist/sourcemaps/384*map", "./dist/sourcemaps/4024*map", "./dist/sourcemaps/4044*map", @@ -131,29 +138,25 @@ Array [ "./dist/sourcemaps/4155*map", "./dist/sourcemaps/4314*map", "./dist/sourcemaps/4418*map", - "./dist/sourcemaps/4486*map", "./dist/sourcemaps/5020*map", "./dist/sourcemaps/5068*map", "./dist/sourcemaps/5242*map", "./dist/sourcemaps/5394*map", "./dist/sourcemaps/5473*map", "./dist/sourcemaps/5876*map", + "./dist/sourcemaps/6000*map", "./dist/sourcemaps/608*map", "./dist/sourcemaps/6395*map", "./dist/sourcemaps/6402*map", "./dist/sourcemaps/6816*map", - "./dist/sourcemaps/6873*map", - "./dist/sourcemaps/7191*map", "./dist/sourcemaps/7235*map", - "./dist/sourcemaps/7471*map", "./dist/sourcemaps/7535*map", "./dist/sourcemaps/7585*map", - "./dist/sourcemaps/7891*map", + "./dist/sourcemaps/7780*map", "./dist/sourcemaps/8139*map", "./dist/sourcemaps/8191*map", "./dist/sourcemaps/8213*map", "./dist/sourcemaps/8216*map", - "./dist/sourcemaps/8232*map", "./dist/sourcemaps/8255*map", "./dist/sourcemaps/8326*map", "./dist/sourcemaps/8341*map", @@ -164,21 +167,21 @@ Array [ "./dist/sourcemaps/8731*map", "./dist/sourcemaps/8766*map", "./dist/sourcemaps/8900*map", + "./dist/sourcemaps/90*map", "./dist/sourcemaps/9051*map", "./dist/sourcemaps/9175*map", "./dist/sourcemaps/9270*map", - "./dist/sourcemaps/9297*map", "./dist/sourcemaps/930*map", "./dist/sourcemaps/931*map", - "./dist/sourcemaps/9373*map", "./dist/sourcemaps/939*map", + "./dist/sourcemaps/9407*map", "./dist/sourcemaps/9517*map", "./dist/sourcemaps/9669*map", "./dist/sourcemaps/9709*map", + "./dist/sourcemaps/9833*map", "./dist/sourcemaps/9844*map", "./dist/sourcemaps/9877*map", "./dist/sourcemaps/9928*map", - "./dist/sourcemaps/9942*map", "./dist/sourcemaps/998*map", "./dist/sourcemaps/App*map", "./dist/subscriptions*js", diff --git a/tests/__snapshots__/html.test.js.snap b/tests/__snapshots__/html.test.js.snap index 088910f37..bf29b0890 100644 --- a/tests/__snapshots__/html.test.js.snap +++ b/tests/__snapshots__/html.test.js.snap @@ -1,17 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Index.HTML should have a specific html output: html output 1`] = ` -" - - - - -Subscriptions - - - - - - -" -`; +exports[`Index.HTML should have a specific html output: html output 1`] = `""`; diff --git a/tests/html.test.js b/tests/html.test.js index ae7a055e2..ce5ec2d7a 100644 --- a/tests/html.test.js +++ b/tests/html.test.js @@ -11,7 +11,7 @@ describe('Index.HTML', () => { .replace(/"([/a-z0-9]*)\/apps\//gi, '"*/apps/') .replace(/\/([a-z0-9]+)\.([a-z0-9]+)\.chunk.css"/gi, '/*.chunk.css"') .replace(/\/([a-z0-9]+)\.([a-z0-9]+)\.chunk.js"/gi, '/*.chunk.js"') - .replace(/\/([a-z]+)\.([a-z0-9]+)\.js"/gi, '/$1.*.js"') + .replace(/\/([a-z-]+)\.([a-z0-9]+)\.js"/gi, '/$1.*.js"') .replace(/'); expect(replacedFile).toMatchSnapshot('html output'); diff --git a/yarn.lock b/yarn.lock index 15633fc26..a90e06415 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21,30 +21,30 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.0.tgz#86850b8597ea6962089770952075dcaabb8dba34" integrity sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng== -"@babel/compat-data@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" - integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== +"@babel/compat-data@^7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.10.tgz#711dc726a492dfc8be8220028b1b92482362baab" + integrity sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw== -"@babel/core@7.17.8": - version "7.17.8" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.8.tgz#3dac27c190ebc3a4381110d46c80e77efe172e1a" - integrity sha512-OdQDV/7cRBtJHLSOBqqbYNkOcydOgnX59TZx4puf41fzcVtN3e/4yqY8lMQsK+5X2lJtAdmA+6OHqsj1hBJ4IQ== +"@babel/core@7.17.10", "@babel/core@^7.11.6": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.10.tgz#74ef0fbf56b7dfc3f198fc2d927f4f03e12f4b05" + integrity sha512-liKoppandF3ZcBnIYFjfSDHZLKdLHGJRkoWtG8zQyGJBQfIYobpnVGI5+pLBNtS6psFLDzyq8+h5HiVljW9PNA== dependencies: "@ampproject/remapping" "^2.1.0" "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.17.7" - "@babel/helper-compilation-targets" "^7.17.7" + "@babel/generator" "^7.17.10" + "@babel/helper-compilation-targets" "^7.17.10" "@babel/helper-module-transforms" "^7.17.7" - "@babel/helpers" "^7.17.8" - "@babel/parser" "^7.17.8" + "@babel/helpers" "^7.17.9" + "@babel/parser" "^7.17.10" "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.3" - "@babel/types" "^7.17.0" + "@babel/traverse" "^7.17.10" + "@babel/types" "^7.17.10" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" - json5 "^2.1.2" + json5 "^2.2.1" semver "^6.3.0" "@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.16.0", "@babel/core@^7.7.2", "@babel/core@^7.8.0": @@ -77,6 +77,15 @@ eslint-visitor-keys "^2.1.0" semver "^6.3.0" +"@babel/generator@^7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.10.tgz#c281fa35b0c349bbe9d02916f4ae08fc85ed7189" + integrity sha512-46MJZZo9y3o4kmhBVc7zW7i8dtR1oIK/sdO5NcfcZRhTGYi+KKJRtHNgsU6c4VUcJmUNV/LQdebD/9Dlv4K+Tg== + dependencies: + "@babel/types" "^7.17.10" + "@jridgewell/gen-mapping" "^0.1.0" + jsesc "^2.5.1" + "@babel/generator@^7.17.3", "@babel/generator@^7.7.2": version "7.17.3" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.3.tgz#a2c30b0c4f89858cb87050c3ffdfd36bdf443200" @@ -86,15 +95,6 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.7.tgz#8da2599beb4a86194a3b24df6c085931d9ee45ad" - integrity sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w== - dependencies: - "@babel/types" "^7.17.0" - jsesc "^2.5.1" - source-map "^0.5.0" - "@babel/helper-annotate-as-pure@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" @@ -120,14 +120,14 @@ browserslist "^4.17.5" semver "^6.3.0" -"@babel/helper-compilation-targets@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46" - integrity sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w== +"@babel/helper-compilation-targets@^7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.10.tgz#09c63106d47af93cf31803db6bc49fef354e2ebe" + integrity sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ== dependencies: - "@babel/compat-data" "^7.17.7" + "@babel/compat-data" "^7.17.10" "@babel/helper-validator-option" "^7.16.7" - browserslist "^4.17.5" + browserslist "^4.20.2" semver "^6.3.0" "@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7", "@babel/helper-create-class-features-plugin@^7.17.1": @@ -188,6 +188,14 @@ "@babel/template" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helper-function-name@^7.17.9": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz#136fcd54bc1da82fcb47565cf16fd8e444b1ff12" + integrity sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg== + dependencies: + "@babel/template" "^7.16.7" + "@babel/types" "^7.17.0" + "@babel/helper-get-function-arity@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" @@ -333,13 +341,13 @@ "@babel/traverse" "^7.17.0" "@babel/types" "^7.17.0" -"@babel/helpers@^7.17.8": - version "7.17.8" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.8.tgz#288450be8c6ac7e4e44df37bcc53d345e07bc106" - integrity sha512-QcL86FGxpfSJwGtAvv4iG93UL6bmqBdmoVY0CMCU2g+oD2ezQse3PT5Pa+jiD6LJndBQi0EDlpzOWNlLuhz5gw== +"@babel/helpers@^7.17.9": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.9.tgz#b2af120821bfbe44f9907b1826e168e819375a1a" + integrity sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q== dependencies: "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.3" + "@babel/traverse" "^7.17.9" "@babel/types" "^7.17.0" "@babel/highlight@^7.16.7": @@ -356,10 +364,10 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.3.tgz#b07702b982990bf6fdc1da5049a23fece4c5c3d0" integrity sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA== -"@babel/parser@^7.17.8": - version "7.17.8" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.8.tgz#2817fb9d885dd8132ea0f8eb615a6388cca1c240" - integrity sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ== +"@babel/parser@^7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.10.tgz#873b16db82a8909e0fbd7f115772f4b739f6ce78" + integrity sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": version "7.16.7" @@ -1127,6 +1135,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.17.10", "@babel/traverse@^7.17.9": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.10.tgz#1ee1a5ac39f4eac844e6cf855b35520e5eb6f8b5" + integrity sha512-VmbrTHQteIdUUQNTb+zE12SHS/xQVIShmBPhlNP12hD5poF2pbITW1Z4172d03HegaQWhLffdkRJYtAzp0AGcw== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.10" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.17.9" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.17.10" + "@babel/types" "^7.17.10" + debug "^4.1.0" + globals "^11.1.0" + "@babel/types@^7.0.0", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.17.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" @@ -1135,6 +1159,14 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" +"@babel/types@^7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.10.tgz#d35d7b4467e439fcf06d195f8100e0fea7fc82c4" + integrity sha512-9O26jG0mBYfGkUYCYZRnBwbVLd1UZOICEr2Em6InB6jVfsAv1GKgwXHmrSg+WFWDmeKTA6vyTZiN8tCSM5Oo3A== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -1145,16 +1177,16 @@ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== -"@cspell/cspell-bundled-dicts@^5.19.3": - version "5.19.3" - resolved "https://registry.yarnpkg.com/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-5.19.3.tgz#826e166eb56f193c2d770575adfbb1557816f1af" - integrity sha512-YAz68AgXTFFtrBUhNJlOQ7KOjUE6ncYt578/esa2GStMJHgJoUtPnOZsE41hh+cVWXqO5yRRI+Qkwub99zLMgQ== +"@cspell/cspell-bundled-dicts@^5.20.0": + version "5.20.0" + resolved "https://registry.yarnpkg.com/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-5.20.0.tgz#294106a2660baf825494535019a0d2230c3cc0c1" + integrity sha512-tCO32xVSuey4Tg8XuayBzcrCAfrAXL8J1PeYl26+/ZUl5zkAL4AuyL0Cf4e2PpeEomnUWP2y5noZLLbUeOIwnw== dependencies: "@cspell/dict-ada" "^2.0.0" "@cspell/dict-aws" "^2.0.0" - "@cspell/dict-bash" "^2.0.1" - "@cspell/dict-companies" "^2.0.3" - "@cspell/dict-cpp" "^2.0.0" + "@cspell/dict-bash" "^2.0.2" + "@cspell/dict-companies" "^2.0.4" + "@cspell/dict-cpp" "^2.0.3" "@cspell/dict-cryptocurrencies" "^2.0.0" "@cspell/dict-csharp" "^2.0.1" "@cspell/dict-css" "^2.0.0" @@ -1163,10 +1195,11 @@ "@cspell/dict-dotnet" "^2.0.1" "@cspell/dict-elixir" "^2.0.1" "@cspell/dict-en-gb" "^1.1.33" - "@cspell/dict-en_us" "^2.2.0" + "@cspell/dict-en_us" "^2.2.2" "@cspell/dict-filetypes" "^2.0.1" "@cspell/dict-fonts" "^2.0.0" - "@cspell/dict-fullstack" "^2.0.4" + "@cspell/dict-fullstack" "^2.0.5" + "@cspell/dict-git" "^1.0.1" "@cspell/dict-golang" "^2.0.0" "@cspell/dict-haskell" "^2.0.0" "@cspell/dict-html" "^3.0.1" @@ -1175,30 +1208,30 @@ "@cspell/dict-latex" "^2.0.0" "@cspell/dict-lorem-ipsum" "^2.0.0" "@cspell/dict-lua" "^2.0.0" - "@cspell/dict-node" "^2.0.0" - "@cspell/dict-npm" "^2.0.2" + "@cspell/dict-node" "^2.0.1" + "@cspell/dict-npm" "^2.0.3" "@cspell/dict-php" "^2.0.0" "@cspell/dict-powershell" "^2.0.0" "@cspell/dict-public-licenses" "^1.0.4" - "@cspell/dict-python" "^2.0.6" + "@cspell/dict-python" "^3.0.3" "@cspell/dict-r" "^1.0.2" "@cspell/dict-ruby" "^2.0.1" "@cspell/dict-rust" "^2.0.0" "@cspell/dict-scala" "^2.0.0" - "@cspell/dict-software-terms" "^2.1.4" + "@cspell/dict-software-terms" "^2.1.5" "@cspell/dict-swift" "^1.0.2" "@cspell/dict-typescript" "^2.0.0" "@cspell/dict-vue" "^2.0.2" -"@cspell/cspell-pipe@^5.19.3": - version "5.19.3" - resolved "https://registry.yarnpkg.com/@cspell/cspell-pipe/-/cspell-pipe-5.19.3.tgz#af818c0362786f61ac8741947e1819f94b55ec3b" - integrity sha512-3RKntgGRxYYzoxoH3VBPvnNMYkHKPq0U+U7qogcWxDkgAUgKXlBP0oc2mw96grJQ4HIzOL1vBnaVAWAqteY9Kw== +"@cspell/cspell-pipe@^5.20.0": + version "5.20.0" + resolved "https://registry.yarnpkg.com/@cspell/cspell-pipe/-/cspell-pipe-5.20.0.tgz#964aa560c89ecdf4eea9145700ccd6ab4c235ed8" + integrity sha512-dGHf4XZgPlGqviYTD+5ZwSk3hpiywsuuDqnoPo9SeQ1xPon7uFVKsMiAAzvhGAkkBaKIBNP/nwPU0feYvLoCJg== -"@cspell/cspell-types@^5.19.3": - version "5.19.3" - resolved "https://registry.yarnpkg.com/@cspell/cspell-types/-/cspell-types-5.19.3.tgz#37a64db00e33a1c8bb8aa3bf86d503689b3afbf5" - integrity sha512-tub7PW/I6qB6o+ZtlahAZjm5O5cnzj88HRiC8nAbJFpa7q0mrdpFMYhd7ksWtyFLlNbuDkCsfzXGamAhIQnnIw== +"@cspell/cspell-types@^5.20.0": + version "5.20.0" + resolved "https://registry.yarnpkg.com/@cspell/cspell-types/-/cspell-types-5.20.0.tgz#4c9a47249e1ad534938f2f35fbba1221e7800570" + integrity sha512-p06/HAKgalqyGHfnowJvjO3SQHxuOzKdiJTUlUi8x1CrEk7PmZEHuORlt9tVVZ46Xf2qY9+QLeTtattlWPJ39A== "@cspell/dict-ada@^2.0.0": version "2.0.0" @@ -1210,20 +1243,20 @@ resolved "https://registry.yarnpkg.com/@cspell/dict-aws/-/dict-aws-2.0.0.tgz#9af72af4e59e96029dd4335271d87784843cb7dd" integrity sha512-NKz7pDZ7pwj/b33i3f4WLpC1rOOUMmENwYgftxU+giU2YBeKM2wZbMTSEIzsrel56r0UlQYmdIVlP/B4nnVaoQ== -"@cspell/dict-bash@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@cspell/dict-bash/-/dict-bash-2.0.1.tgz#76f6be974e9a968235d4e1b04c4ae76b16169057" - integrity sha512-pBx3T/5w7fPF8XD5cx3NwtRFvNpQYmYqzM043NKP2hDmlx4uFwbH599Lvt5mwCMZKfIoRXaNUQvq7se2gstQjw== +"@cspell/dict-bash@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@cspell/dict-bash/-/dict-bash-2.0.2.tgz#8bc3e0a6c1b9c0df1bd9a1b7694c58d9843fd16b" + integrity sha512-ASIgI/LmV2TYrD4mtk+gm4XmUSTRomOyRt7NDWyBpEww/AeawC2O2NH6FosyUT6dUU3GaXt2wgJRN7R78n1SGg== -"@cspell/dict-companies@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@cspell/dict-companies/-/dict-companies-2.0.3.tgz#9e0f93a2cc884ff0b98d019123d1dbfb853da872" - integrity sha512-O622rMAaHm85AmqNyMki5je8HB/1XlTKbGOXh2UUhooI5qdgdfrjTQ6VBuHwHrfEfuODBHYTNYXVB2m23XqHCg== +"@cspell/dict-companies@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@cspell/dict-companies/-/dict-companies-2.0.4.tgz#2ba11418478d99d67a96004ea782a47a42c501a3" + integrity sha512-nLNVddo+iu4q/Mu03nkVTMnSPxBkoLyZ0MgpHJZWCqxVATbBkzoZNNNjsTkJhvkbrUIWydf8YW4U4wYY+kyh7Q== -"@cspell/dict-cpp@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@cspell/dict-cpp/-/dict-cpp-2.0.0.tgz#d5f04b693d96d41d67050cfe3ca0d342e141347b" - integrity sha512-EflHLs2pHEEXZM6jPfTGR/KHZKQtJlvzqgkg1zaA1YKv5HQNw9Wy5KVPGEV2bjPcFsZJO3xXjO1KBZcoOPjPmA== +"@cspell/dict-cpp@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@cspell/dict-cpp/-/dict-cpp-2.0.3.tgz#551bec166c4520f7ba36f8d263fb885d19f98db0" + integrity sha512-aWRvI3CQW2M3XeJpDVffItw/9n4hxsN5EPwyBa6Po6EnCxZZZLOqpieZk4JNz4pH0/xbnOX+sMMuSeKWr71r/w== "@cspell/dict-cryptocurrencies@^2.0.0": version "2.0.0" @@ -1265,10 +1298,10 @@ resolved "https://registry.yarnpkg.com/@cspell/dict-en-gb/-/dict-en-gb-1.1.33.tgz#7f1fd90fc364a5cb77111b5438fc9fcf9cc6da0e" integrity sha512-tKSSUf9BJEV+GJQAYGw5e+ouhEe2ZXE620S7BLKe3ZmpnjlNG9JqlnaBhkIMxKnNFkLY2BP/EARzw31AZnOv4g== -"@cspell/dict-en_us@^2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@cspell/dict-en_us/-/dict-en_us-2.2.0.tgz#33ee50fac4c42036ce98b9c9925cc86b16b0f2c3" - integrity sha512-IJWu8MI2NdLyPzekrMi9K+v71b0qjDE+z/BccoMA/APnphqgSNM8BDUAzhio6mPKi1AvPRCNUjk79oiUfp+1Gw== +"@cspell/dict-en_us@^2.2.2": + version "2.2.2" + resolved "https://registry.yarnpkg.com/@cspell/dict-en_us/-/dict-en_us-2.2.2.tgz#0106063ef390dcd3fb1e69113f402735164b75d4" + integrity sha512-iFiz1DXJUlU/sFqGPc58790RoCFf7xVr5OxCUVy5cvGHvm5o5Cx1AZ4Gj9ugPJYUXfJjLcfsUJDhL2SkD5tV0g== "@cspell/dict-filetypes@^2.0.1": version "2.0.1" @@ -1280,10 +1313,15 @@ resolved "https://registry.yarnpkg.com/@cspell/dict-fonts/-/dict-fonts-2.0.0.tgz#76e7781b44cdda6933144e15cba80e978c29bd15" integrity sha512-AgkTalphfDPtKFPYmEExDcj8rRCh86xlOSXco8tehOEkYVYbksOk9XH0YVH34RFpy93YBd2nnVGLgyGVwagcPw== -"@cspell/dict-fullstack@^2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@cspell/dict-fullstack/-/dict-fullstack-2.0.4.tgz#d7d1c80863d9fd9bda51346edcc5a72de2cf81b4" - integrity sha512-+JtYO58QAXnetRN+MGVzI8YbkbFTLpYfl/Cw/tmNqy7U1IDVC4sTXQ2pZvbbeKQWFHBqYvBs0YASV+mTouXYBw== +"@cspell/dict-fullstack@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@cspell/dict-fullstack/-/dict-fullstack-2.0.5.tgz#ffe416f90b0b30f1586e75432c0bc09b4c1faf96" + integrity sha512-jnLnHZ4HcCFNUfN+q7m0CUDtISNKat0Jahe1GgnAdEwzcozqKBhlGAjV7mQWPtKpqfJU61JakDnrxzqefAfZHw== + +"@cspell/dict-git@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@cspell/dict-git/-/dict-git-1.0.1.tgz#9de5ab2532abcdc8b10bd83ccb1f5e5dae0b6067" + integrity sha512-Rk+eTof/9inF11lvxmkCRK+gODatA3qai8kSASv6OG/JfPvpj7fTHErx/rdgPw/LOTDUafnoTjTYmj7B2MOQXg== "@cspell/dict-golang@^2.0.0": version "2.0.0" @@ -1325,15 +1363,15 @@ resolved "https://registry.yarnpkg.com/@cspell/dict-lua/-/dict-lua-2.0.0.tgz#b96d0363a28ac7e0483ad03edb21705c4f951459" integrity sha512-7WUEBEspSKtsq104WdIys1+DLqAxpJPzw74Py1TuE3fI5GvlzeSZkRFP2ya54GB2lCO4C3mq4M8EnitpibVDfw== -"@cspell/dict-node@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@cspell/dict-node/-/dict-node-2.0.0.tgz#f89ca72deac5bfc7ccd46b6b8880fad52ab44843" - integrity sha512-tPPl3liJORa/l6AoYqh/7rjoM7bdtaIXnIN6ox7CE0flZcBS5rWOB6mzEY3rpu/XJX0pjbBiIoqrolDkVl1RTQ== +"@cspell/dict-node@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@cspell/dict-node/-/dict-node-2.0.1.tgz#eda891ebdbce83f20829cb6c85cd209da8cf5cdd" + integrity sha512-ztBWzhvI+YaMehICSJ65cohhjQqoztxf9vrS3YckOiVGBFvUMaFVNdX9klQkvrLcS/O4+2PzoGeIEkmf99amLA== -"@cspell/dict-npm@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@cspell/dict-npm/-/dict-npm-2.0.2.tgz#8ad78bc23d10aa1dd295bf2de6078a02d3a91766" - integrity sha512-Q5ua0aeKTxW4WxvtU+UMdct46hCStOTeEiiG8iinTh/mH5brmdtMEj4olO8+mmkAKPpIC4TI3TmaaN6RN+Vpgw== +"@cspell/dict-npm@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@cspell/dict-npm/-/dict-npm-2.0.3.tgz#044d71c36cf322f2816a77978bfd5dc21698667c" + integrity sha512-K/rnVhmHkR3jfdo7o8P2NDKyMcpVe9pUBiFDY1y2C0YqZXIxCz1f5hObm/hxyO+Vbn5VLU3TKU5fZ5z3LspXOg== "@cspell/dict-php@^2.0.0": version "2.0.0" @@ -1350,10 +1388,10 @@ resolved "https://registry.yarnpkg.com/@cspell/dict-public-licenses/-/dict-public-licenses-1.0.4.tgz#13c2af357e7139bf3896eba58e0feb9f51053b3f" integrity sha512-h4xULfVEDUeWyvp1OO19pcGDqWcBEQ7WGMp3QBHyYpjsamlzsyYYjCRSY2ZvpM7wruDmywSRFmRHJ/+uNFT7nA== -"@cspell/dict-python@^2.0.6": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@cspell/dict-python/-/dict-python-2.0.6.tgz#2c1b4f61d72c582db03382f72f08fb4192dcd378" - integrity sha512-54ICgMRiGwavorg8UJC38Fwx8tW8WKj8pimJmFUd0F/ImQ8wmeg4VrmyMach5MZVUaw1qUe2aP5uSyqA15Q0mg== +"@cspell/dict-python@^3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@cspell/dict-python/-/dict-python-3.0.3.tgz#6c55ee768ffe93a828e607bcab437ccf78c494c6" + integrity sha512-Mt415KczTfqmLvKTgeV8FzMzpms9baTS0P5HfULTW+UxQtZeroviYyRM9TJPJKJSoI0ISu0GiIDgmYlV7+YPog== "@cspell/dict-r@^1.0.2": version "1.0.2" @@ -1375,10 +1413,10 @@ resolved "https://registry.yarnpkg.com/@cspell/dict-scala/-/dict-scala-2.0.0.tgz#b8098103bb03a13406c1c79f1769052353aafac4" integrity sha512-MUwA2YKpqaQOSR4V1/CVGRNk8Ii5kf6I8Ch+4/BhRZRQXuwWbi21rDRYWPqdQWps7VNzAbbMA+PQDWsD5YY38g== -"@cspell/dict-software-terms@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@cspell/dict-software-terms/-/dict-software-terms-2.1.4.tgz#4a3e1d62abcaa237b98510638e279bae7712e97f" - integrity sha512-MB2eT9qhbnIEJajGv+ndzzi6S8NCJ9cMyeGJYMoRAiJobTKP6xPrT37VjPzhckRtrHJGG//UgtQ4NsiK5aBITw== +"@cspell/dict-software-terms@^2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@cspell/dict-software-terms/-/dict-software-terms-2.1.5.tgz#4e2aa08839f37aa933cf1ac5196dbc7005bc8d3e" + integrity sha512-ylXWCsOJlYuucaMoHaHQLVaB8HeDrsCZ42a3jrTC/i6F/SF9I+4tBg4lMivd4w31bXBgILdbIvVHtWzJf+5m0A== "@cspell/dict-swift@^1.0.2": version "1.0.2" @@ -1409,19 +1447,19 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA== -"@es-joy/jsdoccomment@~0.22.1": - version "0.22.1" - resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.22.1.tgz#3c86d458780231769215a795105bd3b03b2616f2" - integrity sha512-/WMkqLYfwCf0waCAMC8Eddt3iAOdghkDF5vmyKEu8pfO66KRFY1L15yks8mfgURiwOAOJpAQ3blvB3Znj6ZwBw== +"@es-joy/jsdoccomment@~0.29.0": + version "0.29.0" + resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.29.0.tgz#527c7eefadeaf5c5d0c3b2721b5fa425d2119e98" + integrity sha512-4yKy5t+/joLihG+ei6CCU6sc08sjUdEdXCQ2U+9h9VP13EiqHQ4YMgDC18ys/AsLdJDBX3KRx/AWY6PR7hn52Q== dependencies: comment-parser "1.3.1" esquery "^1.4.0" - jsdoc-type-pratt-parser "~2.2.5" + jsdoc-type-pratt-parser "~3.0.1" -"@eslint/eslintrc@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6" - integrity sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ== +"@eslint/eslintrc@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.2.tgz#4989b9e8c0216747ee7cca314ae73791bb281aae" + integrity sha512-lTVWHs7O2hjBFZunXTZYnYqtB9GakA1lnxIf+gKq2nY5gxkkNi/lQvveW6t8gFdOHTg6nG50Xs95PrLqVpcaLg== dependencies: ajv "^6.12.4" debug "^4.3.2" @@ -1497,6 +1535,18 @@ jest-util "^27.5.1" slash "^3.0.0" +"@jest/console@^28.0.2": + version "28.0.2" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.0.2.tgz#d11e8b43ae431ae9b3112656848417ae4008fcad" + integrity sha512-tiRpnMeeyQuuzgL5UNSeiqMwF8UOWPbAE5rzcu/1zyq4oPG2Ox6xm4YCOruwbp10F8odWc+XwVxTyGzMSLMqxA== + dependencies: + "@jest/types" "^28.0.2" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^28.0.2" + jest-util "^28.0.2" + slash "^3.0.0" + "@jest/core@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" @@ -1593,6 +1643,13 @@ terminal-link "^2.0.0" v8-to-istanbul "^8.1.0" +"@jest/schemas@^28.0.2": + version "28.0.2" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.0.2.tgz#08c30df6a8d07eafea0aef9fb222c5e26d72e613" + integrity sha512-YVDJZjd4izeTDkij00vHHAymNXQ6WWsdChFRK86qck6Jpr3DCL5W3Is3vslviRlP+bLuMYRLbdp98amMvqudhA== + dependencies: + "@sinclair/typebox" "^0.23.3" + "@jest/source-map@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" @@ -1612,6 +1669,16 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" +"@jest/test-result@^28.0.2": + version "28.0.2" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.0.2.tgz#bc8e15a95347e3c2149572ae06a5a6fed939c522" + integrity sha512-4EUqgjq9VzyUiVTvZfI9IRJD6t3NYBNP4f+Eq8Zr93+hkJ0RrGU4OBTw8tfNzidKX+bmuYzn8FxqpxOPIGGCMA== + dependencies: + "@jest/console" "^28.0.2" + "@jest/types" "^28.0.2" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + "@jest/test-sequencer@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" @@ -1643,6 +1710,27 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" +"@jest/transform@^28.0.3": + version "28.0.3" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-28.0.3.tgz#591fb5ebc1d84db5c5f21e1225c7406c35f5eb1e" + integrity sha512-+Y0ikI7SwoW/YbK8t9oKwC70h4X2Gd0OVuz5tctRvSV/EDQU00AAkoqevXgPSSFimUmp/sp7Yl8s/1bExDqOIg== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^28.0.2" + "@jridgewell/trace-mapping" "^0.3.7" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^28.0.2" + jest-regex-util "^28.0.2" + jest-util "^28.0.2" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.1" + "@jest/types@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" @@ -1654,6 +1742,18 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" +"@jest/types@^28.0.2": + version "28.0.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.0.2.tgz#70b9538c1863fb060b2f438ca008b5563d00c5b4" + integrity sha512-hi3jUdm9iht7I2yrV5C4s3ucCJHUP8Eh3W6rQ1s4n/Qw9rQgsda4eqCt+r3BKRi7klVmZfQlMx1nGlzNMP2d8A== + dependencies: + "@jest/schemas" "^28.0.2" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + "@joi/date@^2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@joi/date/-/date-2.1.0.tgz#fa7e3069a63c17d9ebe51a0b667f090c288de237" @@ -1661,11 +1761,24 @@ dependencies: moment "2.x.x" +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/resolve-uri@^3.0.3": version "3.0.5" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c" integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew== +"@jridgewell/set-array@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.0.tgz#1179863356ac8fbea64a5a4bcde93a4871012c01" + integrity sha512-SfJxIxNVYLTsKwzB3MoOQ1yxf4w/E6MdkvTgrgAt1bfxjSrLUoHMKrDOykwN14q65waezZIdqDneUIPh4/sKxg== + "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.11" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" @@ -1679,6 +1792,19 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/trace-mapping@^0.3.7": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz#0300943770e04231041a51bd39f0439b5c7ab4f0" + integrity sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1752,13 +1878,20 @@ resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-1.0.3.tgz#a912e637418ffc5f2db375e93b85837691a43a33" integrity sha512-fnkhw+fmX65kiLqk6E3BFLXNC26rUhK90zVwe2yncPliVT/Qos3xjhTLE59Df8KnPlcwIERXKVlU1bXoUQ+liA== -"@npmcli/promise-spawn@^1.2.0", "@npmcli/promise-spawn@^1.3.2": +"@npmcli/promise-spawn@^1.3.2": version "1.3.2" resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz#42d4e56a8e9274fba180dabc0aea6e38f29274f5" integrity sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg== dependencies: infer-owner "^1.0.4" +"@npmcli/promise-spawn@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-3.0.0.tgz#53283b5f18f855c6925f23c24e67c911501ef573" + integrity sha512-s9SgS+p3a9Eohe68cSI3fi+hpcZUmXq5P7w0kMlAsWVtR7XbK3ptkZqKT2cK1zLDObJ3sR+8P59sJE0w/KTL1g== + dependencies: + infer-owner "^1.0.4" + "@npmcli/run-script@^3.0.1": version "3.0.1" resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-3.0.1.tgz#9d10b46586300074cc9e53ef320130a69567e1ce" @@ -1769,10 +1902,10 @@ node-gyp "^9.0.0" read-package-json-fast "^2.0.3" -"@patternfly/patternfly@4.183.1": - version "4.183.1" - resolved "https://registry.yarnpkg.com/@patternfly/patternfly/-/patternfly-4.183.1.tgz#717ae0f5614605369f0a26bf17d99b993f6f449a" - integrity sha512-XJZIG/kcEbIPI/0Q6+Q5ax2m295IpQCppertUQ4RfOSkvJVfjQ4CUNmR/ycgjlGm1DItmYJe/NqVFerNlvzUeg== +"@patternfly/patternfly@4.192.1": + version "4.192.1" + resolved "https://registry.yarnpkg.com/@patternfly/patternfly/-/patternfly-4.192.1.tgz#7bc466327a358891a915f0ccf3870bf60d775310" + integrity sha512-eNJ3aI9mGfvwMtBwkI+CBJHPhZx1FoNN6QY36iYEvrEOIL5xuuKRDG2tbOzeucQOzNqZ1PO1Eoock5xTcCG86Q== "@patternfly/react-charts@6.51.19": version "6.51.19" @@ -1850,10 +1983,10 @@ resolved "https://registry.yarnpkg.com/@redhat-cloud-services/frontend-components-config-utilities/-/frontend-components-config-utilities-1.5.17.tgz#d7b104b1f9df2d6fc7c45783831cdd31f063b778" integrity sha512-eXDUIdzfL7CVliHIVThaNY+t5+qd5Jgx360uoURMWdEFQmPHlaAo7hpEqQBcFw77oPFmI1bqE5tOOUkVHPfHmA== -"@redhat-cloud-services/frontend-components-config@4.6.6": - version "4.6.6" - resolved "https://registry.yarnpkg.com/@redhat-cloud-services/frontend-components-config/-/frontend-components-config-4.6.6.tgz#ab4491fb3ef177416f7aa32f743dc0454541e6a3" - integrity sha512-aOOwpFhfKxb+OEWNp92fFR/52AwgOXK+l3A3tZBQPcJL2aRS+WMOooqya0vhmSvRmQWAZYawY+aq4xdDpXMkNg== +"@redhat-cloud-services/frontend-components-config@4.6.11": + version "4.6.11" + resolved "https://registry.yarnpkg.com/@redhat-cloud-services/frontend-components-config/-/frontend-components-config-4.6.11.tgz#e052cf834c5c40c9f3bdcaa0f4de2ab9be1b52c3" + integrity sha512-EBm/kEVIk2UNMa9MQjv5a0C/tMZH+nNc+CsvNanD8EjUdTfPIYoJ0eAtEbQPJ/gIS3pc4+5+fz++GptU/YLk0A== dependencies: "@redhat-cloud-services/frontend-components-config-utilities" "^1.5.17" assert "^2.0.0" @@ -1888,7 +2021,7 @@ util "^0.12.4" webpack "^5.55.1" webpack-cli "^4.8.0" - webpack-dev-server "4.3.1" + webpack-dev-server "4.8.1" write-file-webpack-plugin "^4.5.1" yargs "^17.2.1" @@ -1915,10 +2048,10 @@ mkdirp "^1.0.4" react-content-loader ">=3.4.1" -"@redhat-cloud-services/frontend-components-utilities@3.2.12": - version "3.2.12" - resolved "https://registry.yarnpkg.com/@redhat-cloud-services/frontend-components-utilities/-/frontend-components-utilities-3.2.12.tgz#3835e7b0c364811c3a4f6faec9012089f94a88fc" - integrity sha512-vmw1qC1GPVskD8TaNzJibuAAfC77GrLR1wzjTIxVUW3VDZD6pbaSgxiYpgTm4q6iPklNAy5DtYCDWZ8g6Bp1LQ== +"@redhat-cloud-services/frontend-components-utilities@3.2.16": + version "3.2.16" + resolved "https://registry.yarnpkg.com/@redhat-cloud-services/frontend-components-utilities/-/frontend-components-utilities-3.2.16.tgz#ac58bcdd885b831b4a4f05f285ea4d1eda45c6b1" + integrity sha512-DZ0rg73JdnBW8xovot8Nth5GVeIZTeHIE8to2ygJxmW/0yLRLG0b6vR2gQBmWClkbaI2dpehkE9P/Mtx+tOj/g== dependencies: "@redhat-cloud-services/types" "0.0.1" "@sentry/browser" "^5.4.0" @@ -1928,10 +2061,10 @@ mkdirp "^1.0.4" react-content-loader ">=3.4.1" -"@redhat-cloud-services/frontend-components@3.8.3": - version "3.8.3" - resolved "https://registry.yarnpkg.com/@redhat-cloud-services/frontend-components/-/frontend-components-3.8.3.tgz#c0b52ef67651ad904a704729ec37ed7cbe8e6da6" - integrity sha512-PWAWuBjSEFcErmUgKnQ0UH6dEtgLK0+iAJiTqWvhzS8xlWCDQaNtvb7w8MolTGkWU46BaeaiuFuuELskarrsRA== +"@redhat-cloud-services/frontend-components@3.8.12": + version "3.8.12" + resolved "https://registry.yarnpkg.com/@redhat-cloud-services/frontend-components/-/frontend-components-3.8.12.tgz#9a4105ba477d857a61bc143a7e3a4596824ca541" + integrity sha512-k2t5D/I57Tt0ILa+F/TSsbF05mVhrDHY2cf/5dFlN4cvxNp6nDtb3L06gkiSc79VAq3HwliNlz32la2p8uNMpw== dependencies: "@redhat-cloud-services/frontend-components-utilities" ">=3.0.0" "@redhat-cloud-services/types" "0.0.1" @@ -2031,6 +2164,11 @@ resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== +"@sinclair/typebox@^0.23.3": + version "0.23.5" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.23.5.tgz#93f7b9f4e3285a7a9ade7557d9a8d36809cbc47d" + integrity sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg== + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -2100,6 +2238,21 @@ dependencies: "@babel/types" "^7.3.0" +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.10" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" + integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== + dependencies: + "@types/node" "*" + "@types/cheerio@^0.22.22": version "0.22.31" resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.31.tgz#b8538100653d6bb1b08a1e46dec75b4f2a5d5eb6" @@ -2107,6 +2260,21 @@ dependencies: "@types/node" "*" +"@types/connect-history-api-fallback@^1.3.5": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" + integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + "@types/debounce-promise@^3.1.1": version "3.1.4" resolved "https://registry.yarnpkg.com/@types/debounce-promise/-/debounce-promise-3.1.4.tgz#bf10eead11724e666ea541df1c9d3969677a505b" @@ -2141,6 +2309,25 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": + version "4.17.28" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8" + integrity sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + "@types/glob@^7.1.1": version "7.2.0" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" @@ -2149,7 +2336,7 @@ "@types/minimatch" "*" "@types/node" "*" -"@types/graceful-fs@^4.1.2": +"@types/graceful-fs@^4.1.2", "@types/graceful-fs@^4.1.3": version "4.1.5" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== @@ -2210,6 +2397,11 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + "@types/minimatch@*": version "3.0.5" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" @@ -2245,6 +2437,16 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11" integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ== +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + "@types/react-redux@^7.1.20": version "7.1.22" resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.22.tgz#0eab76a37ef477cc4b53665aeaf29cb60631b72a" @@ -2274,6 +2476,28 @@ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== +"@types/serve-index@^1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" + integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== + dependencies: + "@types/express" "*" + +"@types/serve-static@*": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.33" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" + integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== + dependencies: + "@types/node" "*" + "@types/source-list-map@*": version "0.1.2" resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" @@ -2317,6 +2541,13 @@ anymatch "^3.0.0" source-map "^0.6.0" +"@types/ws@^8.5.1": + version "8.5.3" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== + dependencies: + "@types/node" "*" + "@types/yargs-parser@*": version "20.2.1" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129" @@ -2329,6 +2560,13 @@ dependencies: "@types/yargs-parser" "*" +"@types/yargs@^17.0.8": + version "17.0.10" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.10.tgz#591522fce85d8739bca7b8bb90d048e4478d186a" + integrity sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA== + dependencies: + "@types/yargs-parser" "*" + "@typescript-eslint/eslint-plugin@^5.5.0": version "5.12.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.12.1.tgz#b2cd3e288f250ce8332d5035a2ff65aba3374ac4" @@ -2554,19 +2792,19 @@ resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.1.tgz#0de2875ac31b46b6c5bb1ae0a7d7f0ba5678dffe" integrity sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw== -"@wojtekmaj/enzyme-adapter-react-17@^0.6.6": - version "0.6.6" - resolved "https://registry.yarnpkg.com/@wojtekmaj/enzyme-adapter-react-17/-/enzyme-adapter-react-17-0.6.6.tgz#2ee3d4956caea4de05e372e5d9f39b31becffe6a" - integrity sha512-gSfhg8CiL0Vwc2UgUblGVZIy7M0KyXaZsd8+QwzV8TSVRLkGyzdLtYEcs9wRWyQTsdmOd+oRGqbVgUX7AVJxug== +"@wojtekmaj/enzyme-adapter-react-17@^0.6.7": + version "0.6.7" + resolved "https://registry.yarnpkg.com/@wojtekmaj/enzyme-adapter-react-17/-/enzyme-adapter-react-17-0.6.7.tgz#7784bd32f518b186218cebb26c98c852676f30b0" + integrity sha512-B+byiwi/T1bx5hcj9wc0fUL5Hlb5giSXJzcnEfJVl2j6dGV2NJfcxDBYX0WWwIxlzNiFz8kAvlkFWI2y/nscZQ== dependencies: - "@wojtekmaj/enzyme-adapter-utils" "^0.1.2" + "@wojtekmaj/enzyme-adapter-utils" "^0.1.4" enzyme-shallow-equal "^1.0.0" has "^1.0.0" prop-types "^15.7.0" react-is "^17.0.0" react-test-renderer "^17.0.0" -"@wojtekmaj/enzyme-adapter-utils@^0.1.2": +"@wojtekmaj/enzyme-adapter-utils@^0.1.4": version "0.1.4" resolved "https://registry.yarnpkg.com/@wojtekmaj/enzyme-adapter-utils/-/enzyme-adapter-utils-0.1.4.tgz#bcd411ad6e368f17dce5425582c2907104cdb1ad" integrity sha512-ARGIQSIIv3oBia1m5Ihn1VU0FGmft6KPe39SBKTb8p7LSXO23YI4kNtc4M/cKoIY7P+IYdrZcgMObvedyjoSQA== @@ -2791,16 +3029,16 @@ apidoc-core@^0.15.0: lodash "^4.17.20" semver "~7.3.2" -apidoc-mock@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/apidoc-mock/-/apidoc-mock-4.0.2.tgz#0b66008b828f758fd8fa5f57ee5068def1d5e2bb" - integrity sha512-8VEJ6sBuZ3MDqnJYrQV8WgQ30iq/vmcZhoemt1DTZ1j3oa6NTiNu2UhMRR6SdfH07L3mih0nq1Lp9KoMaPgwdg== +apidoc-mock@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/apidoc-mock/-/apidoc-mock-4.0.3.tgz#ea4b37d5443eb21ad82316dda02d0df183d7864e" + integrity sha512-6dQ4ZN0HZ1NuzgXzsaLpVFx1djH0R/ofoyv98UtBkXpiQ2ovYW5AaeJNmxFpc1hvHbAbQnI21rs/U08xxBdEow== dependencies: apidoc "^0.29.0" - express "^4.17.1" + express "^4.17.2" node-watch "^0.7.2" - winston "^3.3.3" - yargs "^17.2.1" + winston "^3.6.0" + yargs "^17.3.1" apidoc@^0.29.0: version "0.29.0" @@ -2854,7 +3092,7 @@ array-flatten@1.1.1: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= -array-flatten@^2.1.0: +array-flatten@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== @@ -3052,6 +3290,19 @@ babel-jest@^27.5.1: graceful-fs "^4.2.9" slash "^3.0.0" +babel-jest@^28.0.3: + version "28.0.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-28.0.3.tgz#843dc170da5b9671d4054ada9fdcd28f85f92a6e" + integrity sha512-S0ADyYdcrt5fp9YldRYWCUHdk1BKt9AkvBkLWBoNAEV9NoWZPIj5+MYhPcGgTS65mfv3a+Ymf2UqgWoAVd41cA== + dependencies: + "@jest/transform" "^28.0.3" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^28.0.2" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + babel-loader@^8.2.2: version "8.2.3" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.3.tgz#8986b40f1a64cacfcb4b8429320085ef68b1342d" @@ -3090,6 +3341,16 @@ babel-plugin-jest-hoist@^27.5.1: "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" +babel-plugin-jest-hoist@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.0.2.tgz#9307d03a633be6fc4b1a6bc5c3a87e22bd01dd3b" + integrity sha512-Kizhn/ZL+68ZQHxSnHyuvJv8IchXD62KQxV77TBDV/xoBFBOfgRAk97GNs6hXdTTCiVES9nB2I6+7MXXrk5llQ== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + babel-plugin-macros@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" @@ -3154,6 +3415,14 @@ babel-preset-jest@^27.5.1: babel-plugin-jest-hoist "^27.5.1" babel-preset-current-node-syntax "^1.0.0" +babel-preset-jest@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-28.0.2.tgz#d8210fe4e46c1017e9fa13d7794b166e93aa9f89" + integrity sha512-sYzXIdgIXXroJTFeB3S6sNDWtlJ2dllCdTEsnZ65ACrMojj3hVNFRmnJ1HZtomGi+Be7aqpY/HJ92fr8OhKVkQ== + dependencies: + babel-plugin-jest-hoist "^28.0.2" + babel-preset-current-node-syntax "^1.0.0" + babel-preset-react-app@^10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz#ed6005a20a24f2c88521809fa9aea99903751584" @@ -3236,17 +3505,33 @@ body-parser@1.19.2: raw-body "2.4.3" type-is "~1.6.18" -bonjour@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" - integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= +body-parser@1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" + integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.10.3" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +bonjour-service@^1.0.11: + version "1.0.12" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.12.tgz#28fbd4683f5f2e36feedb833e24ba661cac960c3" + integrity sha512-pMmguXYCu63Ug37DluMKEHdxc+aaIf/ay4YbF8Gxtba+9d3u+rmEWy61VK3Z3hp8Rskok3BunHYnG0dUHAsblw== dependencies: - array-flatten "^2.1.0" - deep-equal "^1.0.1" + array-flatten "^2.1.2" dns-equal "^1.0.0" - dns-txt "^2.0.2" - multicast-dns "^6.0.1" - multicast-dns-service-types "^1.1.0" + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.4" boolbase@^1.0.0: version "1.0.0" @@ -3282,7 +3567,7 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^3.0.1, braces@~3.0.2: +braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -3312,6 +3597,17 @@ browserslist@^4.14.5, browserslist@^4.17.5, browserslist@^4.19.1: node-releases "^2.0.2" picocolors "^1.0.0" +browserslist@^4.20.2: + version "4.20.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.3.tgz#eb7572f49ec430e054f56d52ff0ebe9be915f8bf" + integrity sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg== + dependencies: + caniuse-lite "^1.0.30001332" + electron-to-chromium "^1.4.118" + escalade "^3.1.1" + node-releases "^2.0.3" + picocolors "^1.0.0" + bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -3329,11 +3625,6 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer-indexof@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" - integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== - buffer@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" @@ -3471,6 +3762,11 @@ caniuse-lite@^1.0.30001312: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz#e11eba4b87e24d22697dae05455d5aea28550d5f" integrity sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ== +caniuse-lite@^1.0.30001332: + version "1.0.30001335" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001335.tgz#899254a0b70579e5a957c32dced79f0727c61f2a" + integrity sha512-ddP1Tgm7z2iIxu6QTtbZUv6HJxSaV/PZeSrWFZtbY4JZ69tOeNhBCl3HyRQgeNZKE5AOn1kpV7fhljigy0Ty3w== + chalk@^2.0.0, chalk@^2.4.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -3532,7 +3828,7 @@ cheerio@^1.0.0-rc.3: parse5-htmlparser2-tree-adapter "^6.0.1" tslib "^2.2.0" -"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.1, chokidar@^3.5.2: +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.2, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -3749,7 +4045,7 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -commander@>=2.20.0, commander@^9.0.0: +commander@>=2.20.0: version "9.0.0" resolved "https://registry.yarnpkg.com/commander/-/commander-9.0.0.tgz#86d58f24ee98126568936bd1d3574e0308a99a40" integrity sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw== @@ -3774,6 +4070,11 @@ commander@^9.1.0: resolved "https://registry.yarnpkg.com/commander/-/commander-9.1.0.tgz#a6b263b2327f2e188c6402c42623327909f2dbec" integrity sha512-i0/MaqBtdbnJ4XQs4Pmyb+oFQl+q0lsAmokVUH92SlSw4fkeAcG3bVon+Qt7hmtF+u3Het6o4VgrcY3qAoEB6w== +commander@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.2.0.tgz#6e21014b2ed90d8b7c9647230d8b7a94a4a419a9" + integrity sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w== + comment-json@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/comment-json/-/comment-json-4.2.2.tgz#5fae70a94e0c8f84a077bd31df5aa5269252f293" @@ -4080,6 +4381,11 @@ cookie@0.4.2: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + copy-to-clipboard@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz#115aa1a9998ffab6196f93076ad6da3b913662ae" @@ -4163,44 +4469,44 @@ 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-gitignore@^5.19.3: - version "5.19.3" - resolved "https://registry.yarnpkg.com/cspell-gitignore/-/cspell-gitignore-5.19.3.tgz#c27780dc1b43cb48705dc3695c3875f001d7b038" - integrity sha512-Q67uHcf0qNgOoanRLhatapjWpLiftT+MuLIyAaSLe5eNVzQurQIc+UnXhtaslkVyOTqQt4NJFqLgtf5ZSGz1bg== +cspell-gitignore@^5.20.0: + version "5.20.0" + resolved "https://registry.yarnpkg.com/cspell-gitignore/-/cspell-gitignore-5.20.0.tgz#0c4f405559383663a9c24fab5cf829e7b19abed5" + integrity sha512-oWzoHcaidX6jFON6vwiH3cA1HqkGmawD1DWt+fPWKrea9/SuTcvFxm+RbqO4DjwXEAMIczyPOWo+SCM0VbcCrA== dependencies: - cspell-glob "^5.19.3" + cspell-glob "^5.20.0" find-up "^5.0.0" -cspell-glob@^5.19.3: - version "5.19.3" - resolved "https://registry.yarnpkg.com/cspell-glob/-/cspell-glob-5.19.3.tgz#f6b423523a0c2d77d244ecfc7c48ef320f4d122a" - integrity sha512-qp2Oe/euzTu3e0zZrQxHuTrqRo418tYfh4CnCa+DKU6lWKKcF4zCEhOGJHPsYak8SFIXZ4ZE360wHFxB/JDutQ== +cspell-glob@^5.20.0: + version "5.20.0" + resolved "https://registry.yarnpkg.com/cspell-glob/-/cspell-glob-5.20.0.tgz#2bda5cc90bc6694ce2eb1a5aaee54196fc9b37a9" + integrity sha512-eyo8NYH4GapHxfilMarwvf1HIyGWT3gWuFlYkmQjYVx3KjzmfR1Y1x9S068wmwjp9kKCu9T6Vj71EGG+9R59Lw== dependencies: - micromatch "^4.0.4" + micromatch "^4.0.5" -cspell-io@^5.19.3: - version "5.19.3" - resolved "https://registry.yarnpkg.com/cspell-io/-/cspell-io-5.19.3.tgz#89ab249dc53206651a7833399a83b04a7d8a8a63" - integrity sha512-dE9eBvHgIJ11DelWtyehMU3W3bCpcB+0nS6uOZJ2d8fDu13m5BebpLrXZ2dKfY4cjksJUhRPatt14uwQSeUp2A== +cspell-io@^5.20.0: + version "5.20.0" + resolved "https://registry.yarnpkg.com/cspell-io/-/cspell-io-5.20.0.tgz#2f7fc676a068acc641f3bd77ddca7f72985b6ee5" + integrity sha512-wgqqpVIhtMh+/+3YfHt8cDfrD7OLF+xQlStlURj8AJwEJ0xu16zyI9S5zcig+83+0QyzuMdxfZiMgbdQxWEvOg== -cspell-lib@^5.19.3: - version "5.19.3" - resolved "https://registry.yarnpkg.com/cspell-lib/-/cspell-lib-5.19.3.tgz#6efc9ee5620d427e2f20c000b60a3b3d0ce6cd4c" - integrity sha512-peMJggwJpxCXKZZ0DuHyDtZmf66POKaHf5Im8LGEyMKFARUIq6O2WvaUGggYjyRe3Ng/f5G+EYTcIHbF9pZYcg== +cspell-lib@^5.20.0: + version "5.20.0" + resolved "https://registry.yarnpkg.com/cspell-lib/-/cspell-lib-5.20.0.tgz#0eb5797cb32ce03db7ad7e14649296c434e3d142" + integrity sha512-Fc7+3ExF2pNS8BsQTXSMkhR6ITbpyiMQf+y4ZH/aBml09+O6lrbj4j2tJx/oR4XvDEA8uQkV/5lMGdU+otC1KQ== dependencies: - "@cspell/cspell-bundled-dicts" "^5.19.3" - "@cspell/cspell-pipe" "^5.19.3" - "@cspell/cspell-types" "^5.19.3" + "@cspell/cspell-bundled-dicts" "^5.20.0" + "@cspell/cspell-pipe" "^5.20.0" + "@cspell/cspell-types" "^5.20.0" clear-module "^4.1.2" comment-json "^4.2.2" configstore "^5.0.1" cosmiconfig "^7.0.1" - cspell-glob "^5.19.3" - cspell-io "^5.19.3" - cspell-trie-lib "^5.19.3" - fast-equals "^3.0.0" + cspell-glob "^5.20.0" + cspell-io "^5.20.0" + cspell-trie-lib "^5.20.0" + fast-equals "^3.0.2" find-up "^5.0.0" - fs-extra "^10.0.1" + fs-extra "^10.1.0" gensequence "^3.1.1" import-fresh "^3.3.0" resolve-from "^5.0.0" @@ -4208,34 +4514,33 @@ cspell-lib@^5.19.3: vscode-languageserver-textdocument "^1.0.4" vscode-uri "^3.0.3" -cspell-trie-lib@^5.19.3: - version "5.19.3" - resolved "https://registry.yarnpkg.com/cspell-trie-lib/-/cspell-trie-lib-5.19.3.tgz#0a0f8d9300f95188f2f2b1831bd7fea2e9c9d6ee" - integrity sha512-Io8EB7E1pmttHzZvgvPEF0b87qlq8G5uA4B+sbqCxrUf5l4JDcK/UYLih0+rekLTbv4Q68zqgCTASvqxgqnoAg== +cspell-trie-lib@^5.20.0: + version "5.20.0" + resolved "https://registry.yarnpkg.com/cspell-trie-lib/-/cspell-trie-lib-5.20.0.tgz#3a13ba0477a36ecb16311e85b270bcc2b4300f37" + integrity sha512-ET95dJh+OJ04PdLI9dKqAa+dDu47tXcUxCR6uKiZ+qZ18v1Zl986s8q89m9c+xpo7Leqh0rF6Zsw3M9Cjy6Jhw== dependencies: - "@cspell/cspell-pipe" "^5.19.3" - fs-extra "^10.0.1" + "@cspell/cspell-pipe" "^5.20.0" + fs-extra "^10.1.0" gensequence "^3.1.1" -cspell@^5.19.3: - version "5.19.3" - resolved "https://registry.yarnpkg.com/cspell/-/cspell-5.19.3.tgz#0f2c6cf529fb3f0b721b380f81b04e9c22272c05" - integrity sha512-JJBH8iqtHYmxqLQZ+7GAMTVvc6SAoHVgn1tdYknOI2/uxAbZVH29eaxINY7JfjwPuxPPVAvttRetBAIRiu6ZYw== +cspell@^5.20.0: + version "5.20.0" + resolved "https://registry.yarnpkg.com/cspell/-/cspell-5.20.0.tgz#580909fc1283aeda43f1c583188ea046417d340b" + integrity sha512-lXAS14ZlfJfOI3FgoAAfyl/AlTB8T+ayHmKrHxwuRRUvN4IBT4y8d7tdjWDj7/bsM4u5M5WrlAXg6vXH3Fg5bA== dependencies: - "@cspell/cspell-pipe" "^5.19.3" + "@cspell/cspell-pipe" "^5.20.0" chalk "^4.1.2" - commander "^9.1.0" - comment-json "^4.2.2" - cspell-gitignore "^5.19.3" - cspell-glob "^5.19.3" - cspell-lib "^5.19.3" + commander "^9.2.0" + cspell-gitignore "^5.20.0" + cspell-glob "^5.20.0" + cspell-lib "^5.20.0" fast-json-stable-stringify "^2.1.0" file-entry-cache "^6.0.1" - fs-extra "^10.0.1" + fs-extra "^10.1.0" get-stdin "^8.0.0" - glob "^7.2.0" + glob "^8.0.1" imurmurhash "^0.1.4" - semver "^7.3.5" + semver "^7.3.7" strip-ansi "^6.0.1" vscode-uri "^3.0.3" @@ -4495,18 +4800,6 @@ deep-diff@^0.3.5: resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84" integrity sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ= -deep-equal@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -4522,7 +4815,7 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== -default-gateway@^6.0.0: +default-gateway@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== @@ -4566,20 +4859,6 @@ del@^4.1.1: pify "^4.0.1" rimraf "^2.6.3" -del@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/del/-/del-6.0.0.tgz#0b40d0332cea743f1614f818be4feb717714c952" - integrity sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ== - dependencies: - globby "^11.0.1" - graceful-fs "^4.2.4" - is-glob "^4.0.1" - is-path-cwd "^2.2.0" - is-path-inside "^3.0.2" - p-map "^4.0.0" - rimraf "^3.0.2" - slash "^3.0.0" - delaunator@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-4.0.1.tgz#3d779687f57919a7a418f8ab947d3bddb6846957" @@ -4602,11 +4881,21 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + depd@^1.1.2, depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" @@ -4649,20 +4938,12 @@ dns-equal@^1.0.0: resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= -dns-packet@^1.3.1: - version "1.3.4" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" - integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== - dependencies: - ip "^1.1.0" - safe-buffer "^5.0.1" - -dns-txt@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" - integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= +dns-packet@^5.2.2: + version "5.3.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.3.1.tgz#eb94413789daec0f0ebe2fcc230bdc9d7c91b43d" + integrity sha512-spBwIj0TK0Ey3666GwIdWVfUpLyubpU53BTCu8iPn4r4oXd9O14Hjg3EHw3ts2oed77/SeckunUYCyRlSngqHw== dependencies: - buffer-indexof "^1.0.0" + "@leichtgewicht/ip-codec" "^2.0.1" doctrine@^2.1.0: version "2.1.0" @@ -4796,11 +5077,21 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +electron-to-chromium@^1.4.118: + version "1.4.132" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.132.tgz#b64599eb018221e52e2e4129de103b03a413c55d" + integrity sha512-JYdZUw/1068NWN+SwXQ7w6Ue0bWYGihvSUNNQwurvcDV/SM7vSiGZ3NuFvFgoEiCs4kB8xs3cX2an3wB7d4TBw== + electron-to-chromium@^1.4.71: version "1.4.71" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz#17056914465da0890ce00351a3b946fd4cd51ff6" integrity sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw== +emittery@^0.10.2: + version "0.10.2" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" + integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== + emittery@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" @@ -5069,10 +5360,10 @@ eslint-config-prettier@^8.5.0: resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== -eslint-config-react-app@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-7.0.0.tgz#0fa96d5ec1dfb99c029b1554362ab3fa1c3757df" - integrity sha512-xyymoxtIt1EOsSaGag+/jmcywRuieQoA2JbPCjnw9HukFj9/97aGPoZVFioaotzk1K5Qt9sHO5EutZbkrAXS0g== +eslint-config-react-app@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz#73ba3929978001c5c86274c017ea57eb5fa644b4" + integrity sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA== dependencies: "@babel/core" "^7.16.0" "@babel/eslint-parser" "^7.16.3" @@ -5139,25 +5430,24 @@ eslint-plugin-jest@^25.3.0: dependencies: "@typescript-eslint/experimental-utils" "^5.0.0" -eslint-plugin-jest@^26.1.3: - version "26.1.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-26.1.3.tgz#e722e5efeea18aa9dec7c7349987b641db19feb7" - integrity sha512-Pju+T7MFpo5VFhFlwrkK/9jRUu18r2iugvgyrWOnnGRaVTFFmFXp+xFJpHyqmjjLmGJPKLeEFLVTAxezkApcpQ== +eslint-plugin-jest@^26.1.5: + version "26.1.5" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-26.1.5.tgz#6cfca264818d6d6aa120b019dab4d62b6aa8e775" + integrity sha512-su89aDuljL9bTjEufTXmKUMSFe2kZUL9bi7+woq+C2ukHZordhtfPm4Vg+tdioHBaKf8v3/FXW9uV0ksqhYGFw== dependencies: "@typescript-eslint/utils" "^5.10.0" -eslint-plugin-jsdoc@^38.0.6: - version "38.0.6" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-38.0.6.tgz#b26843bdc445202b9f0e3830bda39ec5aacbfa97" - integrity sha512-Wvh5ERLUL8zt2yLZ8LLgi8RuF2UkjDvD+ri1/i7yMpbfreK2S29B9b5JC7iBIoFR7KDaEWCLnUPHTqgwcXX1Sg== +eslint-plugin-jsdoc@^39.2.9: + version "39.2.9" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.2.9.tgz#bc351de403f1862f1ef8c440d12dedc28e74cbbb" + integrity sha512-gaPYJT94rWlWyQcisQyyEJHtLaaJqN4baFlLCEr/LcXVibS9wzQTL2dskqk327ggwqQopR+Xecu2Lng1IJ9Ypw== dependencies: - "@es-joy/jsdoccomment" "~0.22.1" + "@es-joy/jsdoccomment" "~0.29.0" comment-parser "1.3.1" debug "^4.3.4" escape-string-regexp "^4.0.0" esquery "^1.4.0" - regextras "^0.8.0" - semver "^7.3.5" + semver "^7.3.7" spdx-expression-parse "^3.0.1" eslint-plugin-json@^3.1.0: @@ -5269,12 +5559,12 @@ eslint-webpack-plugin@^3.1.1: normalize-path "^3.0.0" schema-utils "^3.1.1" -eslint@8.11.0: - version "8.11.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.11.0.tgz#88b91cfba1356fc10bb9eb592958457dfe09fb37" - integrity sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA== +eslint@8.14.0: + version "8.14.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.14.0.tgz#62741f159d9eb4a79695b28ec4989fcdec623239" + integrity sha512-3/CE4aJX7LNEiE3i6FeodHmI/38GZtWCsAtsymScmzYapx8q1nVVb+eLcLSzATmCPXw5pT4TqVs1E0OmxAd9tw== dependencies: - "@eslint/eslintrc" "^1.2.1" + "@eslint/eslintrc" "^1.2.2" "@humanwhocodes/config-array" "^0.9.2" ajv "^6.10.0" chalk "^4.0.0" @@ -5398,7 +5688,7 @@ expect@^27.5.1: jest-matcher-utils "^27.5.1" jest-message-util "^27.5.1" -express@^4.17.1, express@^4.17.2, express@^4.17.3: +express@^4.17.2, express@^4.17.3: version "4.17.3" resolved "https://registry.yarnpkg.com/express/-/express-4.17.3.tgz#f6c7302194a4fb54271b73a1fe7a06478c8f85a1" integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg== @@ -5434,6 +5724,43 @@ express@^4.17.1, express@^4.17.2, express@^4.17.3: utils-merge "1.0.1" vary "~1.1.2" +express@^4.18.1: + version "4.18.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" + integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.0" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.10.3" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -5453,10 +5780,10 @@ fast-diff@^1.1.2: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== -fast-equals@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-3.0.0.tgz#efbe679d4c0d74040f61d4dda3e6bcb3bdccab82" - integrity sha512-Af7nSOpf7617idrFg0MJY6x7yVDPoO80aSwtKTC0afT8B/SsmvTpA+2a+uPLmhVF5IHmY5NPuBAA3dJrp55rJA== +fast-equals@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-3.0.2.tgz#77f80047b381b6cb747130463ccc144e24c44097" + integrity sha512-iY0fAmW7fzxHp22VCRLpOgWbsWsF+DJWi1jhc8w+VGlJUiS+KcGZV2A8t+Q9oTQwhG3L1W8Lu/oe3ZyOPdhZjw== fast-glob@^3.2.7, fast-glob@^3.2.9: version "3.2.11" @@ -5563,6 +5890,19 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + finalhandler@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" @@ -5681,10 +6021,10 @@ fs-access@^1.0.1: dependencies: null-check "^1.0.0" -fs-extra@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.1.tgz#27de43b4320e833f6867cc044bfce29fdf0ef3b8" - integrity sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag== +fs-extra@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" @@ -5903,6 +6243,18 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, gl once "^1.3.0" path-is-absolute "^1.0.0" +glob@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.1.tgz#00308f5c035aa0b2a447cd37ead267ddff1577d3" + integrity sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + global-dirs@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" @@ -5929,7 +6281,7 @@ globals@^13.6.0, globals@^13.9.0: dependencies: type-fest "^0.20.2" -globby@^11.0.1, globby@^11.0.4: +globby@^11.0.4: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -6209,6 +6561,17 @@ http-errors@1.8.1: statuses ">= 1.5.0 < 2" toidentifier "1.0.1" +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + http-errors@~1.6.2: version "1.6.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" @@ -6242,10 +6605,10 @@ http-proxy-agent@^5.0.0: agent-base "6" debug "4" -http-proxy-middleware@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.3.tgz#5df04f69a89f530c2284cd71eeaa51ba52243289" - integrity sha512-1bloEwnrHMnCoO/Gcwbz7eSVvW50KPES01PecpagI+YLNLci4AcuKJrujW4Mc3sBLpFxMSlsLNHS5Nl/lvrTPA== +http-proxy-middleware@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== dependencies: "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" @@ -6312,10 +6675,10 @@ i18next-xhr-backend@^3.2.2: dependencies: "@babel/runtime" "^7.5.5" -i18next@^21.6.14: - version "21.6.14" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.6.14.tgz#2bc199fba7f4da44b5952d7df0a3814a6e5c3943" - integrity sha512-XL6WyD+xlwQwbieXRlXhKWoLb/rkch50/rA+vl6untHnJ+aYnkQ0YDZciTWE78PPhOpbi2gR0LTJCJpiAhA+uQ== +i18next@^21.6.16: + version "21.6.16" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.6.16.tgz#8cff8c3ba2ffaf8438a8c83fe284083f15cf3941" + integrity sha512-xJlzrVxG9CyAGsbMP1aKuiNr1Ed2m36KiTB7hjGMG2Zo4idfw3p9THUEu+GjBwIgEZ7F11ZbCzJcfv4uyfKNuw== dependencies: "@babel/runtime" "^7.17.2" @@ -6348,12 +6711,12 @@ ignore-by-default@^1.0.1: resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= -ignore-walk@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-4.0.1.tgz#fc840e8346cf88a3a9380c5b17933cd8f4d39fa3" - integrity sha512-rzDQLaW4jQbh2YrOFlJdCtX8qgJTehFRYiUB2r1osqTeDzV/3+Jh8fz1oAPzUThf3iku8Ds4IDqawI5d8mUiQw== +ignore-walk@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-5.0.1.tgz#5f199e23e1288f518d90358d461387788a154776" + integrity sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw== dependencies: - minimatch "^3.0.4" + minimatch "^5.0.1" ignore@^5.1.8, ignore@^5.1.9, ignore@^5.2.0: version "5.2.0" @@ -6456,16 +6819,6 @@ inquirer@^8.2.0: strip-ansi "^6.0.0" through "^2.3.6" -internal-ip@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-6.2.0.tgz#d5541e79716e406b74ac6b07b856ef18dc1621c1" - integrity sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg== - dependencies: - default-gateway "^6.0.0" - ipaddr.js "^1.9.1" - is-ip "^3.1.0" - p-event "^4.2.0" - internal-slot@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" @@ -6480,17 +6833,12 @@ interpret@^2.2.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== -ip-regex@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" - integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== - -ip@^1.1.0, ip@^1.1.5: +ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= -ipaddr.js@1.9.1, ipaddr.js@^1.9.1: +ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== @@ -6613,13 +6961,6 @@ is-interactive@^1.0.0: resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== -is-ip@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8" - integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q== - dependencies: - ip-regex "^4.0.0" - is-lambda@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" @@ -6660,7 +7001,7 @@ is-obj@^2.0.0: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== -is-path-cwd@^2.0.0, is-path-cwd@^2.2.0: +is-path-cwd@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== @@ -6711,7 +7052,7 @@ is-potential-custom-element-name@^1.0.1: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== -is-regex@^1.0.4, is-regex@^1.0.5, is-regex@^1.1.4: +is-regex@^1.0.5, is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== @@ -7016,6 +7357,11 @@ jest-get-type@^27.5.1: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== +jest-get-type@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203" + integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA== + jest-haste-map@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" @@ -7036,6 +7382,25 @@ jest-haste-map@^27.5.1: optionalDependencies: fsevents "^2.3.2" +jest-haste-map@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-28.0.2.tgz#0c768f43680013cfd2a4471a3ec76c47bfb9e7c6" + integrity sha512-EokdL7l5uk4TqWGawwrIt8w3tZNcbeiRxmKGEURf42pl+/rWJy3sCJlon5HBhJXZTW978jk6600BLQOI7i25Ig== + dependencies: + "@jest/types" "^28.0.2" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^28.0.2" + jest-util "^28.0.2" + jest-worker "^28.0.2" + micromatch "^4.0.4" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + jest-jasmine2@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" @@ -7092,6 +7457,21 @@ jest-message-util@^27.5.1: slash "^3.0.0" stack-utils "^2.0.3" +jest-message-util@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.0.2.tgz#f3cf36be72be4c4c4058cb34bd6673996d26dee3" + integrity sha512-knK7XyojvwYh1XiF2wmVdskgM/uN11KsjcEWWHfnMZNEdwXCrqB4sCBO94F4cfiAwCS8WFV6CDixDwPlMh/wdA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^28.0.2" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^28.0.2" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-mock@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" @@ -7105,11 +7485,16 @@ jest-pnp-resolver@^1.2.2: resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== -jest-regex-util@^27.0.0, jest-regex-util@^27.5.1: +jest-regex-util@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== +jest-regex-util@^28.0.0, jest-regex-util@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" + integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== + jest-resolve-dependencies@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" @@ -7119,7 +7504,22 @@ jest-resolve-dependencies@^27.5.1: jest-regex-util "^27.5.1" jest-snapshot "^27.5.1" -jest-resolve@27.5.1, jest-resolve@^27.5.1: +jest-resolve@28.0.3: + version "28.0.3" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-28.0.3.tgz#63f8e6b53e40f265b3ca9116195221dd43e3d16d" + integrity sha512-lfgjd9JhEjpjIN3HLUfdysdK+A7ePQoYmd7WL9DUEWqdnngb1rF56eee6iDXJxl/3eSolpP43VD7VrhjL3NsoQ== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^28.0.2" + jest-pnp-resolver "^1.2.2" + jest-util "^28.0.2" + jest-validate "^28.0.2" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + +jest-resolve@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== @@ -7238,6 +7638,18 @@ jest-util@^27.5.1: graceful-fs "^4.2.9" picomatch "^2.2.3" +jest-util@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.0.2.tgz#8e22cdd6e0549e0a393055f0e2da7eacc334b143" + integrity sha512-EVdpIRCC8lzqhp9A0u0aAKlsFIzufK6xKxNK7awsnebTdOP4hpyQW5o6Ox2qPl8gbeUKYF+POLyItaND53kpGA== + dependencies: + "@jest/types" "^28.0.2" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + jest-validate@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" @@ -7250,20 +7662,32 @@ jest-validate@^27.5.1: leven "^3.1.0" pretty-format "^27.5.1" -jest-watch-typeahead@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-1.0.0.tgz#4de2ca1eb596acb1889752afbab84b74fcd99173" - integrity sha512-jxoszalAb394WElmiJTFBMzie/RDCF+W7Q29n5LzOPtcoQoHWfdUtHFkbhgf5NwWe8uMOxvKb/g7ea7CshfkTw== +jest-validate@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-28.0.2.tgz#58bb7e826c054a8bb3b54c05f73758d96cf6dbef" + integrity sha512-nr0UOvCTtxP0YPdsk01Gk7e7c0xIiEe2nncAe3pj0wBfUvAykTVrMrdeASlAJnlEQCBuwN/GF4hKoCzbkGNCNw== + dependencies: + "@jest/types" "^28.0.2" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^28.0.2" + leven "^3.1.0" + pretty-format "^28.0.2" + +jest-watch-typeahead@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz#b4a6826dfb9c9420da2f7bc900de59dad11266a9" + integrity sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw== dependencies: ansi-escapes "^4.3.1" chalk "^4.0.0" - jest-regex-util "^27.0.0" - jest-watcher "^27.0.0" + jest-regex-util "^28.0.0" + jest-watcher "^28.0.0" slash "^4.0.0" string-length "^5.0.1" strip-ansi "^7.0.1" -jest-watcher@^27.0.0, jest-watcher@^27.5.1: +jest-watcher@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== @@ -7276,6 +7700,20 @@ jest-watcher@^27.0.0, jest-watcher@^27.5.1: jest-util "^27.5.1" string-length "^4.0.1" +jest-watcher@^28.0.0: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.0.2.tgz#649fa24df531d4071be5784b6274d494d788c88b" + integrity sha512-uIVJLpQ/5VTGQWBiBatHsi7jrCqHjHl0e0dFHMWzwuIfUbdW/muk0DtSr0fteY2T7QTFylv+7a5Rm8sBKrE12Q== + dependencies: + "@jest/test-result" "^28.0.2" + "@jest/types" "^28.0.2" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.10.2" + jest-util "^28.0.2" + string-length "^4.0.1" + jest-worker@^27.3.1, jest-worker@^27.4.5, jest-worker@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" @@ -7285,6 +7723,15 @@ jest-worker@^27.3.1, jest-worker@^27.4.5, jest-worker@^27.5.1: merge-stream "^2.0.0" supports-color "^8.0.0" +jest-worker@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.0.2.tgz#75f7e5126541289ba02e9c1a67e46349ddb8141d" + integrity sha512-pijNxfjxT0tGAx+8+OzZ+eayVPCwy/rsZFhebmC0F4YnXu1EHPEPxg7utL3m5uX3EaFH1/jwDxGa1EbjJCST2g== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + jest@27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" @@ -7340,10 +7787,10 @@ js-yaml@^4.0.0, js-yaml@^4.1.0: dependencies: argparse "^2.0.1" -jsdoc-type-pratt-parser@~2.2.5: - version "2.2.5" - resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.2.5.tgz#c9f93afac7ee4b5ed4432fe3f09f7d36b05ed0ff" - integrity sha512-2a6eRxSxp1BW040hFvaJxhsCMI9lT8QB8t14t+NY5tC5rckIR0U9cr2tjOeaFirmEOy6MHvmJnY7zTBHq431Lw== +jsdoc-type-pratt-parser@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.0.1.tgz#ccbc7a4180bc8748af64d2cc431aaa92f88175bb" + integrity sha512-vqMCdAFVIiFhVgBYE/X8naf3L/7qiJsaYWTfUJZZZ124dR3OUz9HrmaMUGpYIYAN4VSuodf6gIZY0e8ktPw9cg== jsdom@^16.6.0: version "16.7.0" @@ -7444,6 +7891,11 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" +json5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + jsonc-parser@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" @@ -7764,6 +8216,11 @@ lru-cache@^7.5.1, lru-cache@^7.7.1: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.7.1.tgz#03d2846b1ad2dcc7931a9340b8711d9798fcb0c6" integrity sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw== +lru-cache@^7.9.0: + version "7.9.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.9.0.tgz#29c2a989b6c10f32ceccc66ff44059e1490af3e1" + integrity sha512-lkcNMUKqdJk96TuIXUidxaPuEg5sJo/+ZyVE2BDFnuZGzwXem7d8582eG8vbu4todLfT14snP6iHriCHXXi5Rw== + make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -7923,6 +8380,14 @@ micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4: braces "^3.0.1" picomatch "^2.2.3" +micromatch@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + mime-db@1.51.0, "mime-db@>= 1.43.0 < 2": version "1.51.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" @@ -8135,17 +8600,12 @@ ms@2.1.3, ms@^2.0.0, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -multicast-dns-service-types@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" - integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= - -multicast-dns@^6.0.1: - version "6.2.3" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" - integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== +multicast-dns@^7.2.4: + version "7.2.4" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.4.tgz#cf0b115c31e922aeb20b64e6556cbeb34cf0dd19" + integrity sha512-XkCYOU+rr2Ft3LI6w4ye51M3VK31qJXFIxu0XLw169PtKG0Zx47OrXeVW/GCYOfpC9s1yyyf1S+L8/4LY0J9Zw== dependencies: - dns-packet "^1.3.1" + dns-packet "^5.2.2" thunky "^1.0.2" mute-stream@0.0.8: @@ -8210,10 +8670,10 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -node-forge@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" - integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== node-gyp@^9.0.0: version "9.0.0" @@ -8241,6 +8701,11 @@ node-releases@^2.0.2: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01" integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg== +node-releases@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.4.tgz#f38252370c43854dc48aa431c766c6c398f40476" + integrity sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ== + node-watch@^0.7.2: version "0.7.3" resolved "https://registry.yarnpkg.com/node-watch/-/node-watch-0.7.3.tgz#6d4db88e39c8d09d3ea61d6568d80e5975abc7ab" @@ -8323,32 +8788,32 @@ npm-bundled@^1.1.1, npm-bundled@^1.1.2: dependencies: npm-normalize-package-bin "^1.0.1" -npm-check-updates@^12.5.4: - version "12.5.4" - resolved "https://registry.yarnpkg.com/npm-check-updates/-/npm-check-updates-12.5.4.tgz#c783b9ec6e27508a91c97d343f7714f1b5e43ec4" - integrity sha512-4+27zaTdieWgvPLaCZ/A6Q2WC1cYVcrc2SqVmLFYgkWBrKw1QkwpeV16FSvkFGZr3OdFyr7Dpjw8JRn4H2QxFw== +npm-check-updates@^12.5.11: + version "12.5.11" + resolved "https://registry.yarnpkg.com/npm-check-updates/-/npm-check-updates-12.5.11.tgz#c594902b21af8c251a5ebf12686143b0d2f06356" + integrity sha512-uS3yYYK/F1VvZlJRymuCkq+MY2R7v/WlORo5WPUTYx+1OwkqeDMC/CEEGfCN7ATwT2M+JxVVKk9Gq/TGiZjJOw== dependencies: chalk "^4.1.2" cint "^8.2.1" cli-table "^0.3.11" - commander "^9.0.0" + commander "^9.1.0" fast-memoize "^2.5.2" find-up "5.0.0" fp-and-or "^0.1.3" get-stdin "^8.0.0" globby "^11.0.4" - hosted-git-info "^4.1.0" + hosted-git-info "^5.0.0" json-parse-helpfulerror "^1.0.3" jsonlines "^0.1.1" libnpmconfig "^1.2.1" lodash "^4.17.21" minimatch "^5.0.1" p-map "^4.0.0" - pacote "^13.0.3" + pacote "^13.0.5" parse-github-url "^1.0.2" progress "^2.0.3" prompts "^2.4.2" - rc-config-loader "^4.0.0" + rc-config-loader "^4.1.0" remote-git-tags "^3.0.0" rimraf "^3.0.2" semver "^7.3.5" @@ -8388,13 +8853,13 @@ npm-package-arg@^9.0.1: semver "^7.3.5" validate-npm-package-name "^3.0.0" -npm-packlist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-4.0.0.tgz#ba54713f8ee2ad919a6dc9f1b9ec7aa291466703" - integrity sha512-gL6XC/iw9YSmqArmZOGSkyy+yIZf2f7uH0p4Vmxef/irn73vd9/rDkCtvm+a9rh/QK2xGYfCAMOghM06ymzC0A== +npm-packlist@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-5.0.2.tgz#a5eb2503faec92ad6853a2bbb2231dced6cfc549" + integrity sha512-jLhcNisUgpz6v2KC75qSeEYAM8UBMYjQ2OhlCOJjB4Ovu7XXnD25UqZ6hOQNeGShL/2ju3LL2E/zBbsuzkIQ8w== dependencies: - glob "^7.2.0" - ignore-walk "^4.0.1" + glob "^8.0.1" + ignore-walk "^5.0.1" npm-bundled "^1.1.2" npm-normalize-package-bin "^1.0.1" @@ -8550,6 +9015,13 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -8646,18 +9118,6 @@ p-cancelable@^1.0.0: resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== -p-event@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" - integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== - dependencies: - p-timeout "^3.1.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -8727,13 +9187,6 @@ p-retry@^4.5.0: "@types/retry" "^0.12.0" retry "^0.13.1" -p-timeout@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" - integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== - dependencies: - p-finally "^1.0.0" - p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" @@ -8754,14 +9207,14 @@ package-json@^6.3.0: registry-url "^5.0.0" semver "^6.2.0" -pacote@^13.0.3: - version "13.0.5" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-13.0.5.tgz#d6f370b11112492d8257ae1178a003b36d4bb261" - integrity sha512-6CYfot3/rUAn3qqzF2d/jrrXm5HlBtvaSgfmg0VtOUAdJ8fbSq21BJwftMGArkL71yXHIbUJ7Bt5B04547HELA== +pacote@^13.0.5: + version "13.2.0" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-13.2.0.tgz#420b9b4971c3e937721c15a752748bc77da45a41" + integrity sha512-IT4/xHT8eLi4cJdKSGCuqooWp2YwRP5OgrQypbBlLG8Ubzw+h7s57QbrA2SegQcdGefD81ZvuI+aL0JlfFcPCA== dependencies: "@npmcli/git" "^3.0.0" "@npmcli/installed-package-contents" "^1.0.7" - "@npmcli/promise-spawn" "^1.2.0" + "@npmcli/promise-spawn" "^3.0.0" "@npmcli/run-script" "^3.0.1" cacache "^16.0.0" chownr "^2.0.0" @@ -8770,7 +9223,7 @@ pacote@^13.0.3: minipass "^3.1.6" mkdirp "^1.0.4" npm-package-arg "^9.0.0" - npm-packlist "^4.0.0" + npm-packlist "^5.0.0" npm-pick-manifest "^7.0.0" npm-registry-fetch "^13.0.1" proc-log "^2.0.0" @@ -8778,7 +9231,7 @@ pacote@^13.0.3: read-package-json "^5.0.0" read-package-json-fast "^2.0.3" rimraf "^3.0.2" - ssri "^8.0.1" + ssri "^9.0.0" tar "^6.1.11" pako@~1.0.5: @@ -8935,7 +9388,7 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -9070,10 +9523,10 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.1.tgz#d472797e0d7461605c1609808e27b80c0f9cfe17" - integrity sha512-8UVbTBYGwN37Bs9LERmxCPjdvPxlEowx2urIL6urHzdb3SDq4B/Z6xLFCblrSnE4iKWcS6ziJ3aOYrc1kz/E2A== +prettier@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032" + integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew== pretty-error@^4.0.0: version "4.0.0" @@ -9092,6 +9545,16 @@ pretty-format@^27.5.1: ansi-styles "^5.0.0" react-is "^17.0.1" +pretty-format@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.0.2.tgz#6a24d71cbb61a5e5794ba7513fe22101675481bc" + integrity sha512-UmGZ1IERwS3yY35LDMTaBUYI1w4udZDdJGGT/DqQeKG9ZLDn7/K2Jf/JtYSRiHCCKMHvUA+zsEGSmHdpaVp1yw== + dependencies: + "@jest/schemas" "^28.0.2" + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^18.0.0" + proc-log@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-2.0.0.tgz#25f8cb346a5d08e27f2422b3ca6ba8379bcbf8ba" @@ -9203,18 +9666,18 @@ q@^1.5.1: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= -qs@6.9.7: - version "6.9.7" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe" - integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== - -qs@^6.4.0: +qs@6.10.3, qs@^6.4.0: version "6.10.3" resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== dependencies: side-channel "^1.0.4" +qs@6.9.7: + version "6.9.7" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe" + integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== + querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" @@ -9272,10 +9735,20 @@ raw-body@2.4.3: iconv-lite "0.4.24" unpipe "1.0.0" -rc-config-loader@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/rc-config-loader/-/rc-config-loader-4.0.0.tgz#144cf31961c9f8ebcf252bd9c263fd40d62bd387" - integrity sha512-//LRTblJEcqbmmro1GCmZ39qZXD+JqzuD8Y5/IZU3Dhp3A1Yr0Xn68ks8MQ6qKfKvYCWDveUmRDKDA40c+sCXw== +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc-config-loader@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/rc-config-loader/-/rc-config-loader-4.1.0.tgz#208e797d773a2203473df10496cd75b5fd93740e" + integrity sha512-aW+kX4qy0CiM9L4fG4Us3oEOpIrOrXzWykAn+xldD07Y9PXWjTH744oHbv0Kc9ZwWaylw3jMjxaf14RgStrNrA== dependencies: debug "^4.1.1" js-yaml "^4.0.0" @@ -9321,10 +9794,10 @@ 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.16.2: - version "11.16.2" - resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.16.2.tgz#650b18c12a624057ee2651ba4b4a989b526be554" - integrity sha512-1iuZduvARUelL5ux663FvIoDZExwFO+9QtRAAt4uvs1/aun4cUZt8XBrVg7iiDgNls9cOSORAhE7Ri5KA9RMvg== +react-i18next@^11.16.7: + version "11.16.7" + resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.16.7.tgz#8d0680b7f4c8e43f59996336b7183ad576a28df7" + integrity sha512-7yotILJLnKfvUfrl/nt9eK9vFpVFjZPLWAwBzWL6XppSZZEvlmlKk0GBGDCAPfLfs8oND7WAbry8wGzdoiW5Nw== dependencies: "@babel/runtime" "^7.14.5" html-escaper "^2.0.2" @@ -9340,6 +9813,11 @@ react-is@^16.12.0, react-is@^16.13.1, react-is@^16.3.2, react-is@^16.6.0, react- resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-is@^18.0.0: + version "18.1.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67" + integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== + react-redux@>=5.0.7, react-redux@^7.2.6: version "7.2.6" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.6.tgz#49633a24fe552b5f9caf58feb8a138936ddfe9aa" @@ -9352,7 +9830,7 @@ react-redux@>=5.0.7, react-redux@^7.2.6: prop-types "^15.7.2" react-is "^17.0.2" -react-router-dom@^5.3.0: +react-router-dom@5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.0.tgz#da1bfb535a0e89a712a93b97dd76f47ad1f32363" integrity sha512-ObVBLjUZsphUUMVycibxgMdh5jJ1e3o+KpAZBVeHcNQZ4W+uUGGWsokurzlF4YOldQYRQL4y6yFRWM4m3svmuQ== @@ -9365,7 +9843,7 @@ react-router-dom@^5.3.0: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react-router@5.2.1, react-router@^5.2.1: +react-router@5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.1.tgz#4d2e4e9d5ae9425091845b8dbc6d9d276239774d" integrity sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ== @@ -9381,6 +9859,22 @@ react-router@5.2.1, react-router@^5.2.1: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" +react-router@5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.3.1.tgz#b13e84a016c79b9e80dde123ca4112c4f117e3cf" + integrity sha512-v+zwjqb7bakqgF+wMVKlAPTca/cEmPOvQ9zt7gpSNyPXau1+0qvuYZ5BWzzNDP1y6s15zDwgb9rPN63+SIniRQ== + dependencies: + "@babel/runtime" "^7.12.13" + history "^4.9.0" + hoist-non-react-statics "^3.1.0" + loose-envify "^1.3.1" + mini-create-react-context "^0.4.0" + path-to-regexp "^1.7.0" + prop-types "^15.6.2" + react-is "^16.6.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + react-shallow-renderer@^16.13.1: version "16.14.1" resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.14.1.tgz#bf0d02df8a519a558fd9b8215442efa5c840e124" @@ -9554,13 +10048,20 @@ redux-thunk@^2.4.1: resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.1.tgz#0dd8042cf47868f4b29699941de03c9301a75714" integrity sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q== -redux@>=4.0.5, redux@^4.0.0, redux@^4.1.2: +redux@>=4.0.5, redux@^4.0.0: version "4.1.2" resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.2.tgz#140f35426d99bb4729af760afcf79eaaac407104" integrity sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw== dependencies: "@babel/runtime" "^7.9.2" +redux@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.0.tgz#46f10d6e29b6666df758780437651eeb2b969f13" + integrity sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA== + dependencies: + "@babel/runtime" "^7.9.2" + regenerate-unicode-properties@^10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" @@ -9585,7 +10086,7 @@ regenerator-transform@^0.14.2: dependencies: "@babel/runtime" "^7.8.4" -regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1: +regexp.prototype.flags@^1.3.1: version "1.4.1" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307" integrity sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ== @@ -9610,11 +10111,6 @@ regexpu-core@^5.0.1: unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.0.0" -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" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" @@ -9940,12 +10436,12 @@ select-hose@^2.0.0: resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= -selfsigned@^1.10.11: - version "1.10.14" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.14.tgz#ee51d84d9dcecc61e07e4aba34f229ab525c1574" - integrity sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA== +selfsigned@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" + integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ== dependencies: - node-forge "^0.10.0" + node-forge "^1" semver-diff@^3.1.1: version "3.1.1" @@ -9981,6 +10477,13 @@ semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@~7.3.2: dependencies: lru-cache "^6.0.0" +semver@^7.3.7: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + send@0.17.2: version "0.17.2" resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" @@ -10000,6 +10503,25 @@ send@0.17.2: range-parser "~1.2.1" statuses "~1.5.0" +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + serialize-javascript@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -10030,6 +10552,16 @@ serve-static@1.14.2: parseurl "~1.3.3" send "0.17.2" +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -10299,6 +10831,13 @@ ssri@^8.0.1: dependencies: minipass "^3.1.1" +ssri@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.0.tgz#70ad90e339eb910f1a7ff1dcf4afc268326c4547" + integrity sha512-Y1Z6J8UYnexKFN1R/hxUaYoY2LVdKEzziPmVAFKiKX8fiwvCJTVzn/xYE9TEWod5OVyNfIHHuVfIEuBClL/uJQ== + dependencies: + minipass "^3.1.1" + stack-generator@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36" @@ -10361,6 +10900,11 @@ standard-version@^9.3.2: stringify-package "^1.0.1" yargs "^16.0.0" +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + "statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" @@ -10478,7 +11022,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.0, strip-ansi@^7.0.1: +strip-ansi@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== @@ -11541,7 +12085,7 @@ webpack-cli@^4.8.0: rechoir "^0.7.0" webpack-merge "^5.7.3" -webpack-dev-middleware@^5.2.1: +webpack-dev-middleware@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz#aa079a8dedd7e58bfeab358a9af7dab304cee57f" integrity sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg== @@ -11552,36 +12096,40 @@ webpack-dev-middleware@^5.2.1: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.3.1.tgz#759d3337f0fbea297fbd1e433ab04ccfc000076b" - integrity sha512-qNXQCVYo1kYhH9pgLtm8LRNkXX3XzTfHSj/zqzaqYzGPca+Qjr+81wj1jgPMCHhIhso9WEQ+kX9z23iG9PzQ7w== - dependencies: +webpack-dev-server@4.8.1: + version "4.8.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.8.1.tgz#58f9d797710d6e25fa17d6afab8708f958c11a29" + integrity sha512-dwld70gkgNJa33czmcj/PlKY/nOy/BimbrgZRaR9vDATBQAYgLzggR0nxDtPLJiLrMgZwbE6RRfJ5vnBBasTyg== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.1" ansi-html-community "^0.0.8" - bonjour "^3.5.0" - chokidar "^3.5.1" + bonjour-service "^1.0.11" + chokidar "^3.5.3" colorette "^2.0.10" compression "^1.7.4" connect-history-api-fallback "^1.6.0" - del "^6.0.0" - express "^4.17.1" + default-gateway "^6.0.3" + express "^4.17.3" graceful-fs "^4.2.6" html-entities "^2.3.2" - http-proxy-middleware "^2.0.0" - internal-ip "^6.2.0" + http-proxy-middleware "^2.0.3" ipaddr.js "^2.0.1" open "^8.0.9" p-retry "^4.5.0" portfinder "^1.0.28" - schema-utils "^3.1.0" - selfsigned "^1.10.11" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.0.1" serve-index "^1.9.1" sockjs "^0.3.21" spdy "^4.0.2" - strip-ansi "^7.0.0" - url "^0.11.0" - webpack-dev-middleware "^5.2.1" - ws "^8.1.0" + webpack-dev-middleware "^5.3.1" + ws "^8.4.2" webpack-merge@^5.7.3: version "5.8.0" @@ -11750,6 +12298,22 @@ winston@^3.3.3: triple-beam "^1.3.0" winston-transport "^4.5.0" +winston@^3.6.0: + version "3.7.2" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.7.2.tgz#95b4eeddbec902b3db1424932ac634f887c400b1" + integrity sha512-QziIqtojHBoyzUOdQvQiar1DH0Xp9nF1A1y7NVy2DGEsz82SBDtOalS0ulTRGVT14xPX3WRWkCsdcJKqNflKng== + dependencies: + "@dabh/diagnostics" "^2.0.2" + async "^3.2.3" + is-stream "^2.0.0" + logform "^2.4.0" + one-time "^1.0.0" + readable-stream "^3.4.0" + safe-stable-stringify "^2.3.1" + stack-trace "0.0.x" + triple-beam "^1.3.0" + winston-transport "^4.5.0" + word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" @@ -11793,6 +12357,14 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" +write-file-atomic@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.1.tgz#9faa33a964c1c85ff6f849b80b42a88c2c537c8f" + integrity sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + write-file-webpack-plugin@^4.5.1: version "4.5.1" resolved "https://registry.yarnpkg.com/write-file-webpack-plugin/-/write-file-webpack-plugin-4.5.1.tgz#aeeb68889194da5ec8a864667d46da9e00ee92d5" @@ -11811,10 +12383,10 @@ ws@^7.3.1, ws@^7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== -ws@^8.1.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" - integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== +ws@^8.4.2: + version "8.6.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.6.0.tgz#e5e9f1d9e7ff88083d0c0dd8281ea662a42c9c23" + integrity sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw== xdg-basedir@^4.0.0: version "4.0.0" @@ -11895,6 +12467,19 @@ yargs@^17.2.1: y18n "^5.0.5" yargs-parser "^21.0.0" +yargs@^17.3.1: + version "17.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.4.1.tgz#ebe23284207bb75cee7c408c33e722bfb27b5284" + integrity sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.0.0" + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"