diff --git a/.env.dev.example b/.env.dev.example
index ad6128a2..8f7f1ad6 100644
--- a/.env.dev.example
+++ b/.env.dev.example
@@ -14,11 +14,6 @@ TWILIO_VERIFY_SERVICE_SID=
TWILIO_AUTH_TOKEN=
TWILIO_NUMBER=
-SENDGRID_SECRET_KEY=
-SENDGRID_INBOUND_EMAIL_DOMAIN=
-SENDGRID_API_KEY=
-SENDGRID_FROM_EMAIL=
-
DJANGO_SETTINGS_MODULE=settings.dev
SECRET_KEY=jkashdkjashdkjh
BASE_URL=http://localhost:8080
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e4b913c0..5f816a2e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -27,6 +27,22 @@ jobs:
run: |
pre-commit run --all-files
+ test:
+ runs-on: ubuntu-latest
+ container: python:3.9
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v3
+ with:
+ node-version: 14.17.0
+ - name: Unit Testing Frontend
+ run: |
+ pip install $(grep "pre-commit" engine/requirements.txt)
+ npm install -g yarn
+ cd grafana-plugin/
+ yarn --network-timeout 500000
+ yarn test
+
test-technical-documentation:
runs-on: ubuntu-latest
steps:
@@ -124,3 +140,17 @@ jobs:
cd engine/
pip install -r requirements.txt
pytest --ds=settings.ci-test -x
+
+ docker-build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Test docker build (no push)
+ id: docker_build
+ uses: docker/build-push-action@v2
+ with:
+ context: ./engine
+ file: ./engine/Dockerfile
+ push: false
+ - name: Image digest
+ run: echo ${{ steps.docker_build.outputs.digest }}
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index e2dbf2de..f61d3a85 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -23,16 +23,26 @@ repos:
- flake8-tidy-imports
- repo: https://github.com/pre-commit/mirrors-eslint
- rev: v7.21.0
+ rev: v8.25.0
hooks:
- id: eslint
- entry: bash -c 'cd grafana-plugin && eslint --fix ${@/grafana-plugin\//}' --
+ entry: bash -c 'cd grafana-plugin && eslint --max-warnings=0 --fix ${@/grafana-plugin\//}' --
types: [file]
files: ^grafana-plugin/src/.*\.(js|jsx|ts|tsx)$
additional_dependencies:
- - eslint@7.21.0
+ - eslint@^8.25.0
- eslint-plugin-import@^2.25.4
- eslint-plugin-rulesdir@^0.2.1
+ - "@grafana/eslint-config@^5.0.0"
+
+ - repo: https://github.com/pre-commit/mirrors-prettier
+ rev: "v2.7.1"
+ hooks:
+ - id: prettier
+ types_or: [css, javascript, jsx, ts, tsx, json]
+ files: ^grafana-plugin/src
+ additional_dependencies:
+ - prettier@^2.7.1
- repo: https://github.com/thibaudcolas/pre-commit-stylelint
rev: v13.13.1
@@ -43,4 +53,6 @@ repos:
files: ^grafana-plugin/src/.*\.css$
additional_dependencies:
- stylelint@^13.13.1
+ - stylelint-prettier@^2.0.0
- stylelint-config-standard@^22.0.0
+ - stylelint-config-prettier@^9.0.3
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 01e27157..6794d33e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
# Change Log
+## v1.0.42 (2022-10-24)
+- Fix posting resolution notes to Slack
+
+## v1.0.41 (2022-10-24)
+- Add personal email notifications
+- Bug fixes
+
## v1.0.40 (2022-10-05)
- Improved database and celery backends support
- Added script to import PagerDuty users to Grafana
diff --git a/DEVELOPER.md b/DEVELOPER.md
index 347f7e95..e65f186a 100644
--- a/DEVELOPER.md
+++ b/DEVELOPER.md
@@ -2,6 +2,7 @@
- [Code style](#code-style)
- [Backend setup](#backend-setup)
- [Frontend setup](#frontend-setup)
+ - [Setup using Makefile](#setup-using-makefile)
- [Slack application setup](#slack-application-setup)
- [Update drone build](#update-drone-build)
- [Troubleshooting](#troubleshooting)
@@ -142,6 +143,45 @@ extra_hosts:
```
+### Setup using Makefile
+
+- Make sure you have `make` installed
+- Backend setup:
+ - Run stateful services:
+ `$ make docker-services-start`
+
+ (you can change your preferred docker file by defining the `DOCKER_FILE` env variable)
+
+ - Setup environment:
+ `$ make bootstrap`
+
+ (you can change your preferred directory for your Python virtualenv by defining the `ENV_DIR` env variable)
+
+ - Start the server (this will run bootstrap if needed and apply db migrations):
+ `$ make run`
+
+ - Start the celery workers:
+ `$ make start-celery`
+
+ - Start celery beat:
+ `$ make start-celery-beat`
+
+- Frontend:
+ - Build and watch plugin:
+ `$ make watch-plugin`
+
+ - Generate invitation token:
+ `$ make manage ARGS="issue_invite_for_the_frontend --override"`
+
+ - Follow instructions above to setup plugin (see steps 5 and 6)
+
+- Other useful targets:
+ - `$ make shell` (open Django shell)
+ - `$ make dbshell` (open DB shell)
+ - `$ make test` (run tests)
+ - `$ make lint` (run lint checks)
+
+
### Slack application setup
For Slack app configuration check our docs: https://grafana.com/docs/grafana-cloud/oncall/open-source/#slack-setup
diff --git a/README.md b/README.md
index 51eaa6b1..08019328 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ Developer-friendly incident response with brilliant Slack integration.
We prepared multiple environments: [production](https://grafana.com/docs/grafana-cloud/oncall/open-source/#production-environment), [developer](DEVELOPER.md) and hobby:
-1. Download docker-compose.yaml:
+1. Download [`docker-compose.yml`](docker-compose.yml):
```bash
curl -fsSL https://raw.githubusercontent.com/grafana/oncall/dev/docker-compose.yml -o docker-compose.yml
@@ -31,9 +31,7 @@ curl -fsSL https://raw.githubusercontent.com/grafana/oncall/dev/docker-compose.y
```bash
echo "DOMAIN=http://localhost:8080
COMPOSE_PROFILES=with_grafana # Remove this line if you want to use existing grafana
-SECRET_KEY=my_random_secret_must_be_more_than_32_characters_long
-RABBITMQ_PASSWORD=rabbitmq_secret_pw
-MYSQL_PASSWORD=mysql_secret_pw" > .env
+SECRET_KEY=my_random_secret_must_be_more_than_32_characters_long" > .env
```
3. Launch services:
diff --git a/docker-compose-mysql-rabbitmq.yml b/docker-compose-mysql-rabbitmq.yml
new file mode 100644
index 00000000..a77f5d25
--- /dev/null
+++ b/docker-compose-mysql-rabbitmq.yml
@@ -0,0 +1,162 @@
+version: "3.8"
+
+x-environment:
+ &oncall-environment
+ BASE_URL: $DOMAIN
+ SECRET_KEY: $SECRET_KEY
+ RABBITMQ_USERNAME: "rabbitmq"
+ RABBITMQ_PASSWORD: $RABBITMQ_PASSWORD
+ RABBITMQ_HOST: "rabbitmq"
+ RABBITMQ_PORT: "5672"
+ RABBITMQ_DEFAULT_VHOST: "/"
+ MYSQL_PASSWORD: $MYSQL_PASSWORD
+ MYSQL_DB_NAME: oncall_hobby
+ MYSQL_USER: ${MYSQL_USER:-root}
+ MYSQL_HOST: ${MYSQL_HOST:-mysql}
+ MYSQL_PORT: 3306
+ REDIS_URI: redis://redis:6379/0
+ DJANGO_SETTINGS_MODULE: settings.hobby
+ CELERY_WORKER_QUEUE: "default,critical,long,slack,telegram,webhook,retry,celery"
+ CELERY_WORKER_CONCURRENCY: "1"
+ CELERY_WORKER_MAX_TASKS_PER_CHILD: "100"
+ CELERY_WORKER_SHUTDOWN_INTERVAL: "65m"
+ CELERY_WORKER_BEAT_ENABLED: "True"
+
+services:
+ engine:
+ image: grafana/oncall
+ restart: always
+ ports:
+ - "8080:8080"
+ command: >
+ sh -c "uwsgi --ini uwsgi.ini"
+ environment: *oncall-environment
+ depends_on:
+ mysql:
+ condition: service_healthy
+ oncall_db_migration:
+ condition: service_completed_successfully
+ rabbitmq:
+ condition: service_healthy
+ redis:
+ condition: service_started
+
+ celery:
+ image: grafana/oncall
+ restart: always
+ command: sh -c "./celery_with_exporter.sh"
+ environment: *oncall-environment
+ depends_on:
+ mysql:
+ condition: service_healthy
+ oncall_db_migration:
+ condition: service_completed_successfully
+ rabbitmq:
+ condition: service_healthy
+ redis:
+ condition: service_started
+
+ oncall_db_migration:
+ image: grafana/oncall
+ command: python manage.py migrate --noinput
+ environment: *oncall-environment
+ depends_on:
+ mysql:
+ condition: service_healthy
+ rabbitmq:
+ condition: service_healthy
+
+ mysql:
+ image: mysql:5.7
+ platform: linux/x86_64
+ command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
+ restart: always
+ expose:
+ - 3306
+ volumes:
+ - dbdata:/var/lib/mysql
+ environment:
+ MYSQL_ROOT_PASSWORD: $MYSQL_PASSWORD
+ MYSQL_DATABASE: oncall_hobby
+ deploy:
+ resources:
+ limits:
+ memory: 500m
+ cpus: '0.5'
+ healthcheck:
+ test: "mysql -uroot -p$MYSQL_PASSWORD oncall_hobby -e 'select 1'"
+ timeout: 20s
+ retries: 10
+
+ redis:
+ image: redis
+ restart: always
+ expose:
+ - 6379
+ deploy:
+ resources:
+ limits:
+ memory: 100m
+ cpus: '0.1'
+
+ rabbitmq:
+ image: "rabbitmq:3.7.15-management"
+ restart: always
+ hostname: rabbitmq
+ volumes:
+ - rabbitmqdata:/var/lib/rabbitmq
+ environment:
+ RABBITMQ_DEFAULT_USER: "rabbitmq"
+ RABBITMQ_DEFAULT_PASS: $RABBITMQ_PASSWORD
+ RABBITMQ_DEFAULT_VHOST: "/"
+ deploy:
+ resources:
+ limits:
+ memory: 1000m
+ cpus: '0.5'
+ healthcheck:
+ test: rabbitmq-diagnostics -q ping
+ interval: 30s
+ timeout: 30s
+ retries: 3
+
+ mysql_to_create_grafana_db:
+ image: mysql:5.7
+ platform: linux/x86_64
+ command: bash -c "mysql -h ${MYSQL_HOST:-mysql} -uroot -p${MYSQL_PASSWORD:?err} -e 'CREATE DATABASE IF NOT EXISTS grafana CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'"
+ depends_on:
+ mysql:
+ condition: service_healthy
+ profiles:
+ - with_grafana
+
+ grafana:
+ image: "grafana/grafana:9.0.0-beta3"
+ restart: always
+ ports:
+ - "3000:3000"
+ environment:
+ GF_DATABASE_TYPE: mysql
+ GF_DATABASE_HOST: ${MYSQL_HOST:-mysql}
+ GF_DATABASE_USER: ${MYSQL_USER:-root}
+ GF_DATABASE_PASSWORD: ${MYSQL_PASSWORD:?err}
+ GF_SECURITY_ADMIN_USER: ${GRAFANA_USER:-admin}
+ GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD:-admin}
+ GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS: grafana-oncall-app
+ GF_INSTALL_PLUGINS: grafana-oncall-app
+ deploy:
+ resources:
+ limits:
+ memory: 500m
+ cpus: '0.5'
+ depends_on:
+ mysql_to_create_grafana_db:
+ condition: service_completed_successfully
+ mysql:
+ condition: service_healthy
+ profiles:
+ - with_grafana
+
+volumes:
+ dbdata:
+ rabbitmqdata:
diff --git a/docker-compose.yml b/docker-compose.yml
index a77f5d25..070f6f51 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -2,18 +2,10 @@ version: "3.8"
x-environment:
&oncall-environment
+ DATABASE_TYPE: sqlite3
+ BROKER_TYPE: redis
BASE_URL: $DOMAIN
SECRET_KEY: $SECRET_KEY
- RABBITMQ_USERNAME: "rabbitmq"
- RABBITMQ_PASSWORD: $RABBITMQ_PASSWORD
- RABBITMQ_HOST: "rabbitmq"
- RABBITMQ_PORT: "5672"
- RABBITMQ_DEFAULT_VHOST: "/"
- MYSQL_PASSWORD: $MYSQL_PASSWORD
- MYSQL_DB_NAME: oncall_hobby
- MYSQL_USER: ${MYSQL_USER:-root}
- MYSQL_HOST: ${MYSQL_HOST:-mysql}
- MYSQL_PORT: 3306
REDIS_URI: redis://redis:6379/0
DJANGO_SETTINGS_MODULE: settings.hobby
CELERY_WORKER_QUEUE: "default,critical,long,slack,telegram,webhook,retry,celery"
@@ -31,104 +23,54 @@ services:
command: >
sh -c "uwsgi --ini uwsgi.ini"
environment: *oncall-environment
+ volumes:
+ - oncall_data:/var/lib/oncall
depends_on:
- mysql:
- condition: service_healthy
oncall_db_migration:
condition: service_completed_successfully
- rabbitmq:
- condition: service_healthy
redis:
- condition: service_started
+ condition: service_healthy
celery:
image: grafana/oncall
restart: always
command: sh -c "./celery_with_exporter.sh"
environment: *oncall-environment
+ volumes:
+ - oncall_data:/var/lib/oncall
depends_on:
- mysql:
- condition: service_healthy
oncall_db_migration:
condition: service_completed_successfully
- rabbitmq:
- condition: service_healthy
redis:
- condition: service_started
+ condition: service_healthy
oncall_db_migration:
image: grafana/oncall
command: python manage.py migrate --noinput
environment: *oncall-environment
- depends_on:
- mysql:
- condition: service_healthy
- rabbitmq:
- condition: service_healthy
-
- mysql:
- image: mysql:5.7
- platform: linux/x86_64
- command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
- restart: always
- expose:
- - 3306
volumes:
- - dbdata:/var/lib/mysql
- environment:
- MYSQL_ROOT_PASSWORD: $MYSQL_PASSWORD
- MYSQL_DATABASE: oncall_hobby
- deploy:
- resources:
- limits:
- memory: 500m
- cpus: '0.5'
- healthcheck:
- test: "mysql -uroot -p$MYSQL_PASSWORD oncall_hobby -e 'select 1'"
- timeout: 20s
- retries: 10
+ - oncall_data:/var/lib/oncall
+ depends_on:
+ redis:
+ condition: service_healthy
redis:
image: redis
restart: always
expose:
- 6379
- deploy:
- resources:
- limits:
- memory: 100m
- cpus: '0.1'
-
- rabbitmq:
- image: "rabbitmq:3.7.15-management"
- restart: always
- hostname: rabbitmq
volumes:
- - rabbitmqdata:/var/lib/rabbitmq
- environment:
- RABBITMQ_DEFAULT_USER: "rabbitmq"
- RABBITMQ_DEFAULT_PASS: $RABBITMQ_PASSWORD
- RABBITMQ_DEFAULT_VHOST: "/"
+ - redis_data:/data
deploy:
resources:
limits:
- memory: 1000m
+ memory: 500m
cpus: '0.5'
healthcheck:
- test: rabbitmq-diagnostics -q ping
- interval: 30s
- timeout: 30s
- retries: 3
-
- mysql_to_create_grafana_db:
- image: mysql:5.7
- platform: linux/x86_64
- command: bash -c "mysql -h ${MYSQL_HOST:-mysql} -uroot -p${MYSQL_PASSWORD:?err} -e 'CREATE DATABASE IF NOT EXISTS grafana CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'"
- depends_on:
- mysql:
- condition: service_healthy
- profiles:
- - with_grafana
+ test: ["CMD", "redis-cli", "ping"]
+ timeout: 5s
+ interval: 5s
+ retries: 10
grafana:
image: "grafana/grafana:9.0.0-beta3"
@@ -136,27 +78,21 @@ services:
ports:
- "3000:3000"
environment:
- GF_DATABASE_TYPE: mysql
- GF_DATABASE_HOST: ${MYSQL_HOST:-mysql}
- GF_DATABASE_USER: ${MYSQL_USER:-root}
- GF_DATABASE_PASSWORD: ${MYSQL_PASSWORD:?err}
GF_SECURITY_ADMIN_USER: ${GRAFANA_USER:-admin}
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD:-admin}
GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS: grafana-oncall-app
GF_INSTALL_PLUGINS: grafana-oncall-app
+ volumes:
+ - grafana_data:/var/lib/grafana
deploy:
resources:
limits:
memory: 500m
cpus: '0.5'
- depends_on:
- mysql_to_create_grafana_db:
- condition: service_completed_successfully
- mysql:
- condition: service_healthy
profiles:
- with_grafana
volumes:
- dbdata:
- rabbitmqdata:
+ grafana_data:
+ oncall_data:
+ redis_data:
diff --git a/docs/sources/open-source/_index.md b/docs/sources/open-source/_index.md
index b2e6c1df..fdc3a1a8 100644
--- a/docs/sources/open-source/_index.md
+++ b/docs/sources/open-source/_index.md
@@ -187,3 +187,14 @@ Grafana OnCall supports Twilio SMS and phone call notifications delivery. If you
1. Set `GRAFANA_CLOUD_NOTIFICATIONS_ENABLED` as **False** to ensure the Grafana OSS <-> Cloud connector is disabled.
1. From your **OnCall** environment, select **Env Variables** and configure all variables starting with `TWILIO_`.
+
+## Email Setup
+Grafana OnCall is capable of sending emails using SMTP as a user notification step. To setup email notifications, populate the following env variables with your SMTP server credentials:
+
+- `EMAIL_HOST` - SMTP server host
+- `EMAIL_HOST_USER` - SMTP server user
+- `EMAIL_HOST_PASSWORD` - SMTP server password
+- `EMAIL_PORT` (default is `587`) - SMTP server port
+- `EMAIL_USE_TLS` (default is `True`) - to enable/disable TLS
+
+After enabling the email integration, it will be possible to use the `Notify by email` notification step in user settings.
diff --git a/engine/apps/alerts/incident_appearance/renderers/email_renderer.py b/engine/apps/alerts/incident_appearance/renderers/email_renderer.py
deleted file mode 100644
index eb18e190..00000000
--- a/engine/apps/alerts/incident_appearance/renderers/email_renderer.py
+++ /dev/null
@@ -1,42 +0,0 @@
-from django.template.loader import render_to_string
-
-from apps.alerts.incident_appearance.renderers.base_renderer import AlertBaseRenderer, AlertGroupBaseRenderer
-from apps.alerts.incident_appearance.renderers.constants import DEFAULT_BACKUP_TITLE
-from apps.alerts.incident_appearance.templaters import AlertEmailTemplater
-from common.utils import str_or_backup
-
-
-class AlertEmailRenderer(AlertBaseRenderer):
- @property
- def templater_class(self):
- return AlertEmailTemplater
-
-
-class AlertGroupEmailRenderer(AlertGroupBaseRenderer):
- @property
- def alert_renderer_class(self):
- return AlertEmailRenderer
-
- def render(self, limit_notification=False):
- subject = "You are invited to check an incident from Grafana OnCall"
- templated_alert = self.alert_renderer.templated_alert
-
- title_fallback = (
- f"#{self.alert_group.inside_organization_number} "
- f"{DEFAULT_BACKUP_TITLE} via {self.alert_group.channel.verbal_name}"
- )
-
- content = render_to_string(
- "email_notification.html",
- {
- "url": self.alert_group.slack_permalink or self.alert_group.web_link,
- "title": str_or_backup(templated_alert.title, title_fallback),
- "message": str_or_backup(templated_alert.message, ""), # not render message it all if smth go wrong
- "amixr_team": self.alert_group.channel.organization,
- "alert_channel": self.alert_group.channel.short_name,
- "limit_notification": limit_notification,
- "emails_left": self.alert_group.channel.organization.emails_left,
- },
- )
-
- return subject, content
diff --git a/engine/apps/alerts/incident_appearance/renderers/telegram_renderer.py b/engine/apps/alerts/incident_appearance/renderers/telegram_renderer.py
index edc89dd4..b3364810 100644
--- a/engine/apps/alerts/incident_appearance/renderers/telegram_renderer.py
+++ b/engine/apps/alerts/incident_appearance/renderers/telegram_renderer.py
@@ -49,8 +49,10 @@ class AlertGroupTelegramRenderer(AlertGroupBaseRenderer):
status_verbose = self.alert_group.get_resolve_text()
elif self.alert_group.acknowledged:
status_verbose = self.alert_group.get_acknowledge_text()
-
- text = f"{status_emoji} #{self.alert_group.inside_organization_number}, {title}\n"
+ # First line in the invisible link with id of organization.
+ # It is needed to add info about organization to the telegram message for the oncall-gateway.
+ text = f" "
+ text += f"{status_emoji} #{self.alert_group.inside_organization_number}, {title}\n"
text += f"{status_verbose}, alerts: {alerts_count_str}\n"
text += f"Source: {self.alert_group.channel.short_name}\n"
text += f"{self.alert_group.web_link}"
diff --git a/engine/apps/alerts/incident_appearance/templaters/__init__.py b/engine/apps/alerts/incident_appearance/templaters/__init__.py
index c34fc370..bff515d4 100644
--- a/engine/apps/alerts/incident_appearance/templaters/__init__.py
+++ b/engine/apps/alerts/incident_appearance/templaters/__init__.py
@@ -1,6 +1,5 @@
from .alert_templater import TemplateLoader # noqa: F401
from .classic_markdown_templater import AlertClassicMarkdownTemplater # noqa: F401
-from .email_templater import AlertEmailTemplater # noqa: F401
from .phone_call_templater import AlertPhoneCallTemplater # noqa: F401
from .slack_templater import AlertSlackTemplater # noqa: F401
from .sms_templater import AlertSmsTemplater # noqa: F401
diff --git a/engine/apps/alerts/incident_appearance/templaters/email_templater.py b/engine/apps/alerts/incident_appearance/templaters/email_templater.py
deleted file mode 100644
index 48870848..00000000
--- a/engine/apps/alerts/incident_appearance/templaters/email_templater.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from apps.alerts.incident_appearance.templaters.alert_templater import AlertTemplater
-
-
-class AlertEmailTemplater(AlertTemplater):
- RENDER_FOR_EMAIL = "email"
-
- def _render_for(self):
- return self.RENDER_FOR_EMAIL
-
- def _postformat(self, templated_alert):
- templated_alert.title = self._slack_format_for_email(templated_alert.title)
- templated_alert.message = self._slack_format_for_email(templated_alert.message)
- return templated_alert
-
- def _slack_format_for_email(self, data):
- sf = self.slack_formatter
- sf.hyperlink_mention_format = "{title} - {url}"
- return sf.format(data)
diff --git a/engine/apps/alerts/incident_log_builder/incident_log_builder.py b/engine/apps/alerts/incident_log_builder/incident_log_builder.py
index ca5ae047..11285ad1 100644
--- a/engine/apps/alerts/incident_log_builder/incident_log_builder.py
+++ b/engine/apps/alerts/incident_log_builder/incident_log_builder.py
@@ -589,9 +589,6 @@ class IncidentLogBuilder:
result += f"call {user_verbal} by phone"
elif notification_policy.notify_by == UserNotificationPolicy.NotificationChannel.TELEGRAM:
result += f"send telegram message to {user_verbal}"
- # TODO: restore email notifications
- # elif notification_policy.notify_by == UserNotificationPolicy.NotificationChannel.EMAIL:
- # result += f"send email to {user_verbal}"
else:
try:
backend_id = UserNotificationPolicy.NotificationChannel(notification_policy.notify_by).name
diff --git a/engine/apps/alerts/integration_options_mixin.py b/engine/apps/alerts/integration_options_mixin.py
index a0a81bab..a747d899 100644
--- a/engine/apps/alerts/integration_options_mixin.py
+++ b/engine/apps/alerts/integration_options_mixin.py
@@ -59,8 +59,6 @@ class IntegrationOptionsMixin:
"web_title",
"web_message",
"web_image_url",
- "email_title",
- "email_message",
"sms_title",
"phone_call_title",
"telegram_title",
diff --git a/engine/apps/alerts/migrations/0005_alertgroup_cached_render_for_web.py b/engine/apps/alerts/migrations/0005_alertgroup_cached_render_for_web.py
index e8ac0970..cff73da3 100644
--- a/engine/apps/alerts/migrations/0005_alertgroup_cached_render_for_web.py
+++ b/engine/apps/alerts/migrations/0005_alertgroup_cached_render_for_web.py
@@ -1,6 +1,6 @@
# Generated by Django 3.2.13 on 2022-07-20 09:04
-from django.db import migrations, models, OperationalError
+from django.db import migrations, models, OperationalError, ProgrammingError
class AddFieldIfNotExists(migrations.AddField):
@@ -14,6 +14,9 @@ class AddFieldIfNotExists(migrations.AddField):
super().database_forwards(app_label, schema_editor, from_state, to_state)
except OperationalError:
pass
+ except ProgrammingError as e: # ignore if the field already exists
+ if "already exists" in str(e):
+ pass
def database_backwards(self, app_label, schema_editor, from_state, to_state):
pass
@@ -27,6 +30,7 @@ class Migration(migrations.Migration):
it will recreate these fields.
"""
+ atomic = False
dependencies = [
('alerts', '0004_auto_20220711_1106'),
]
diff --git a/engine/apps/alerts/models/alert_receive_channel.py b/engine/apps/alerts/models/alert_receive_channel.py
index 60704773..caa79fbf 100644
--- a/engine/apps/alerts/models/alert_receive_channel.py
+++ b/engine/apps/alerts/models/alert_receive_channel.py
@@ -21,7 +21,6 @@ from apps.alerts.integration_options_mixin import IntegrationOptionsMixin
from apps.alerts.models.maintainable_object import MaintainableObject
from apps.alerts.tasks import disable_maintenance, sync_grafana_alerting_contact_points
from apps.base.messaging import get_messaging_backend_from_id
-from apps.base.utils import live_settings
from apps.integrations.metadata import heartbeat
from apps.integrations.tasks import create_alert, create_alertmanager_alerts
from apps.slack.constants import SLACK_RATE_LIMIT_DELAY, SLACK_RATE_LIMIT_TIMEOUT
@@ -162,8 +161,10 @@ class AlertReceiveChannel(IntegrationOptionsMixin, MaintainableObject):
web_message_template = models.TextField(null=True, default=None)
web_image_url_template = models.TextField(null=True, default=None)
- email_title_template = models.TextField(null=True, default=None)
- email_message_template = models.TextField(null=True, default=None)
+ # email related fields are deprecated in favour of messaging backend based templates
+ # these templates are stored in the messaging_backends_templates field
+ email_title_template = models.TextField(null=True, default=None) # deprecated
+ email_message_template = models.TextField(null=True, default=None) # deprecated
telegram_title_template = models.TextField(null=True, default=None)
telegram_message_template = models.TextField(null=True, default=None)
@@ -194,10 +195,6 @@ class AlertReceiveChannel(IntegrationOptionsMixin, MaintainableObject):
"phone_call": {
"title": "phone_call_title_template",
},
- "email": {
- "title": "email_title_template",
- "message": "email_message_template",
- },
"telegram": {
"title": "telegram_title_template",
"message": "telegram_message_template",
@@ -388,10 +385,19 @@ class AlertReceiveChannel(IntegrationOptionsMixin, MaintainableObject):
organization=kwargs["organization"],
integration=kwargs["integration"],
team=kwargs["team"],
+ deleted_at=None,
)
except cls.DoesNotExist:
kwargs.update(defaults)
alert_receive_channel = cls.create(**kwargs)
+ except cls.MultipleObjectsReturned:
+ # general team may inherit integrations from deleted teams
+ alert_receive_channel = cls.objects.filter(
+ organization=kwargs["organization"],
+ integration=kwargs["integration"],
+ team=kwargs["team"],
+ deleted_at=None,
+ ).first()
return alert_receive_channel
@property
@@ -438,7 +444,8 @@ class AlertReceiveChannel(IntegrationOptionsMixin, MaintainableObject):
@property
def inbound_email(self):
- return f"{self.token}@{live_settings.SENDGRID_INBOUND_EMAIL_DOMAIN}"
+ # todo: implement inbound emails
+ pass
@property
def default_channel_filter(self):
@@ -461,10 +468,6 @@ class AlertReceiveChannel(IntegrationOptionsMixin, MaintainableObject):
"message": self.web_message_template,
"image_url": self.web_image_url_template,
},
- "email": {
- "title": self.email_title_template,
- "message": self.email_message_template,
- },
"sms": {
"title": self.sms_title_template,
},
@@ -620,8 +623,6 @@ class AlertReceiveChannel(IntegrationOptionsMixin, MaintainableObject):
"web_title": self.web_title_template or "default",
"web_message": self.web_message_template or "default",
"web_image_url_template": self.web_image_url_template or "default",
- "email_title_template": self.email_title_template or "default",
- "email_message": self.email_message_template or "default",
"telegram_title": self.telegram_title_template or "default",
"telegram_message": self.telegram_message_template or "default",
"telegram_image_url": self.telegram_image_url_template or "default",
diff --git a/engine/apps/alerts/models/channel_filter.py b/engine/apps/alerts/models/channel_filter.py
index 2d573714..62b04a6e 100644
--- a/engine/apps/alerts/models/channel_filter.py
+++ b/engine/apps/alerts/models/channel_filter.py
@@ -116,7 +116,11 @@ class ChannelFilter(OrderedModel):
return self.is_default or self.check_filter(json.dumps(raw_request_data)) or self.check_filter(str(title))
def check_filter(self, value):
- return re.search(self.filtering_term, value)
+ try:
+ return re.search(self.filtering_term, value)
+ except re.error:
+ logger.error(f"channel_filter={self.id} failed to parse regex={self.filtering_term}")
+ return False
@property
def slack_channel_id_or_general_log_id(self):
diff --git a/engine/apps/alerts/tasks/notify_user.py b/engine/apps/alerts/tasks/notify_user.py
index 425eea16..7bd2f03d 100644
--- a/engine/apps/alerts/tasks/notify_user.py
+++ b/engine/apps/alerts/tasks/notify_user.py
@@ -228,7 +228,6 @@ def notify_user_task(
def perform_notification(log_record_pk):
SMSMessage = apps.get_model("twilioapp", "SMSMessage")
PhoneCall = apps.get_model("twilioapp", "PhoneCall")
- # EmailMessage = apps.get_model("sendgridapp", "EmailMessage") TODO: restore email notifications
UserNotificationPolicy = apps.get_model("base", "UserNotificationPolicy")
TelegramToUserConnector = apps.get_model("telegram", "TelegramToUserConnector")
UserNotificationPolicyLogRecord = apps.get_model("base", "UserNotificationPolicyLogRecord")
@@ -280,10 +279,6 @@ def perform_notification(log_record_pk):
elif notification_channel == UserNotificationPolicy.NotificationChannel.TELEGRAM:
TelegramToUserConnector.notify_user(user, alert_group, notification_policy)
- # TODO: restore email notifications
- # elif notification_channel == UserNotificationPolicy.NotificationChannel.EMAIL:
- # EmailMessage.send_incident_mail(user, alert_group, notification_policy)
-
elif notification_channel == UserNotificationPolicy.NotificationChannel.SLACK:
# TODO: refactor checking the possibility of sending a notification in slack
# Code below is not consistent.
diff --git a/engine/apps/alerts/tests/test_alert_receiver_channel.py b/engine/apps/alerts/tests/test_alert_receiver_channel.py
index 20d5528d..cdc204de 100644
--- a/engine/apps/alerts/tests/test_alert_receiver_channel.py
+++ b/engine/apps/alerts/tests/test_alert_receiver_channel.py
@@ -144,3 +144,28 @@ def test_notify_maintenance_with_general_channel(make_organization, make_alert_r
mock_post_message.assert_called_once_with(
organization, organization.general_log_channel_id, "maintenance mode enabled"
)
+
+
+@pytest.mark.django_db
+def test_get_or_create_manual_integration_deleted_team(make_organization, make_team, make_alert_receive_channel):
+ organization = make_organization(general_log_channel_id="CHANNEL-ID")
+ # setup general manual integration
+ general_manual = AlertReceiveChannel.get_or_create_manual_integration(
+ organization=organization, team=None, integration=AlertReceiveChannel.INTEGRATION_MANUAL, defaults={}
+ )
+ # setup another team manual integration
+ team1 = make_team(organization)
+ team1_manual = AlertReceiveChannel.get_or_create_manual_integration(
+ organization=organization, team=team1, integration=AlertReceiveChannel.INTEGRATION_MANUAL, defaults={}
+ )
+
+ # team is deleted
+ team1.delete()
+ team1_manual.refresh_from_db()
+ assert team1_manual.team is None
+
+ # it should still be possible to get a manual integration for general team
+ integration = AlertReceiveChannel.get_or_create_manual_integration(
+ organization=organization, team=None, integration=AlertReceiveChannel.INTEGRATION_MANUAL, defaults={}
+ )
+ assert integration == general_manual
diff --git a/engine/apps/alerts/tests/test_default_templates.py b/engine/apps/alerts/tests/test_default_templates.py
index 259aa051..50c1ecd6 100644
--- a/engine/apps/alerts/tests/test_default_templates.py
+++ b/engine/apps/alerts/tests/test_default_templates.py
@@ -2,7 +2,6 @@ import pytest
from jinja2 import TemplateSyntaxError
from apps.alerts.incident_appearance.templaters import (
- AlertEmailTemplater,
AlertPhoneCallTemplater,
AlertSlackTemplater,
AlertSmsTemplater,
@@ -45,14 +44,12 @@ def test_default_templates(
slack_templater = AlertSlackTemplater(alert)
web_templater = AlertWebTemplater(alert)
sms_templater = AlertSmsTemplater(alert)
- email_templater = AlertEmailTemplater(alert)
telegram_templater = AlertTelegramTemplater(alert)
phone_call_templater = AlertPhoneCallTemplater(alert)
templaters = {
"slack": slack_templater,
"web": web_templater,
"sms": sms_templater,
- "email": email_templater,
"telegram": telegram_templater,
"phone_call": phone_call_templater,
}
diff --git a/engine/apps/api/serializers/alert_receive_channel.py b/engine/apps/api/serializers/alert_receive_channel.py
index b04f2283..58d6f349 100644
--- a/engine/apps/api/serializers/alert_receive_channel.py
+++ b/engine/apps/api/serializers/alert_receive_channel.py
@@ -254,18 +254,6 @@ class AlertReceiveChannelTemplatesSerializer(EagerLoadingMixin, serializers.Mode
validators=[valid_jinja_template_for_serializer_method_field],
required=False,
)
- email_title_template = WritableSerializerMethodField(
- allow_null=True,
- deserializer_field=serializers.CharField(),
- validators=[valid_jinja_template_for_serializer_method_field],
- required=False,
- )
- email_message_template = WritableSerializerMethodField(
- allow_null=True,
- deserializer_field=serializers.CharField(),
- validators=[valid_jinja_template_for_serializer_method_field],
- required=False,
- )
source_link_template = WritableSerializerMethodField(
allow_null=True,
deserializer_field=serializers.CharField(),
@@ -306,8 +294,6 @@ class AlertReceiveChannelTemplatesSerializer(EagerLoadingMixin, serializers.Mode
"web_title_template",
"web_message_template",
"web_image_url_template",
- "email_title_template",
- "email_message_template",
"telegram_title_template",
"telegram_message_template",
"telegram_image_url_template",
@@ -391,17 +377,6 @@ class AlertReceiveChannelTemplatesSerializer(EagerLoadingMixin, serializers.Mode
elif default_template is not None and default_template.strip() == value.strip():
self.instance.web_title_template = None
- def get_email_title_template(self, obj):
- default_template = AlertReceiveChannel.INTEGRATION_TO_DEFAULT_EMAIL_TITLE_TEMPLATE[obj.integration]
- return obj.email_title_template or default_template
-
- def set_email_title_template(self, value):
- default_template = AlertReceiveChannel.INTEGRATION_TO_DEFAULT_EMAIL_TITLE_TEMPLATE[self.instance.integration]
- if default_template is None or default_template.strip() != value.strip():
- self.instance.email_title_template = value.strip()
- elif default_template is not None and default_template.strip() == value.strip():
- self.instance.email_title_template = None
-
def get_web_message_template(self, obj):
default_template = AlertReceiveChannel.INTEGRATION_TO_DEFAULT_WEB_MESSAGE_TEMPLATE[obj.integration]
return obj.web_message_template or default_template
@@ -424,17 +399,6 @@ class AlertReceiveChannelTemplatesSerializer(EagerLoadingMixin, serializers.Mode
elif default_template is not None and default_template.strip() == value.strip():
self.instance.web_image_url_template = None
- def get_email_message_template(self, obj):
- default_template = AlertReceiveChannel.INTEGRATION_TO_DEFAULT_EMAIL_MESSAGE_TEMPLATE[obj.integration]
- return obj.email_message_template or default_template
-
- def set_email_message_template(self, value):
- default_template = AlertReceiveChannel.INTEGRATION_TO_DEFAULT_EMAIL_MESSAGE_TEMPLATE[self.instance.integration]
- if default_template is None or default_template.strip() != value.strip():
- self.instance.email_message_template = value.strip()
- elif default_template is not None and default_template.strip() == value.strip():
- self.instance.email_message_template = None
-
def get_telegram_title_template(self, obj):
default_template = AlertReceiveChannel.INTEGRATION_TO_DEFAULT_TELEGRAM_TITLE_TEMPLATE[obj.integration]
return obj.telegram_title_template or default_template
@@ -644,8 +608,8 @@ class AlertReceiveChannelTemplatesSerializer(EagerLoadingMixin, serializers.Mode
def _get_messaging_backend_templates(self, obj):
"""Return additional messaging backend templates if any."""
templates = {}
- for backend_id, _ in get_messaging_backends():
- for field in ("title", "message", "image_url"):
+ for backend_id, backend in get_messaging_backends():
+ for field in backend.template_fields:
value = None
if obj.messaging_backends_templates:
value = obj.messaging_backends_templates.get(backend_id, {}).get(field)
diff --git a/engine/apps/api/serializers/custom_button.py b/engine/apps/api/serializers/custom_button.py
index 11e184e7..0ece3b2e 100644
--- a/engine/apps/api/serializers/custom_button.py
+++ b/engine/apps/api/serializers/custom_button.py
@@ -1,4 +1,5 @@
import json
+from collections import defaultdict
from django.core.validators import URLValidator, ValidationError
from jinja2 import Template, TemplateError
@@ -51,15 +52,33 @@ class CustomButtonSerializer(serializers.ModelSerializer):
return None
try:
- json.loads(data)
- except ValueError:
- raise serializers.ValidationError("Data has incorrect format")
-
- try:
- Template(data)
+ template = Template(data)
except TemplateError:
raise serializers.ValidationError("Data has incorrect template")
+ try:
+ rendered = template.render(
+ {
+ # Validate that the template can be rendered with a JSON-ish alert payload.
+ # We don't know what the actual payload will be, so we use a defaultdict
+ # so that attribute access within a template will never fail
+ # (provided it's only one level deep - we won't accept templates that attempt
+ # to do nested attribute access).
+ # Every attribute access should return a string to ensure that users are
+ # correctly using `tojson` or wrapping fields in strings.
+ # If we instead used a `defaultdict(dict)` or `defaultdict(lambda: 1)` we
+ # would accidentally accept templates such as `{"name": {{ alert_payload.name }}}`
+ # which would then fail at the true render time due to the
+ # lack of explicit quotes around the template variable; this would render
+ # as `{"name": some_alert_name}` which is not valid JSON.
+ "alert_payload": defaultdict(str),
+ "alert_group_id": "abcd",
+ }
+ )
+ json.loads(rendered)
+ except ValueError:
+ raise serializers.ValidationError("Data has incorrect format")
+
return data
def validate_forward_whole_payload(self, data):
diff --git a/engine/apps/api/serializers/schedule_base.py b/engine/apps/api/serializers/schedule_base.py
index b3e1858d..c2eb6ea6 100644
--- a/engine/apps/api/serializers/schedule_base.py
+++ b/engine/apps/api/serializers/schedule_base.py
@@ -76,7 +76,8 @@ class ScheduleBaseSerializer(EagerLoadingMixin, serializers.ModelSerializer):
def get_number_of_escalation_chains(self, obj):
# num_escalation_chains param added in queryset via annotate. Check ScheduleView.get_queryset
# return 0 for just created schedules
- return getattr(obj, "num_escalation_chains", 0)
+ num = getattr(obj, "num_escalation_chains", 0)
+ return num or 0
def validate(self, attrs):
if "slack_channel_id" in attrs:
diff --git a/engine/apps/api/tests/test_alert_group.py b/engine/apps/api/tests/test_alert_group.py
index 6d4a0b9e..4ef75494 100644
--- a/engine/apps/api/tests/test_alert_group.py
+++ b/engine/apps/api/tests/test_alert_group.py
@@ -1443,7 +1443,7 @@ def test_alert_group_preview_body_non_existent_template_var(
client = APIClient()
url = reverse("api-internal:alertgroup-preview-template", kwargs={"pk": alert_group.public_primary_key})
- data = {"template_name": "email_title_template", "template_body": "foobar: {{ foobar.does_not_exist }}"}
+ data = {"template_name": "testonly_title_template", "template_body": "foobar: {{ foobar.does_not_exist }}"}
response = client.post(url, data, format="json", **make_user_auth_headers(user, token))
assert response.status_code == status.HTTP_200_OK
@@ -1465,7 +1465,7 @@ def test_alert_group_preview_body_invalid_template_syntax(
client = APIClient()
url = reverse("api-internal:alertgroup-preview-template", kwargs={"pk": alert_group.public_primary_key})
- data = {"template_name": "email_title_template", "template_body": "{{'' if foo is None else foo}}"}
+ data = {"template_name": "testonly_title_template", "template_body": "{{'' if foo is None else foo}}"}
response = client.post(url, data, format="json", **make_user_auth_headers(user, token))
assert response.status_code == status.HTTP_400_BAD_REQUEST
diff --git a/engine/apps/api/tests/test_alert_receive_channel_template.py b/engine/apps/api/tests/test_alert_receive_channel_template.py
index 08340646..a4a10ccf 100644
--- a/engine/apps/api/tests/test_alert_receive_channel_template.py
+++ b/engine/apps/api/tests/test_alert_receive_channel_template.py
@@ -6,6 +6,7 @@ from rest_framework import status
from rest_framework.response import Response
from rest_framework.test import APIClient
+from apps.base.messaging import BaseMessagingBackend
from common.constants.role import Role
@@ -224,7 +225,7 @@ def test_update_alert_receive_channel_backend_template_update_values(
# patch messaging backends to add OTHER as a valid backend
with patch(
"apps.api.serializers.alert_receive_channel.get_messaging_backends",
- return_value=[("TESTONLY", None), ("OTHER", None)],
+ return_value=[("TESTONLY", BaseMessagingBackend), ("OTHER", BaseMessagingBackend)],
):
response = client.put(
url, format="json", data={"testonly_title_template": "updated-title"}, **make_user_auth_headers(user, token)
diff --git a/engine/apps/api/tests/test_custom_button.py b/engine/apps/api/tests/test_custom_button.py
index bc91fc60..d957b9a1 100644
--- a/engine/apps/api/tests/test_custom_button.py
+++ b/engine/apps/api/tests/test_custom_button.py
@@ -128,6 +128,91 @@ def test_create_valid_data_button(custom_button_internal_api_setup, make_user_au
assert response.json() == expected_response
+@pytest.mark.django_db
+def test_create_valid_nested_data_button(custom_button_internal_api_setup, make_user_auth_headers):
+ user, token, custom_button = custom_button_internal_api_setup
+ client = APIClient()
+ url = reverse("api-internal:custom_button-list")
+
+ data = {
+ "name": "amixr_button_with_valid_data",
+ "webhook": TEST_URL,
+ # Assert that nested field access still works as long as the variable
+ # is quoted, making it valid JSON.
+ # This ensures backwards compatibility from when templates were required
+ # to be JSON.
+ "data": '{"nested_item": "{{ alert_payload.foo.bar }}"}',
+ "team": None,
+ }
+
+ response = client.post(url, data, format="json", **make_user_auth_headers(user, token))
+ # modify initial data by adding id and None for optional fields
+ custom_button = CustomButton.objects.get(public_primary_key=response.data["id"])
+ expected_response = data | {
+ "id": custom_button.public_primary_key,
+ "user": None,
+ "password": None,
+ "authorization_header": None,
+ "forward_whole_payload": False,
+ }
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json() == expected_response
+
+
+@pytest.mark.django_db
+def test_create_valid_data_after_render_button(custom_button_internal_api_setup, make_user_auth_headers):
+ user, token, custom_button = custom_button_internal_api_setup
+ client = APIClient()
+ url = reverse("api-internal:custom_button-list")
+
+ data = {
+ "name": "amixr_button_with_valid_data",
+ "webhook": TEST_URL,
+ "data": '{"name": "{{ alert_payload.name }}", "labels": {{ alert_payload.labels | tojson }}}',
+ "team": None,
+ }
+
+ response = client.post(url, data, format="json", **make_user_auth_headers(user, token))
+ # modify initial data by adding id and None for optional fields
+ custom_button = CustomButton.objects.get(public_primary_key=response.data["id"])
+ expected_response = data | {
+ "id": custom_button.public_primary_key,
+ "user": None,
+ "password": None,
+ "authorization_header": None,
+ "forward_whole_payload": False,
+ }
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json() == expected_response
+
+
+@pytest.mark.django_db
+def test_create_valid_data_after_render_use_all_data_button(custom_button_internal_api_setup, make_user_auth_headers):
+ user, token, custom_button = custom_button_internal_api_setup
+ client = APIClient()
+ url = reverse("api-internal:custom_button-list")
+
+ data = {
+ "name": "amixr_button_with_valid_data",
+ "webhook": TEST_URL,
+ "data": "{{ alert_payload | tojson }}",
+ "team": None,
+ }
+
+ response = client.post(url, data, format="json", **make_user_auth_headers(user, token))
+ # modify initial data by adding id and None for optional fields
+ custom_button = CustomButton.objects.get(public_primary_key=response.data["id"])
+ expected_response = data | {
+ "id": custom_button.public_primary_key,
+ "user": None,
+ "password": None,
+ "authorization_header": None,
+ "forward_whole_payload": False,
+ }
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json() == expected_response
+
+
@pytest.mark.django_db
def test_create_invalid_url_custom_button(custom_button_internal_api_setup, make_user_auth_headers):
user, token, custom_button = custom_button_internal_api_setup
@@ -157,6 +242,22 @@ def test_create_invalid_data_custom_button(custom_button_internal_api_setup, mak
assert response.status_code == status.HTTP_400_BAD_REQUEST
+@pytest.mark.django_db
+def test_create_invalid_templated_data_custom_button(custom_button_internal_api_setup, make_user_auth_headers):
+ user, token, custom_button = custom_button_internal_api_setup
+ client = APIClient()
+ url = reverse("api-internal:custom_button-list")
+
+ data = {
+ "name": "amixr_button_invalid_data",
+ "webhook": TEST_URL,
+ # This would need a `| tojson` or some double quotes around it to pass validation.
+ "data": "{{ alert_payload.name }}",
+ }
+ response = client.post(url, data, format="json", **make_user_auth_headers(user, token))
+ assert response.status_code == status.HTTP_400_BAD_REQUEST
+
+
@pytest.mark.django_db
def test_update_custom_button(custom_button_internal_api_setup, make_user_auth_headers):
user, token, custom_button = custom_button_internal_api_setup
diff --git a/engine/apps/api/views/organization.py b/engine/apps/api/views/organization.py
index 34580734..9545ffb3 100644
--- a/engine/apps/api/views/organization.py
+++ b/engine/apps/api/views/organization.py
@@ -59,7 +59,9 @@ class GetTelegramVerificationCode(APIView):
telegram_client = TelegramClient()
bot_username = telegram_client.api_client.username
bot_link = f"https://t.me/{bot_username}"
- return Response({"telegram_code": str(new_code.uuid), "bot_link": bot_link}, status=status.HTTP_200_OK)
+ return Response(
+ {"telegram_code": str(new_code.uuid_with_org_id), "bot_link": bot_link}, status=status.HTTP_200_OK
+ )
class GetChannelVerificationCode(APIView):
diff --git a/engine/apps/api/views/schedule.py b/engine/apps/api/views/schedule.py
index 4bc5764e..9c52a69c 100644
--- a/engine/apps/api/views/schedule.py
+++ b/engine/apps/api/views/schedule.py
@@ -13,7 +13,7 @@ from rest_framework.permissions import IsAuthenticated
from rest_framework.views import Response
from rest_framework.viewsets import ModelViewSet
-from apps.alerts.models import EscalationChain
+from apps.alerts.models import EscalationChain, EscalationPolicy
from apps.api.permissions import MODIFY_ACTIONS, READ_ACTIONS, ActionPermission, AnyRole, IsAdmin, IsAdminOrEditor
from apps.api.serializers.schedule_base import ScheduleFastSerializer
from apps.api.serializers.schedule_polymorphic import (
@@ -108,22 +108,28 @@ class ScheduleView(
slack_team_identity=organization.slack_team_identity,
slack_id=OuterRef("channel"),
)
+ escalation_policies = (
+ EscalationPolicy.objects.values("notify_schedule")
+ .order_by("notify_schedule")
+ .annotate(num_escalation_chains=Count("notify_schedule"))
+ .filter(notify_schedule=OuterRef("id"))
+ )
queryset = queryset.annotate(
slack_channel_name=Subquery(slack_channels.values("name")[:1]),
slack_channel_pk=Subquery(slack_channels.values("public_primary_key")[:1]),
- num_escalation_chains=Count(
- "escalation_policies__escalation_chain",
- distinct=True,
- ),
+ num_escalation_chains=Subquery(escalation_policies.values("num_escalation_chains")[:1]),
)
return queryset
def get_queryset(self):
is_short_request = self.request.query_params.get("short", "false") == "true"
organization = self.request.auth.organization
- queryset = OnCallSchedule.objects.filter(
- organization=organization,
- team=self.request.user.current_team,
+ queryset = OnCallSchedule.objects.filter(organization=organization, team=self.request.user.current_team).defer(
+ # avoid requesting large text fields which are not used when listing schedules
+ "cached_ical_file_primary",
+ "prev_ical_file_primary",
+ "cached_ical_file_overrides",
+ "prev_ical_file_overrides",
)
if not is_short_request:
queryset = self._annotate_queryset(queryset)
diff --git a/engine/apps/api/views/user.py b/engine/apps/api/views/user.py
index cf37b9e7..c27a713d 100644
--- a/engine/apps/api/views/user.py
+++ b/engine/apps/api/views/user.py
@@ -374,7 +374,9 @@ class UserView(
bot_username = telegram_client.api_client.username
bot_link = f"https://t.me/{bot_username}"
- return Response({"telegram_code": str(new_code.uuid), "bot_link": bot_link}, status=status.HTTP_200_OK)
+ return Response(
+ {"telegram_code": str(new_code.uuid_with_org_id), "bot_link": bot_link}, status=status.HTTP_200_OK
+ )
@action(detail=True, methods=["post"])
def unlink_slack(self, request, pk):
diff --git a/engine/apps/api/views/user_notification_policy.py b/engine/apps/api/views/user_notification_policy.py
index 7231bcc5..5cc6399e 100644
--- a/engine/apps/api/views/user_notification_policy.py
+++ b/engine/apps/api/views/user_notification_policy.py
@@ -160,9 +160,6 @@ class UserNotificationPolicyView(UpdateSerializerMixin, ModelViewSet):
notification_channel
in NotificationChannelAPIOptions.TELEGRAM_INTEGRATION_REQUIRED_NOTIFICATION_CHANNELS
)
- email_integration_required = (
- notification_channel in NotificationChannelAPIOptions.EMAIL_INTEGRATION_REQUIRED_NOTIFICATION_CHANNELS
- )
mobile_app_integration_required = (
notification_channel
in NotificationChannelAPIOptions.MOBILE_APP_INTEGRATION_REQUIRED_NOTIFICATION_CHANNELS
@@ -171,8 +168,6 @@ class UserNotificationPolicyView(UpdateSerializerMixin, ModelViewSet):
continue
if telegram_integration_required and not settings.FEATURE_TELEGRAM_INTEGRATION_ENABLED:
continue
- if email_integration_required and not settings.FEATURE_EMAIL_INTEGRATION_ENABLED:
- continue
if mobile_app_integration_required and not settings.MOBILE_APP_PUSH_NOTIFICATIONS_ENABLED:
continue
diff --git a/engine/apps/base/messaging.py b/engine/apps/base/messaging.py
index 64d9682d..7d2b2e88 100644
--- a/engine/apps/base/messaging.py
+++ b/engine/apps/base/messaging.py
@@ -7,7 +7,9 @@ class BaseMessagingBackend:
label = "The Backend"
short_label = "Backend"
available_for_use = False
+
templater = None
+ template_fields = ("title", "message", "image_url")
def __init__(self, *args, **kwargs):
self.notification_channel_id = kwargs.get("notification_channel_id")
diff --git a/engine/apps/base/models/live_setting.py b/engine/apps/base/models/live_setting.py
index abd5cf1e..4e2664d7 100644
--- a/engine/apps/base/models/live_setting.py
+++ b/engine/apps/base/models/live_setting.py
@@ -33,6 +33,11 @@ class LiveSetting(models.Model):
error = models.TextField(null=True, default=None)
AVAILABLE_NAMES = (
+ "EMAIL_HOST",
+ "EMAIL_PORT",
+ "EMAIL_HOST_USER",
+ "EMAIL_HOST_PASSWORD",
+ "EMAIL_USE_TLS",
"TWILIO_ACCOUNT_SID",
"TWILIO_AUTH_TOKEN",
"TWILIO_NUMBER",
@@ -51,6 +56,11 @@ class LiveSetting(models.Model):
)
DESCRIPTIONS = {
+ "EMAIL_HOST": "SMTP server host. This email server will be used to notify users via email.",
+ "EMAIL_PORT": "SMTP server port",
+ "EMAIL_HOST_USER": "SMTP server user",
+ "EMAIL_HOST_PASSWORD": "SMTP server password",
+ "EMAIL_USE_TLS": "SMTP enable/disable TLS",
"SLACK_SIGNING_SECRET": (
"Check more info ."
- ),
- "SENDGRID_FROM_EMAIL": (
- "Address to send emails, "
- "more info ."
- ),
- "SENDGRID_SECRET_KEY": "It is the secret key to secure receiving inbound emails.",
- "SENDGRID_INBOUND_EMAIL_DOMAIN": "Domain to receive emails for inbound emails integration.",
"TELEGRAM_TOKEN": (
"Secret token for Telegram bot, you can get one via BotFather ."
),
@@ -126,11 +126,10 @@ class LiveSetting(models.Model):
}
SECRET_SETTING_NAMES = (
+ "EMAIL_HOST_PASSWORD",
"TWILIO_ACCOUNT_SID",
"TWILIO_AUTH_TOKEN",
"TWILIO_VERIFY_SERVICE_SID",
- "SENDGRID_API_KEY",
- "SENDGRID_SECRET_KEY",
"SLACK_CLIENT_OAUTH_ID",
"SLACK_CLIENT_OAUTH_SECRET",
"SLACK_SIGNING_SECRET",
diff --git a/engine/apps/base/models/user_notification_policy.py b/engine/apps/base/models/user_notification_policy.py
index b6444995..a4c4b876 100644
--- a/engine/apps/base/models/user_notification_policy.py
+++ b/engine/apps/base/models/user_notification_policy.py
@@ -35,7 +35,6 @@ BUILT_IN_BACKENDS = (
("SMS", 1),
("PHONE_CALL", 2),
("TELEGRAM", 3),
- ("EMAIL", 4),
("MOBILE_PUSH_GENERAL", 5),
("MOBILE_PUSH_CRITICAL", 6),
)
@@ -214,7 +213,6 @@ class NotificationChannelOptions:
SLACK_INTEGRATION_REQUIRED_NOTIFICATION_CHANNELS = [UserNotificationPolicy.NotificationChannel.SLACK]
TELEGRAM_INTEGRATION_REQUIRED_NOTIFICATION_CHANNELS = [UserNotificationPolicy.NotificationChannel.TELEGRAM]
- EMAIL_INTEGRATION_REQUIRED_NOTIFICATION_CHANNELS = [UserNotificationPolicy.NotificationChannel.EMAIL]
MOBILE_APP_INTEGRATION_REQUIRED_NOTIFICATION_CHANNELS = [
UserNotificationPolicy.NotificationChannel.MOBILE_PUSH_GENERAL,
UserNotificationPolicy.NotificationChannel.MOBILE_PUSH_CRITICAL,
@@ -227,7 +225,6 @@ class NotificationChannelAPIOptions(NotificationChannelOptions):
UserNotificationPolicy.NotificationChannel.SMS: "SMS \U00002709\U0001F4F2",
UserNotificationPolicy.NotificationChannel.PHONE_CALL: "Phone call \U0000260E",
UserNotificationPolicy.NotificationChannel.TELEGRAM: "Telegram \U0001F916",
- UserNotificationPolicy.NotificationChannel.EMAIL: "Email \U0001F4E8",
UserNotificationPolicy.NotificationChannel.MOBILE_PUSH_GENERAL: "Mobile App",
UserNotificationPolicy.NotificationChannel.MOBILE_PUSH_CRITICAL: "Mobile App Critical",
}
@@ -243,7 +240,6 @@ class NotificationChannelAPIOptions(NotificationChannelOptions):
UserNotificationPolicy.NotificationChannel.SMS: "SMS",
UserNotificationPolicy.NotificationChannel.PHONE_CALL: "\U0000260E",
UserNotificationPolicy.NotificationChannel.TELEGRAM: "Telegram",
- UserNotificationPolicy.NotificationChannel.EMAIL: "Email",
UserNotificationPolicy.NotificationChannel.MOBILE_PUSH_GENERAL: "Mobile App",
UserNotificationPolicy.NotificationChannel.MOBILE_PUSH_CRITICAL: "Mobile App Critical",
}
@@ -261,7 +257,6 @@ class NotificationChannelPublicAPIOptions(NotificationChannelAPIOptions):
UserNotificationPolicy.NotificationChannel.SMS: "notify_by_sms",
UserNotificationPolicy.NotificationChannel.PHONE_CALL: "notify_by_phone_call",
UserNotificationPolicy.NotificationChannel.TELEGRAM: "notify_by_telegram",
- UserNotificationPolicy.NotificationChannel.EMAIL: "notify_by_email",
UserNotificationPolicy.NotificationChannel.MOBILE_PUSH_GENERAL: "notify_by_mobile_app",
UserNotificationPolicy.NotificationChannel.MOBILE_PUSH_CRITICAL: "notify_by_mobile_app_critical",
}
diff --git a/engine/apps/base/models/user_notification_policy_log_record.py b/engine/apps/base/models/user_notification_policy_log_record.py
index e29a9ec4..4256faef 100644
--- a/engine/apps/base/models/user_notification_policy_log_record.py
+++ b/engine/apps/base/models/user_notification_policy_log_record.py
@@ -49,14 +49,14 @@ class UserNotificationPolicyLogRecord(models.Model):
ERROR_NOTIFICATION_PHONE_CALLS_LIMIT_EXCEEDED,
ERROR_NOTIFICATION_PHONE_NUMBER_IS_NOT_VERIFIED,
ERROR_NOTIFICATION_NOT_ABLE_TO_SEND_MAIL,
- ERROR_NOTIFICATION_MAIL_LIMIT_EXCEEDED,
- ERROR_NOTIFICATION_EMAIL_IS_NOT_VERIFIED,
+ ERROR_NOTIFICATION_MAIL_LIMIT_EXCEEDED, # todo: manage backend specific limits in messaging backend
+ ERROR_NOTIFICATION_EMAIL_IS_NOT_VERIFIED, # deprecated
ERROR_NOTIFICATION_TELEGRAM_IS_NOT_LINKED_TO_SLACK_ACC,
ERROR_NOTIFICATION_PHONE_CALL_LINE_BUSY,
ERROR_NOTIFICATION_PHONE_CALL_FAILED,
ERROR_NOTIFICATION_PHONE_CALL_NO_ANSWER,
ERROR_NOTIFICATION_SMS_DELIVERY_FAILED,
- ERROR_NOTIFICATION_MAIL_DELIVERY_FAILED,
+ ERROR_NOTIFICATION_MAIL_DELIVERY_FAILED, # deprecated
ERROR_NOTIFICATION_TELEGRAM_BOT_IS_DELETED,
ERROR_NOTIFICATION_POSTING_TO_SLACK_IS_DISABLED,
ERROR_NOTIFICATION_POSTING_TO_TELEGRAM_IS_DISABLED, # deprecated
@@ -78,7 +78,6 @@ class UserNotificationPolicyLogRecord(models.Model):
ERROR_NOTIFICATION_PHONE_CALLS_LIMIT_EXCEEDED,
ERROR_NOTIFICATION_MAIL_LIMIT_EXCEEDED,
ERROR_NOTIFICATION_PHONE_NUMBER_IS_NOT_VERIFIED,
- ERROR_NOTIFICATION_EMAIL_IS_NOT_VERIFIED,
]
type = models.IntegerField(choices=TYPE_CHOICES)
@@ -172,9 +171,6 @@ class UserNotificationPolicyLogRecord(models.Model):
result += f"SMS to {user_verbal} was delivered successfully"
elif notification_channel == UserNotificationPolicy.NotificationChannel.PHONE_CALL:
result += f"phone call to {user_verbal} was successful"
- # TODO: restore email notifications
- # elif notification_channel == UserNotificationPolicy.NotificationChannel.EMAIL:
- # result += f"email to {user_verbal} was delivered successfully"
elif notification_channel is None:
result += f"notification to {user_verbal} was delivered successfully"
elif self.type == UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_FAILED:
@@ -185,6 +181,7 @@ class UserNotificationPolicyLogRecord(models.Model):
== UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_PHONE_CALLS_LIMIT_EXCEEDED
):
result += f"attempt to call to {user_verbal} has been failed due to a plan limit"
+ # todo: manage backend specific limits in messaging backend
elif self.notification_error_code == UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_MAIL_LIMIT_EXCEEDED:
result += f"failed to send email to {user_verbal}. Exceeded limit for mails"
elif (
@@ -201,10 +198,6 @@ class UserNotificationPolicyLogRecord(models.Model):
result += f"OnCall was not able to send an SMS to {user_verbal}"
elif self.notification_error_code == UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_NOT_ABLE_TO_CALL:
result += f"OnCall was not able to call to {user_verbal}"
- elif (
- self.notification_error_code == UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_NOT_ABLE_TO_SEND_MAIL
- ):
- result += f"OnCall was not able to send an email to {user_verbal}"
elif (
self.notification_error_code
== UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_POSTING_TO_SLACK_IS_DISABLED
@@ -242,10 +235,6 @@ class UserNotificationPolicyLogRecord(models.Model):
result += f"phone call to {user_verbal} ended without being answered"
elif self.notification_error_code == UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_SMS_DELIVERY_FAILED:
result += f"SMS {user_verbal} was not delivered"
- elif (
- self.notification_error_code == UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_MAIL_DELIVERY_FAILED
- ):
- result += f"email to {user_verbal} was not delivered"
elif self.notification_error_code == UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_IN_SLACK:
result += f"failed to notify {user_verbal} in Slack"
elif (
@@ -286,7 +275,7 @@ class UserNotificationPolicyLogRecord(models.Model):
except ValueError:
backend = None
result += (
- f"failed to notify {user_verbal} in {backend.label.lower() if backend else 'disabled backend'}"
+ f"failed to notify {user_verbal} by {backend.label.lower() if backend else 'disabled backend'}"
)
elif self.type == UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_TRIGGERED:
if notification_step == UserNotificationPolicy.Step.NOTIFY:
@@ -298,9 +287,6 @@ class UserNotificationPolicyLogRecord(models.Model):
result += f"called {user_verbal} by phone"
elif notification_channel == UserNotificationPolicy.NotificationChannel.TELEGRAM:
result += f"sent telegram message to {user_verbal}"
- # TODO: restore email notifications
- # elif notification_channel == UserNotificationPolicy.NotificationChannel.EMAIL:
- # result += f"sent email to {user_verbal}"
elif notification_channel == UserNotificationPolicy.NotificationChannel.MOBILE_PUSH_GENERAL:
result += f"sent push notifications to {user_verbal}"
elif notification_channel == UserNotificationPolicy.NotificationChannel.MOBILE_PUSH_CRITICAL:
diff --git a/engine/apps/base/tests/test_user_notification_policy_log_record.py b/engine/apps/base/tests/test_user_notification_policy_log_record.py
index 7c8c8939..c51b892b 100644
--- a/engine/apps/base/tests/test_user_notification_policy_log_record.py
+++ b/engine/apps/base/tests/test_user_notification_policy_log_record.py
@@ -31,7 +31,7 @@ def test_extra_messaging_backends_error_log(
)
output = log_record.render_log_line_action()
- assert output == f"failed to notify {user_1.username} in {TestOnlyBackend.label.lower()}"
+ assert output == f"failed to notify {user_1.username} by {TestOnlyBackend.label.lower()}"
@pytest.mark.django_db
diff --git a/engine/apps/base/utils.py b/engine/apps/base/utils.py
index 0fe0d8a9..f8ad633f 100644
--- a/engine/apps/base/utils.py
+++ b/engine/apps/base/utils.py
@@ -5,8 +5,6 @@ from urllib.parse import urlparse
import phonenumbers
from django.apps import apps
from phonenumbers import NumberParseException
-from python_http_client import UnauthorizedError
-from sendgrid import SendGridAPIClient
from telegram import Bot
from twilio.base.exceptions import TwilioException
from twilio.rest import Client
@@ -77,20 +75,6 @@ class LiveSettingValidator:
if not cls._is_phone_number_valid(twilio_number):
return "Please specify a valid phone number in the following format: +XXXXXXXXXXX"
- @classmethod
- def _check_sendgrid_api_key(cls, sendgrid_api_key):
- sendgrid_client = SendGridAPIClient(sendgrid_api_key)
-
- try:
- sendgrid_client.client.mail_settings.get()
- except Exception as e:
- return cls._prettify_sendgrid_error(e)
-
- @classmethod
- def _check_sendgrid_from_email(cls, sendgrid_from_email):
- if not cls._is_email_valid(sendgrid_from_email):
- return "Please specify a valid email"
-
@classmethod
def _check_slack_install_return_redirect_host(cls, slack_install_return_redirect_host):
scheme = urlparse(slack_install_return_redirect_host).scheme
@@ -147,10 +131,3 @@ class LiveSettingValidator:
return f"Twilio error: {exc.args[0]}"
else:
return f"Twilio error: {str(exc)}"
-
- @staticmethod
- def _prettify_sendgrid_error(exc):
- if isinstance(exc, UnauthorizedError):
- return "Sendgrid error: couldn't authorize with given credentials"
- else:
- return f"Sendgrid error: {str(exc)}"
diff --git a/engine/apps/sendgridapp/__init__.py b/engine/apps/email/__init__.py
similarity index 100%
rename from engine/apps/sendgridapp/__init__.py
rename to engine/apps/email/__init__.py
diff --git a/engine/apps/email/alert_rendering.py b/engine/apps/email/alert_rendering.py
new file mode 100644
index 00000000..b3802d83
--- /dev/null
+++ b/engine/apps/email/alert_rendering.py
@@ -0,0 +1,55 @@
+from django.template.loader import render_to_string
+from emoji.core import emojize
+
+from apps.alerts.incident_appearance.renderers.constants import DEFAULT_BACKUP_TITLE
+from apps.alerts.incident_appearance.templaters.alert_templater import AlertTemplater
+from common.utils import convert_md_to_html, str_or_backup
+
+
+class AlertEmailTemplater(AlertTemplater):
+ RENDER_FOR_EMAIL = "email"
+
+ def _render_for(self):
+ return self.RENDER_FOR_EMAIL
+
+ def _postformat(self, templated_alert):
+ templated_alert.title = self._slack_format_for_email(templated_alert.title)
+ templated_alert.message = self._slack_format_for_email(templated_alert.message)
+ return templated_alert
+
+ def _slack_format_for_email(self, data):
+ sf = self.slack_formatter
+ sf.hyperlink_mention_format = "{title} - {url}"
+ return sf.format(data)
+
+
+def build_subject_and_message(alert_group, emails_left):
+ alert = alert_group.alerts.first()
+ templated_alert = AlertEmailTemplater(alert).render()
+
+ title_fallback = (
+ f"#{alert_group.inside_organization_number} " f"{DEFAULT_BACKUP_TITLE} via {alert_group.channel.verbal_name}"
+ )
+
+ # default templates are the same as web templates, which are in Markdown format
+ message = templated_alert.message
+ if message:
+ message = convert_md_to_html(templated_alert.message) if templated_alert.message else ""
+
+ content = render_to_string(
+ "email_notification.html",
+ {
+ "url": alert_group.slack_permalink or alert_group.web_link,
+ "title": str_or_backup(templated_alert.title, title_fallback),
+ "message": str_or_backup(message, ""), # not render message at all if smth goes wrong
+ "organization": alert_group.channel.organization.org_title,
+ "integration": emojize(alert_group.channel.short_name, use_aliases=True),
+ "limit_notification": emails_left <= 20,
+ "emails_left": emails_left,
+ },
+ )
+
+ title = str_or_backup(templated_alert.title, title_fallback)
+ subject = f"[{title}] You are invited to check an alert group"
+
+ return subject, content
diff --git a/engine/apps/email/backend.py b/engine/apps/email/backend.py
new file mode 100644
index 00000000..164f0cb8
--- /dev/null
+++ b/engine/apps/email/backend.py
@@ -0,0 +1,20 @@
+from apps.base.messaging import BaseMessagingBackend
+from apps.email.tasks import notify_user_async
+
+
+class EmailBackend(BaseMessagingBackend):
+ backend_id = "EMAIL"
+ label = "Email"
+ short_label = "Email"
+ available_for_use = True
+
+ templater = "apps.email.alert_rendering.AlertEmailTemplater"
+ template_fields = ("title", "message")
+
+ def serialize_user(self, user):
+ return {"email": user.email}
+
+ def notify_user(self, user, alert_group, notification_policy):
+ notify_user_async.delay(
+ user_pk=user.pk, alert_group_pk=alert_group.pk, notification_policy_pk=notification_policy.pk
+ )
diff --git a/engine/apps/email/migrations/0001_initial.py b/engine/apps/email/migrations/0001_initial.py
new file mode 100644
index 00000000..3fe9537a
--- /dev/null
+++ b/engine/apps/email/migrations/0001_initial.py
@@ -0,0 +1,31 @@
+# Generated by Django 3.2.15 on 2022-10-10 12:06
+
+from django.db import migrations, models
+import django.db.models.deletion
+import uuid
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ('user_management', '0003_user_hide_phone_number'),
+ ('alerts', '0007_populate_web_title_cache'),
+ ('base', '0003_delete_organizationlogrecord'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='EmailMessage',
+ fields=[
+ ('message_uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
+ ('exceeded_limit', models.BooleanField(default=None, null=True)),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ('notification_policy', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='base.usernotificationpolicy')),
+ ('receiver', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.PROTECT, to='user_management.user')),
+ ('represents_alert', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='alerts.alert')),
+ ('represents_alert_group', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='alerts.alertgroup')),
+ ],
+ ),
+ ]
diff --git a/engine/apps/sendgridapp/migrations/__init__.py b/engine/apps/email/migrations/__init__.py
similarity index 100%
rename from engine/apps/sendgridapp/migrations/__init__.py
rename to engine/apps/email/migrations/__init__.py
diff --git a/engine/apps/email/models.py b/engine/apps/email/models.py
new file mode 100644
index 00000000..0db26986
--- /dev/null
+++ b/engine/apps/email/models.py
@@ -0,0 +1,20 @@
+import logging
+import uuid
+
+from django.db import models
+
+logger = logging.getLogger(__name__)
+
+
+class EmailMessage(models.Model):
+ message_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
+
+ exceeded_limit = models.BooleanField(null=True, default=None)
+ represents_alert = models.ForeignKey("alerts.Alert", on_delete=models.SET_NULL, null=True, default=None)
+ represents_alert_group = models.ForeignKey("alerts.AlertGroup", on_delete=models.SET_NULL, null=True, default=None)
+ notification_policy = models.ForeignKey(
+ "base.UserNotificationPolicy", on_delete=models.SET_NULL, null=True, default=None
+ )
+
+ receiver = models.ForeignKey("user_management.User", on_delete=models.PROTECT, null=True, default=None)
+ created_at = models.DateTimeField(auto_now_add=True)
diff --git a/engine/apps/email/tasks.py b/engine/apps/email/tasks.py
new file mode 100644
index 00000000..3fdf4d4e
--- /dev/null
+++ b/engine/apps/email/tasks.py
@@ -0,0 +1,99 @@
+from socket import gaierror
+
+from celery.utils.log import get_task_logger
+from django.conf import settings
+from django.core.mail import BadHeaderError, get_connection, send_mail
+from django.utils.html import strip_tags
+
+from apps.alerts.models import AlertGroup
+from apps.base.utils import live_settings
+from apps.email.alert_rendering import build_subject_and_message
+from apps.email.models import EmailMessage
+from apps.user_management.models import User
+from common.custom_celery_tasks import shared_dedicated_queue_retry_task
+
+MAX_RETRIES = 1 if settings.DEBUG else 10
+logger = get_task_logger(__name__)
+
+
+@shared_dedicated_queue_retry_task(autoretry_for=(Exception,), retry_backoff=True, max_retries=MAX_RETRIES)
+def notify_user_async(user_pk, alert_group_pk, notification_policy_pk):
+ # imported here to avoid circular import error
+ from apps.base.models import UserNotificationPolicy, UserNotificationPolicyLogRecord
+
+ try:
+ user = User.objects.get(pk=user_pk)
+ except User.DoesNotExist:
+ logger.warning(f"User {user_pk} does not exist")
+ return
+
+ try:
+ alert_group = AlertGroup.all_objects.get(pk=alert_group_pk)
+ except AlertGroup.DoesNotExist:
+ logger.warning(f"Alert group {alert_group_pk} does not exist")
+ return
+
+ try:
+ notification_policy = UserNotificationPolicy.objects.get(pk=notification_policy_pk)
+ except UserNotificationPolicy.DoesNotExist:
+ logger.warning(f"User notification policy {notification_policy_pk} does not exist")
+ return
+
+ emails_left = user.organization.emails_left(user)
+ if emails_left <= 0:
+ UserNotificationPolicyLogRecord.objects.create(
+ author=user,
+ type=UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_FAILED,
+ notification_policy=notification_policy,
+ alert_group=alert_group,
+ reason="Error while sending email",
+ notification_step=notification_policy.step,
+ notification_channel=notification_policy.notify_by,
+ notification_error_code=UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_MAIL_LIMIT_EXCEEDED,
+ )
+ EmailMessage.objects.create(
+ represents_alert_group=alert_group,
+ notification_policy=notification_policy,
+ receiver=user,
+ exceeded_limit=True,
+ )
+ return
+
+ subject, html_message = build_subject_and_message(alert_group, emails_left)
+
+ message = strip_tags(html_message)
+ email_from = settings.EMAIL_HOST_USER
+ recipient_list = [user.email]
+
+ connection = get_connection(
+ host=live_settings.EMAIL_HOST,
+ port=live_settings.EMAIL_PORT,
+ username=live_settings.EMAIL_HOST_USER,
+ password=live_settings.EMAIL_HOST_PASSWORD,
+ use_tls=live_settings.EMAIL_USE_TLS,
+ fail_silently=False,
+ timeout=5,
+ )
+
+ try:
+ send_mail(subject, message, email_from, recipient_list, html_message=html_message, connection=connection)
+ EmailMessage.objects.create(
+ represents_alert_group=alert_group,
+ notification_policy=notification_policy,
+ receiver=user,
+ exceeded_limit=False,
+ )
+ except (gaierror, BadHeaderError) as e:
+ # gaierror is raised when EMAIL_HOST is invalid
+ # BadHeaderError is raised when there's newlines in the subject
+ UserNotificationPolicyLogRecord.objects.create(
+ author=user,
+ type=UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_FAILED,
+ notification_policy=notification_policy,
+ alert_group=alert_group,
+ reason="Error while sending email",
+ notification_step=notification_policy.step,
+ notification_channel=notification_policy.notify_by,
+ )
+ logger.error(f"Error while sending email: {e}")
+ return
diff --git a/engine/apps/email/templates/email_notification.html b/engine/apps/email/templates/email_notification.html
new file mode 100644
index 00000000..86ade2bb
--- /dev/null
+++ b/engine/apps/email/templates/email_notification.html
@@ -0,0 +1,28 @@
+
+You are invited to check an alert group in Grafana OnCall!
+
+Organization: {{ organization }}
+
+Integration: {{ integration }}
+
+Title: {{ title }}
+{% if message %}
+
+Message:
+
+{% autoescape off %}
+ {{ message }}
+{% endautoescape %}
+{% endif %}
+
+Go to the alert group
+
+Your Grafana OnCall
+{% if limit_notification %}
+
+ {{ emails_left }} emails left for the organization today. Contact your admin.
+{% endif %}
+
+
+{% now "H:i.u e"%}
+
\ No newline at end of file
diff --git a/engine/apps/sendgridapp/tests/__init__.py b/engine/apps/email/tests/__init__.py
similarity index 100%
rename from engine/apps/sendgridapp/tests/__init__.py
rename to engine/apps/email/tests/__init__.py
diff --git a/engine/apps/email/tests/factories.py b/engine/apps/email/tests/factories.py
new file mode 100644
index 00000000..db86c94e
--- /dev/null
+++ b/engine/apps/email/tests/factories.py
@@ -0,0 +1,8 @@
+import factory
+
+from apps.email.models import EmailMessage
+
+
+class EmailMessageFactory(factory.DjangoModelFactory):
+ class Meta:
+ model = EmailMessage
diff --git a/engine/apps/email/tests/test_notify_user.py b/engine/apps/email/tests/test_notify_user.py
new file mode 100644
index 00000000..a6b1c356
--- /dev/null
+++ b/engine/apps/email/tests/test_notify_user.py
@@ -0,0 +1,118 @@
+import socket
+from unittest.mock import patch
+
+import pytest
+from django.core import mail
+from django.core.mail.backends.locmem import EmailBackend
+
+from apps.base.models import UserNotificationPolicy, UserNotificationPolicyLogRecord
+from apps.email.tasks import notify_user_async
+from apps.user_management.subscription_strategy.free_public_beta_subscription_strategy import (
+ FreePublicBetaSubscriptionStrategy,
+)
+
+
+@pytest.mark.django_db
+def test_notify_user(
+ settings,
+ make_organization,
+ make_user_for_organization,
+ make_token_for_organization,
+ make_alert_receive_channel,
+ make_alert_group,
+ make_alert,
+ make_user_notification_policy,
+):
+ settings.EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
+
+ organization = make_organization()
+ user = make_user_for_organization(organization)
+
+ alert_receive_channel = make_alert_receive_channel(organization)
+ alert_group = make_alert_group(alert_receive_channel)
+
+ make_alert(alert_group=alert_group, raw_request_data=alert_receive_channel.config.example_payload)
+
+ notification_policy = make_user_notification_policy(
+ user,
+ UserNotificationPolicy.Step.NOTIFY,
+ notify_by=8,
+ important=False,
+ )
+
+ notify_user_async(user.pk, alert_group.pk, notification_policy.pk)
+ assert len(mail.outbox) == 1
+
+
+@pytest.mark.django_db
+def test_notify_user_bad_smtp_host(
+ settings,
+ make_organization,
+ make_user_for_organization,
+ make_token_for_organization,
+ make_alert_receive_channel,
+ make_alert_group,
+ make_alert,
+ make_user_notification_policy,
+):
+ settings.EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
+
+ organization = make_organization()
+ user = make_user_for_organization(organization)
+
+ alert_receive_channel = make_alert_receive_channel(organization)
+ alert_group = make_alert_group(alert_receive_channel)
+
+ make_alert(alert_group=alert_group, raw_request_data=alert_receive_channel.config.example_payload)
+
+ notification_policy = make_user_notification_policy(
+ user,
+ UserNotificationPolicy.Step.NOTIFY,
+ notify_by=8,
+ important=False,
+ )
+
+ with patch.object(EmailBackend, "send_messages", side_effect=socket.gaierror):
+ notify_user_async(user.pk, alert_group.pk, notification_policy.pk)
+
+ assert len(mail.outbox) == 0
+
+ log_record = notification_policy.personal_log_records.last()
+ assert log_record.type == UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_FAILED
+
+
+@pytest.mark.django_db
+def test_notify_user_no_emails_left(
+ settings,
+ make_organization,
+ make_user_for_organization,
+ make_token_for_organization,
+ make_alert_receive_channel,
+ make_alert_group,
+ make_alert,
+ make_user_notification_policy,
+):
+ settings.EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
+
+ organization = make_organization()
+ user = make_user_for_organization(organization)
+
+ alert_receive_channel = make_alert_receive_channel(organization)
+ alert_group = make_alert_group(alert_receive_channel)
+
+ make_alert(alert_group=alert_group, raw_request_data=alert_receive_channel.config.example_payload)
+
+ notification_policy = make_user_notification_policy(
+ user,
+ UserNotificationPolicy.Step.NOTIFY,
+ notify_by=8,
+ important=False,
+ )
+
+ with patch.object(FreePublicBetaSubscriptionStrategy, "emails_left", return_value=0):
+ notify_user_async(user.pk, alert_group.pk, notification_policy.pk)
+
+ assert len(mail.outbox) == 0
+ log_record = notification_policy.personal_log_records.last()
+ assert log_record.type == UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_FAILED
+ assert log_record.notification_error_code == UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_MAIL_LIMIT_EXCEEDED
diff --git a/engine/apps/integrations/middlewares.py b/engine/apps/integrations/middlewares.py
new file mode 100644
index 00000000..87408370
--- /dev/null
+++ b/engine/apps/integrations/middlewares.py
@@ -0,0 +1,14 @@
+import logging
+
+from django.core.exceptions import PermissionDenied
+from django.http import HttpResponse
+from django.utils.deprecation import MiddlewareMixin
+from rest_framework import status
+
+logger = logging.getLogger(__name__)
+
+
+class IntegrationExceptionMiddleware(MiddlewareMixin):
+ def process_exception(self, request, exception):
+ if request.path.startswith("/integrations/v1") and isinstance(exception, PermissionDenied):
+ return HttpResponse(exception, status=status.HTTP_403_FORBIDDEN)
diff --git a/engine/apps/integrations/views.py b/engine/apps/integrations/views.py
index 4c975b15..b0f81c02 100644
--- a/engine/apps/integrations/views.py
+++ b/engine/apps/integrations/views.py
@@ -25,8 +25,6 @@ from apps.integrations.mixins import (
is_ratelimit_ignored,
)
from apps.integrations.tasks import create_alert, create_alertmanager_alerts
-from apps.sendgridapp.parse import Parse
-from apps.sendgridapp.permissions import AllowOnlySendgrid
from common.api_helpers.utils import create_engine_url
logger = logging.getLogger(__name__)
@@ -384,72 +382,8 @@ class HeartBeatAPIView(AlertChannelDefiningMixin, APIView):
class InboundWebhookEmailView(AlertChannelDefiningMixin, APIView):
- permission_classes = [AllowOnlySendgrid]
-
- def dispatch(self, *args, **kwargs):
- parse = Parse(self.request)
- self.email_data = parse.key_values()
- # When email is forwarded recipient field can be stored both in "to" and in "envelope" fields.
- token_from_to = self._parse_token_from_to(self.email_data)
- try:
- kwargs["alert_channel_key"] = token_from_to
- return super().dispatch(*args, **kwargs)
- except KeyError as e:
- logger.warning(f"InboundWebhookEmailView: {e}")
- except PermissionDenied as e:
- self._log_permission_denied(token_from_to, e)
- kwargs.pop("alert_channel_key")
-
- token_from_envelope = self._parse_token_from_envelope(self.email_data)
- try:
- kwargs["alert_channel_key"] = token_from_envelope
- return super().dispatch(*args, **kwargs)
- except KeyError as e:
- logger.warning(f"InboundWebhookEmailView: {e}")
- except PermissionDenied as e:
- self._log_permission_denied(token_from_to, e)
- kwargs.pop("alert_channel_key")
-
- raise PermissionDenied("Integration key was not found. Permission denied.")
-
- def _log_permission_denied(self, token, e):
- logger.info(
- f"InboundWebhookEmailView: Permission denied. token {token}. "
- f"To {self.email_data.get('to')}. "
- f"Envelope {self.email_data.get('envelope')}."
- f"Exception: {e}"
- )
-
- def _parse_token_from_envelope(self, email_data):
- envelope = email_data["envelope"]
- envelope = json.loads(envelope)
- token = envelope.get("to")[0].split("@")[0]
- return token
-
- def _parse_token_from_to(self, email_data):
- return email_data["to"].split("@")[0]
-
- def post(self, request, alert_receive_channel=None):
- title = self.email_data["subject"]
- message = self.email_data.get("text", "").strip()
-
- payload = {"title": title, "message": message}
-
- if alert_receive_channel:
- create_alert.apply_async(
- [],
- {
- "title": title,
- "message": message,
- "alert_receive_channel_pk": alert_receive_channel.pk,
- "image_url": None,
- "link_to_upstream_details": payload.get("link_to_upstream_details"),
- "integration_unique_data": payload,
- "raw_request_data": request.data,
- },
- )
-
- return Response("OK")
+ # todo: implement inbound emails
+ pass
class IntegrationHeartBeatAPIView(AlertChannelDefiningMixin, IntegrationHeartBeatRateLimitMixin, APIView):
diff --git a/engine/apps/public_api/serializers/action.py b/engine/apps/public_api/serializers/action.py
index f652bc7c..ab9e4740 100644
--- a/engine/apps/public_api/serializers/action.py
+++ b/engine/apps/public_api/serializers/action.py
@@ -1,4 +1,5 @@
import json
+from collections import defaultdict
from django.core.validators import URLValidator, ValidationError
from jinja2 import Template, TemplateError
@@ -55,15 +56,33 @@ class ActionCreateSerializer(serializers.ModelSerializer):
return None
try:
- json.loads(data)
- except ValueError:
- raise serializers.ValidationError("Data has incorrect format")
-
- try:
- Template(data)
+ template = Template(data)
except TemplateError:
raise serializers.ValidationError("Data has incorrect template")
+ try:
+ rendered = template.render(
+ {
+ # Validate that the template can be rendered with a JSON-ish alert payload.
+ # We don't know what the actual payload will be, so we use a defaultdict
+ # so that attribute access within a template will never fail
+ # (provided it's only one level deep - we won't accept templates that attempt
+ # to do nested attribute access).
+ # Every attribute access should return a string to ensure that users are
+ # correctly using `tojson` or wrapping fields in strings.
+ # If we instead used a `defaultdict(dict)` or `defaultdict(lambda: 1)` we
+ # would accidentally accept templates such as `{"name": {{ alert_payload.name }}}`
+ # which would then fail at the true render time due to the
+ # lack of explicit quotes around the template variable; this would render
+ # as `{"name": some_alert_name}` which is not valid JSON.
+ "alert_payload": defaultdict(str),
+ "alert_group_id": "abcd",
+ }
+ )
+ json.loads(rendered)
+ except ValueError:
+ raise serializers.ValidationError("Data has incorrect format")
+
return data
def validate_forward_whole_payload(self, data):
diff --git a/engine/apps/public_api/serializers/integrations.py b/engine/apps/public_api/serializers/integrations.py
index 899f6260..b1860b9a 100644
--- a/engine/apps/public_api/serializers/integrations.py
+++ b/engine/apps/public_api/serializers/integrations.py
@@ -5,9 +5,10 @@ from rest_framework import fields, serializers
from apps.alerts.grafana_alerting_sync_manager.grafana_alerting_sync import GrafanaAlertingSyncManager
from apps.alerts.models import AlertReceiveChannel
+from apps.base.messaging import get_messaging_backends
from common.api_helpers.custom_fields import TeamPrimaryKeyRelatedField
from common.api_helpers.exceptions import BadRequest
-from common.api_helpers.mixins import EagerLoadingMixin
+from common.api_helpers.mixins import NOTIFICATION_CHANNEL_OPTIONS, EagerLoadingMixin
from common.jinja_templater import jinja_template_env
from common.utils import timed_lru_cache
@@ -62,6 +63,9 @@ class IntegrationSerializer(EagerLoadingMixin, serializers.ModelSerializer, Main
serializer = DefaultChannelFilterSerializer(default_route, context=self.context)
result["default_route"] = serializer.data
+ # add additional templates for messaging backends
+ result["templates"].update(self._get_messaging_backend_templates(instance))
+
return result
def create(self, validated_data):
@@ -102,6 +106,8 @@ class IntegrationSerializer(EagerLoadingMixin, serializers.ModelSerializer, Main
raise BadRequest(detail="Integration with this name already exists")
def _correct_validated_data(self, validated_data):
+ validated_data = self._correct_validated_data_for_messaging_backends(validated_data)
+
templates = validated_data.pop("templates", {})
for template_name, templates_for_notification_channel in templates.items():
if type(templates_for_notification_channel) is dict:
@@ -134,7 +140,7 @@ class IntegrationSerializer(EagerLoadingMixin, serializers.ModelSerializer, Main
if not isinstance(templates, dict):
raise BadRequest(detail="Invalid template data")
- for notification_channel in ["slack", "web", "sms", "phone_call", "email", "telegram"]:
+ for notification_channel in NOTIFICATION_CHANNEL_OPTIONS:
template_data = templates.get(notification_channel, {})
if template_data is None:
continue
@@ -160,6 +166,49 @@ class IntegrationSerializer(EagerLoadingMixin, serializers.ModelSerializer, Main
raise BadRequest(detail=f"Invalid {common_template} template data")
return templates
+ def _correct_validated_data_for_messaging_backends(self, validated_data):
+ templates = validated_data.get("templates", {})
+
+ messaging_backends_templates = self.instance.messaging_backends_templates if self.instance else None
+
+ for backend_id, backend in get_messaging_backends():
+ backend_templates = {}
+ if messaging_backends_templates is not None:
+ backend_templates = messaging_backends_templates.get(backend_id, {})
+
+ for field in backend.template_fields:
+ try:
+ template = templates[backend_id.lower()][field]
+ except KeyError:
+ continue
+
+ backend_templates[field] = template
+
+ # remove backend-specific template from payload
+ templates.pop(backend_id.lower(), None)
+
+ if backend_templates:
+ validated_data["messaging_backends_templates"] = messaging_backends_templates or {} | {
+ backend_id: backend_templates
+ }
+
+ return validated_data
+
+ @staticmethod
+ def _get_messaging_backend_templates(instance):
+ result = {}
+ messaging_backends_templates = instance.messaging_backends_templates or {}
+
+ for backend_id, backend in get_messaging_backends():
+ if not backend.template_fields:
+ continue
+
+ result[backend_id.lower()] = {
+ field: messaging_backends_templates.get(backend_id, {}).get(field) for field in backend.template_fields
+ }
+
+ return result
+
def get_heartbeat(self, obj):
try:
heartbeat = obj.integration_heartbeat
diff --git a/engine/apps/public_api/tests/test_custom_actions.py b/engine/apps/public_api/tests/test_custom_actions.py
index 9fb4ebb6..7c6a55e3 100644
--- a/engine/apps/public_api/tests/test_custom_actions.py
+++ b/engine/apps/public_api/tests/test_custom_actions.py
@@ -167,6 +167,120 @@ def test_create_custom_action(make_organization_and_user_with_token):
assert response.data == expected_result
+@pytest.mark.django_db
+def test_create_custom_action_nested_data(make_organization_and_user_with_token):
+
+ organization, user, token = make_organization_and_user_with_token()
+ client = APIClient()
+
+ url = reverse("api-public:actions-list")
+
+ data = {
+ "name": "Test outgoing webhook with nested data",
+ "url": "https://example.com",
+ # Assert that nested field access still works as long as the variable
+ # is quoted, making it valid JSON.
+ # This ensures backwards compatibility from when templates were required
+ # to be JSON.
+ "data": '{"nested_item": "{{ alert_payload.foo.bar }}"}',
+ }
+
+ response = client.post(url, data=data, format="json", HTTP_AUTHORIZATION=f"{token}")
+
+ custom_action = CustomButton.objects.get(public_primary_key=response.data["id"])
+
+ expected_result = {
+ "id": custom_action.public_primary_key,
+ "name": custom_action.name,
+ "team_id": None,
+ "url": custom_action.webhook,
+ "data": custom_action.data,
+ "user": custom_action.user,
+ "password": custom_action.password,
+ "authorization_header": custom_action.authorization_header,
+ "forward_whole_payload": custom_action.forward_whole_payload,
+ }
+
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json() == expected_result
+
+
+@pytest.mark.django_db
+def test_create_custom_action_valid_after_render(make_organization_and_user_with_token):
+
+ organization, user, token = make_organization_and_user_with_token()
+ client = APIClient()
+
+ url = reverse("api-public:actions-list")
+
+ data = {
+ "name": "Test outgoing webhook with nested data",
+ "url": "https://example.com",
+ # Assert that nested field access still works as long as the variable
+ # is quoted, making it valid JSON.
+ # This ensures backwards compatibility from when templates were required
+ # to be JSON.
+ "data": '{"name": "{{ alert_payload.name }}", "labels": {{ alert_payload.labels | tojson }}}',
+ }
+
+ response = client.post(url, data=data, format="json", HTTP_AUTHORIZATION=f"{token}")
+
+ custom_action = CustomButton.objects.get(public_primary_key=response.data["id"])
+
+ expected_result = {
+ "id": custom_action.public_primary_key,
+ "name": custom_action.name,
+ "team_id": None,
+ "url": custom_action.webhook,
+ "data": custom_action.data,
+ "user": custom_action.user,
+ "password": custom_action.password,
+ "authorization_header": custom_action.authorization_header,
+ "forward_whole_payload": custom_action.forward_whole_payload,
+ }
+
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json() == expected_result
+
+
+@pytest.mark.django_db
+def test_create_custom_action_valid_after_render_use_all_data(make_organization_and_user_with_token):
+
+ organization, user, token = make_organization_and_user_with_token()
+ client = APIClient()
+
+ url = reverse("api-public:actions-list")
+
+ data = {
+ "name": "Test outgoing webhook with nested data",
+ "url": "https://example.com",
+ # Assert that nested field access still works as long as the variable
+ # is quoted, making it valid JSON.
+ # This ensures backwards compatibility from when templates were required
+ # to be JSON.
+ "data": "{{ alert_payload | tojson }}",
+ }
+
+ response = client.post(url, data=data, format="json", HTTP_AUTHORIZATION=f"{token}")
+
+ custom_action = CustomButton.objects.get(public_primary_key=response.data["id"])
+
+ expected_result = {
+ "id": custom_action.public_primary_key,
+ "name": custom_action.name,
+ "team_id": None,
+ "url": custom_action.webhook,
+ "data": custom_action.data,
+ "user": custom_action.user,
+ "password": custom_action.password,
+ "authorization_header": custom_action.authorization_header,
+ "forward_whole_payload": custom_action.forward_whole_payload,
+ }
+
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json() == expected_result
+
+
@pytest.mark.django_db
def test_create_custom_action_invalid_data(
make_organization_and_user_with_token,
@@ -205,6 +319,29 @@ def test_create_custom_action_invalid_data(
assert response.status_code == status.HTTP_400_BAD_REQUEST
assert response.data["name"][0] == "This field is required."
+ data = {
+ "name": "Test outgoing webhook",
+ "url": "https://example.com",
+ "data": "invalid_json",
+ }
+
+ response = client.post(url, data=data, format="json", HTTP_AUTHORIZATION=f"{token}")
+
+ assert response.status_code == status.HTTP_400_BAD_REQUEST
+ assert response.data["data"][0] == "Data has incorrect format"
+
+ data = {
+ "name": "Test outgoing webhook",
+ "url": "https://example.com",
+ # This would need a `| tojson` or some double quotes around it to pass validation.
+ "data": "{{ alert_payload.name }}",
+ }
+
+ response = client.post(url, data=data, format="json", HTTP_AUTHORIZATION=f"{token}")
+
+ assert response.status_code == status.HTTP_400_BAD_REQUEST
+ assert response.data["data"][0] == "Data has incorrect format"
+
@pytest.mark.django_db
def test_update_custom_action(
diff --git a/engine/apps/public_api/tests/test_integrations.py b/engine/apps/public_api/tests/test_integrations.py
index de992a16..22756022 100644
--- a/engine/apps/public_api/tests/test_integrations.py
+++ b/engine/apps/public_api/tests/test_integrations.py
@@ -54,11 +54,12 @@ def test_get_list_integrations(
"phone_call": {
"title": None,
},
- "email": {
+ "telegram": {
"title": None,
"message": None,
+ "image_url": None,
},
- "telegram": {
+ TEST_MESSAGING_BACKEND_FIELD: {
"title": None,
"message": None,
"image_url": None,
@@ -117,7 +118,6 @@ def test_create_integrations_with_none_templates(
"web": None,
"sms": None,
"phone_call": None,
- "email": None,
"telegram": None,
},
}
@@ -184,15 +184,76 @@ def test_update_integration_template(
"phone_call": {
"title": None,
},
- "email": {
+ "telegram": {
"title": None,
"message": None,
+ "image_url": None,
+ },
+ TEST_MESSAGING_BACKEND_FIELD: {
+ "title": None,
+ "message": None,
+ "image_url": None,
+ },
+ },
+ "maintenance_mode": None,
+ "maintenance_started_at": None,
+ "maintenance_end_at": None,
+ }
+ url = reverse("api-public:integrations-detail", args=[integration.public_primary_key])
+ response = client.put(url, data=data_for_update, format="json", HTTP_AUTHORIZATION=f"{token}")
+ assert response.status_code == status.HTTP_200_OK
+ assert response.data == expected_response
+
+
+@pytest.mark.django_db
+def test_update_integration_template_messaging_backend(
+ make_organization_and_user_with_token, make_alert_receive_channel, make_channel_filter, make_integration_heartbeat
+):
+ organization, user, token = make_organization_and_user_with_token()
+ integration = make_alert_receive_channel(organization, verbal_name="grafana")
+ default_channel_filter = make_channel_filter(integration, is_default=True)
+ make_integration_heartbeat(integration)
+
+ client = APIClient()
+ data_for_update = {"templates": {"grouping_key": "ip_addr", TEST_MESSAGING_BACKEND_FIELD: {"title": "Incident"}}}
+ expected_response = {
+ "id": integration.public_primary_key,
+ "team_id": None,
+ "name": "grafana",
+ "link": integration.integration_url,
+ "type": "grafana",
+ "default_route": {
+ "escalation_chain_id": None,
+ "id": default_channel_filter.public_primary_key,
+ "slack": {"channel_id": None, "enabled": True},
+ "telegram": {"id": None, "enabled": False},
+ TEST_MESSAGING_BACKEND_FIELD: {"id": None, "enabled": False},
+ },
+ "heartbeat": {
+ "link": f"{integration.integration_url}heartbeat/",
+ },
+ "templates": {
+ "grouping_key": "ip_addr",
+ "resolve_signal": None,
+ "acknowledge_signal": None,
+ "slack": {"title": None, "message": None, "image_url": None},
+ "web": {"title": None, "message": None, "image_url": None},
+ "sms": {
+ "title": None,
+ },
+ "phone_call": {
+ "title": None,
},
"telegram": {
"title": None,
"message": None,
"image_url": None,
},
+ TEST_MESSAGING_BACKEND_FIELD: {
+ "title": "Incident",
+ "message": None,
+ "image_url": None,
+ },
},
"maintenance_mode": None,
"maintenance_started_at": None,
@@ -259,11 +320,12 @@ def test_update_resolve_signal_template(
"phone_call": {
"title": None,
},
- "email": {
+ "telegram": {
"title": None,
"message": None,
+ "image_url": None,
},
- "telegram": {
+ TEST_MESSAGING_BACKEND_FIELD: {
"title": None,
"message": None,
"image_url": None,
@@ -366,11 +428,12 @@ def test_update_sms_template_with_empty_dict(
"phone_call": {
"title": None,
},
- "email": {
+ "telegram": {
"title": None,
"message": None,
+ "image_url": None,
},
- "telegram": {
+ TEST_MESSAGING_BACKEND_FIELD: {
"title": None,
"message": None,
"image_url": None,
@@ -425,11 +488,12 @@ def test_update_integration_name(
"phone_call": {
"title": None,
},
- "email": {
+ "telegram": {
"title": None,
"message": None,
+ "image_url": None,
},
- "telegram": {
+ TEST_MESSAGING_BACKEND_FIELD: {
"title": None,
"message": None,
"image_url": None,
@@ -487,11 +551,12 @@ def test_set_default_template(
"phone_call": {
"title": None,
},
- "email": {
+ "telegram": {
"title": None,
"message": None,
+ "image_url": None,
},
- "telegram": {
+ TEST_MESSAGING_BACKEND_FIELD: {
"title": None,
"message": None,
"image_url": None,
diff --git a/engine/apps/schedules/ical_utils.py b/engine/apps/schedules/ical_utils.py
index ac8f9596..3e6756cd 100644
--- a/engine/apps/schedules/ical_utils.py
+++ b/engine/apps/schedules/ical_utils.py
@@ -42,13 +42,13 @@ def users_in_ical(usernames_from_ical, organization, include_viewers=False):
Parse ical file and return list of users found
"""
# Only grafana username will be used, consider adding grafana email and id
-
users_found_in_ical = organization.users
if not include_viewers:
users_found_in_ical = users_found_in_ical.filter(role__in=(Role.ADMIN, Role.EDITOR))
+ user_emails = [v.lower() for v in usernames_from_ical]
users_found_in_ical = users_found_in_ical.filter(
- (Q(username__in=usernames_from_ical) | Q(email__in=usernames_from_ical))
+ (Q(username__in=usernames_from_ical) | Q(email__lower__in=user_emails))
).distinct()
# Here is the example how we extracted users previously, using slack fields too
@@ -394,8 +394,8 @@ def get_missing_users_from_ical_event(event, organization):
all_usernames, _ = get_usernames_from_ical_event(event)
users = list(get_users_from_ical_event(event, organization))
found_usernames = [u.username for u in users]
- found_emails = [u.email for u in users]
- return [u for u in all_usernames if u != "" and u not in found_usernames and u not in found_emails]
+ found_emails = [u.email.lower() for u in users]
+ return [u for u in all_usernames if u != "" and u not in found_usernames and u.lower() not in found_emails]
def get_users_from_ical_event(event, organization):
@@ -536,7 +536,8 @@ def get_user_events_from_calendars(ical_obj: Calendar, calendars: tuple, user: U
for component in calendar.walk():
if component.name == "VEVENT":
event_user = get_usernames_from_ical_event(component)
- if event_user[0][0] in [user.username, user.email]:
+ event_user_value = event_user[0][0]
+ if event_user_value == user.username or event_user_value.lower() == user.email.lower():
ical_obj.add_component(component)
diff --git a/engine/apps/schedules/tests/test_ical_utils.py b/engine/apps/schedules/tests/test_ical_utils.py
index f6bc2155..b1d7171f 100644
--- a/engine/apps/schedules/tests/test_ical_utils.py
+++ b/engine/apps/schedules/tests/test_ical_utils.py
@@ -15,6 +15,16 @@ from apps.schedules.models import CustomOnCallShift, OnCallScheduleCalendar
from common.constants.role import Role
+@pytest.mark.django_db
+def test_users_in_ical_email_case_insensitive(make_organization_and_user, make_user_for_organization):
+ organization, user = make_organization_and_user()
+ user = make_user_for_organization(organization, username="foo", email="TestingUser@test.com")
+
+ usernames = ["testinguser@test.com"]
+ result = users_in_ical(usernames, organization)
+ assert set(result) == {user}
+
+
@pytest.mark.django_db
@pytest.mark.parametrize(
"include_viewers",
diff --git a/engine/apps/sendgridapp/constants.py b/engine/apps/sendgridapp/constants.py
deleted file mode 100644
index b6d84793..00000000
--- a/engine/apps/sendgridapp/constants.py
+++ /dev/null
@@ -1,49 +0,0 @@
-class SendgridEmailMessageStatuses(object):
- """
- https://sendgrid.com/docs/for-developers/tracking-events/event/#delivery-events
- """
-
- # Delivery events
- ACCEPTED = 10
- PROCESSED = 20
- DEFERRED = 30
- DELIVERED = 40
- DROPPED = 50
- BOUNCE = 60 # "event": "bounce", "type: "bounce"
- BLOCKED = 70 # "event": "bounce", "type: "blocked"
-
- # Engagement events
- OPEN = 80
- CLICK = 90
- UNSUBSCRIBE = 100
- SPAMREPORT = 110
- # Group Unsubscribe - ?
- # Group Resubscribe - ?
-
- CHOICES = (
- (ACCEPTED, "accepted"),
- (PROCESSED, "processed"),
- (DEFERRED, "deferred"),
- (DELIVERED, "delivered"),
- (DROPPED, "dropped"),
- (BOUNCE, "bounce"),
- (BLOCKED, "blocked"),
- (OPEN, "open"),
- (CLICK, "click"),
- (UNSUBSCRIBE, "unsubscribe"),
- (SPAMREPORT, "spamreport"),
- )
-
- DETERMINANT = {
- "accepted": ACCEPTED,
- "processed": PROCESSED,
- "deferred": DEFERRED,
- "delivered": DELIVERED,
- "dropped": DROPPED,
- "bounce": BOUNCE,
- "blocked": BLOCKED,
- "open": OPEN,
- "click": CLICK,
- "unsubscribe": UNSUBSCRIBE,
- "spamreport": SPAMREPORT,
- }
diff --git a/engine/apps/sendgridapp/models.py b/engine/apps/sendgridapp/models.py
deleted file mode 100644
index cd717165..00000000
--- a/engine/apps/sendgridapp/models.py
+++ /dev/null
@@ -1,185 +0,0 @@
-import logging
-import uuid
-
-from django.apps import apps
-from django.db import models
-from python_http_client.exceptions import BadRequestsError, ForbiddenError, UnauthorizedError
-from sendgrid import SendGridAPIClient
-from sendgrid.helpers.mail import CustomArg, Mail
-
-from apps.alerts.incident_appearance.renderers.email_renderer import AlertGroupEmailRenderer
-from apps.alerts.signals import user_notification_action_triggered_signal
-from apps.base.utils import live_settings
-from apps.sendgridapp.constants import SendgridEmailMessageStatuses
-
-logger = logging.getLogger(__name__)
-
-
-class EmailMessageManager(models.Manager):
- def update_status(self, message_uuid, message_status):
- """The function checks existence of EmailMessage
- instance according to message_uuid and updates status on
- message_status
-
- Args:
- message_uuid (str): uuid of Email message
- message_status (str): new status
-
- Returns:
-
- """
- UserNotificationPolicyLogRecord = apps.get_model("base", "UserNotificationPolicyLogRecord")
-
- if message_uuid and message_status:
- email_message_qs = self.filter(message_uuid=message_uuid)
- status = SendgridEmailMessageStatuses.DETERMINANT.get(message_status)
-
- if email_message_qs.exists() and status:
- email_message_qs.update(status=status)
-
- email_message = email_message_qs.first()
- log_record = None
-
- if status == SendgridEmailMessageStatuses.DELIVERED:
- log_record = UserNotificationPolicyLogRecord(
- author=email_message.receiver,
- type=UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_SUCCESS,
- notification_policy=email_message.notification_policy,
- alert_group=email_message.represents_alert_group,
- notification_step=email_message.notification_policy.step
- if email_message.notification_policy
- else None,
- notification_channel=email_message.notification_policy.notify_by
- if email_message.notification_policy
- else None,
- )
- elif status in [
- SendgridEmailMessageStatuses.BOUNCE,
- SendgridEmailMessageStatuses.BLOCKED,
- SendgridEmailMessageStatuses.DROPPED,
- ]:
- log_record = UserNotificationPolicyLogRecord(
- author=email_message.receiver,
- type=UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_FAILED,
- notification_policy=email_message.notification_policy,
- alert_group=email_message.represents_alert_group,
- notification_error_code=email_message.get_error_code_by_sendgrid_status(status),
- notification_step=email_message.notification_policy.step
- if email_message.notification_policy
- else None,
- notification_channel=email_message.notification_policy.notify_by
- if email_message.notification_policy
- else None,
- )
- if log_record is not None:
- log_record.save()
- user_notification_action_triggered_signal.send(
- sender=EmailMessage.objects.update_status, log_record=log_record
- )
-
-
-class EmailMessage(models.Model):
- objects = EmailMessageManager()
-
- message_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
-
- exceeded_limit = models.BooleanField(null=True, default=None)
- represents_alert = models.ForeignKey("alerts.Alert", on_delete=models.SET_NULL, null=True, default=None)
- represents_alert_group = models.ForeignKey("alerts.AlertGroup", on_delete=models.SET_NULL, null=True, default=None)
- notification_policy = models.ForeignKey(
- "base.UserNotificationPolicy", on_delete=models.SET_NULL, null=True, default=None
- )
-
- receiver = models.ForeignKey("user_management.User", on_delete=models.PROTECT, null=True, default=None)
-
- status = models.PositiveSmallIntegerField(blank=True, null=True, choices=SendgridEmailMessageStatuses.CHOICES)
-
- created_at = models.DateTimeField(auto_now_add=True)
-
- @staticmethod
- def send_incident_mail(user, alert_group, notification_policy):
- UserNotificationPolicyLogRecord = apps.get_model("base", "UserNotificationPolicyLogRecord")
-
- log_record = None
- alert = alert_group.alerts.first()
-
- email_message = EmailMessage(
- represents_alert_group=alert_group,
- represents_alert=alert,
- receiver=user,
- notification_policy=notification_policy,
- )
- emails_left = alert_group.channel.organization.emails_left(user)
- if emails_left > 0:
- email_message.exceeded_limit = False
-
- limit_notification = False
- if emails_left < 5:
- limit_notification = True
-
- subject, html_content = AlertGroupEmailRenderer(alert_group).render(limit_notification)
-
- message = Mail(
- from_email=live_settings.SENDGRID_FROM_EMAIL,
- to_emails=user.email,
- subject=subject,
- html_content=html_content,
- )
- custom_arg = CustomArg("message_uuid", str(email_message.message_uuid))
- message.add_custom_arg(custom_arg)
-
- sendgrid_client = SendGridAPIClient(live_settings.SENDGRID_API_KEY)
- try:
- response = sendgrid_client.send(message)
- sending_status = True
- except (BadRequestsError, UnauthorizedError, ForbiddenError) as e:
- logger.error(f"Error email sending: {e}")
- sending_status = False
- else:
- if response.status_code == 202:
- email_message.status = SendgridEmailMessageStatuses.ACCEPTED
- email_message.save()
- else:
- logger.error(f"Error email sending: status code: {response.status_code}")
- sending_status = False
-
- if not sending_status:
- log_record = UserNotificationPolicyLogRecord(
- author=user,
- type=UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_FAILED,
- notification_policy=notification_policy,
- alert_group=alert_group,
- notification_error_code=UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_NOT_ABLE_TO_SEND_MAIL,
- notification_step=notification_policy.step if notification_policy else None,
- notification_channel=notification_policy.notify_by if notification_policy else None,
- )
- else:
- log_record = UserNotificationPolicyLogRecord(
- author=user,
- type=UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_FAILED,
- notification_policy=notification_policy,
- alert_group=alert_group,
- notification_error_code=UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_MAIL_LIMIT_EXCEEDED,
- notification_step=notification_policy.step if notification_policy else None,
- notification_channel=notification_policy.notify_by if notification_policy else None,
- )
- email_message.exceeded_limit = True
- email_message.save()
-
- if log_record is not None:
- log_record.save()
- user_notification_action_triggered_signal.send(
- sender=EmailMessage.send_incident_mail, log_record=log_record
- )
-
- @staticmethod
- def get_error_code_by_sendgrid_status(status):
- UserNotificationPolicyLogRecord = apps.get_model("base", "UserNotificationPolicyLogRecord")
-
- SENDGRID_ERRORS_TO_ERROR_CODES_MAP = {
- SendgridEmailMessageStatuses.BOUNCE: UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_MAIL_DELIVERY_FAILED,
- SendgridEmailMessageStatuses.BLOCKED: UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_MAIL_DELIVERY_FAILED,
- SendgridEmailMessageStatuses.DROPPED: UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_MAIL_DELIVERY_FAILED,
- }
-
- return SENDGRID_ERRORS_TO_ERROR_CODES_MAP.get(status, None)
diff --git a/engine/apps/sendgridapp/parse.py b/engine/apps/sendgridapp/parse.py
deleted file mode 100644
index 55cc939c..00000000
--- a/engine/apps/sendgridapp/parse.py
+++ /dev/null
@@ -1,119 +0,0 @@
-import base64
-import email
-import mimetypes
-
-from six import iteritems
-from werkzeug.utils import secure_filename
-
-
-class Parse(object):
- """Parse data received from the SendGrid Inbound Parse webhook.
- It's based on https://github.com/sendgrid/sendgrid-python/blob/master/sendgrid/helpers/inbound/parse.py
- """
-
- def __init__(self, request):
- self._keys = [
- "attachments",
- "headers",
- "text",
- "envelope",
- "to",
- "html",
- "sender_ip",
- "attachment-info",
- "subject",
- "dkim",
- "SPF",
- "charsets",
- "content-ids",
- "spam_report",
- "spam_score",
- "email",
- ]
- self._request = request
- self._payload = request.POST.dict()
- self._raw_payload = request.POST
-
- def key_values(self):
- """
- Return a dictionary of key/values in the payload received from
- the webhook
- """
- key_values = {}
- for key in self.keys:
- if key in self.payload:
- key_values[key] = self.payload[key]
- return key_values
-
- def get_raw_email(self):
- """
- This only applies to raw payloads:
- https://sendgrid.com/docs/Classroom/Basics/Inbound_Parse_Webhook/setting_up_the_inbound_parse_webhook.html#-Raw-Parameters
- """
- if "email" in self.payload:
- raw_email = email.message_from_string(self.payload["email"])
- return raw_email
- else:
- return None
-
- def attachments(self):
- """Returns an object with:
- type = file content type
- file_name = the name of the file
- contents = base64 encoded file contents"""
- attachments = None
- if "attachment-info" in self.payload:
- attachments = self._get_attachments(self.request)
- # Check if we have a raw message
- raw_email = self.get_raw_email()
- if raw_email is not None:
- attachments = self._get_attachments_raw(raw_email)
- return attachments
-
- def _get_attachments(self, request):
- attachments = []
- for _, filestorage in iteritems(request.files):
- attachment = {}
- if filestorage.filename not in (None, "fdopen", ""):
- filename = secure_filename(filestorage.filename)
- attachment["type"] = filestorage.content_type
- attachment["file_name"] = filename
- attachment["contents"] = base64.b64encode(filestorage.read())
- attachments.append(attachment)
- return attachments
-
- def _get_attachments_raw(self, raw_email):
- attachments = []
- counter = 1
- for part in raw_email.walk():
- attachment = {}
- if part.get_content_maintype() == "multipart":
- continue
- filename = part.get_filename()
- if not filename:
- ext = mimetypes.guess_extension(part.get_content_type())
- if not ext:
- ext = ".bin"
- filename = "part-%03d%s" % (counter, ext)
- counter += 1
- attachment["type"] = part.get_content_type()
- attachment["file_name"] = filename
- attachment["contents"] = part.get_payload(decode=False)
- attachments.append(attachment)
- return attachments
-
- @property
- def keys(self):
- return self._keys
-
- @property
- def request(self):
- return self._request
-
- @property
- def payload(self):
- return self._payload
-
- @property
- def raw_payload(self):
- return self._raw_payload
diff --git a/engine/apps/sendgridapp/permissions.py b/engine/apps/sendgridapp/permissions.py
deleted file mode 100644
index 7c2206e3..00000000
--- a/engine/apps/sendgridapp/permissions.py
+++ /dev/null
@@ -1,14 +0,0 @@
-from rest_framework.permissions import BasePermission
-
-from apps.base.utils import live_settings
-
-
-class AllowOnlySendgrid(BasePermission):
- def has_permission(self, request, view):
- # https://stackoverflow.com/questions/20865673/sendgrid-incoming-mail-webhook-how-do-i-secure-my-endpoint
- sendgrid_key = request.query_params.get("key")
-
- if sendgrid_key is None:
- return False
-
- return live_settings.SENDGRID_SECRET_KEY == sendgrid_key
diff --git a/engine/apps/sendgridapp/templates/email_notification.html b/engine/apps/sendgridapp/templates/email_notification.html
deleted file mode 100644
index e591944d..00000000
--- a/engine/apps/sendgridapp/templates/email_notification.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-{% now "H:i.u e"%}
-
-You are invited to check Incident
-
-{{ title }}
-{% if message %}
- {{ message|linebreaks }}
-{% endif %}
-{# #}
-{# #}
-Amixr team: {{ amixr_team }}
-
-Alert channel: {{ alert_channel }}
-
-Check Incident
-
-Your Amixr.IO
-{% if limit_notification %}
-
- {{ emails_left }} mail(s) left for this week. Contact your admin.
-{% endif %}
-
-{% now "H:i.u e"%}
-
\ No newline at end of file
diff --git a/engine/apps/sendgridapp/templates/email_verification.html b/engine/apps/sendgridapp/templates/email_verification.html
deleted file mode 100644
index 468daf41..00000000
--- a/engine/apps/sendgridapp/templates/email_verification.html
+++ /dev/null
@@ -1,15 +0,0 @@
-
-{% now "H:i.u e"%}
-
-Welcome to OnCall!
-
-To verify your email address, please click the button below. If you did not sign up for OnCall, please ignore this email.
-
-Confirm email
-
-Thanks,
-
-OnCall Team
-
-{% now "H:i.u e"%}
-
\ No newline at end of file
diff --git a/engine/apps/sendgridapp/tests/factories.py b/engine/apps/sendgridapp/tests/factories.py
deleted file mode 100644
index e27fd458..00000000
--- a/engine/apps/sendgridapp/tests/factories.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# import factory
-#
-# from apps.sendgridapp.models import EmailMessage
-#
-#
-# class EmailMessageFactory(factory.DjangoModelFactory):
-# class Meta:
-# model = EmailMessage
diff --git a/engine/apps/sendgridapp/tests/test_emails.py b/engine/apps/sendgridapp/tests/test_emails.py
deleted file mode 100644
index 7d29c428..00000000
--- a/engine/apps/sendgridapp/tests/test_emails.py
+++ /dev/null
@@ -1,135 +0,0 @@
-# from unittest.mock import patch
-#
-# import pytest
-# from django.urls import reverse
-# from django.utils import timezone
-# from rest_framework.test import APIClient
-#
-# from apps.sendgridapp.constants import SendgridEmailMessageStatuses
-# from apps.sendgridapp.verification_token import email_verification_token_generator
-#
-#
-# @pytest.mark.skip(reason="email disabled")
-# @pytest.mark.django_db
-# def test_email_verification(
-# make_team,
-# make_user_for_team,
-# make_email_message,
-# make_alert_receive_channel,
-# make_alert_group,
-# ):
-# amixr_team = make_team()
-# admin = make_user_for_team(amixr_team, role=ROLE_ADMIN)
-# alert_receive_channel = make_alert_receive_channel(amixr_team)
-# alert_group = make_alert_group(alert_receive_channel)
-# make_email_message(
-# receiver=admin, status=SendgridEmailMessageStatuses.ACCEPTED, represents_alert_group=alert_group
-# ),
-# client = APIClient()
-# correct_token = email_verification_token_generator.make_token(admin)
-# url = reverse("sendgridapp:verify_email", kwargs={"token": correct_token, "uid": admin.pk, "slackteam": None})
-# response = client.get(url, content_type="application/json")
-# assert response.status_code == 200
-# admin.refresh_from_db()
-# assert admin.email_verified is True
-#
-#
-# @pytest.mark.skip(reason="email disabled")
-# @pytest.mark.django_db
-# def test_email_verification_incorrect_token(
-# make_team,
-# make_user_for_team,
-# make_email_message,
-# make_alert_receive_channel,
-# make_alert_group,
-# ):
-# amixr_team = make_team()
-# admin = make_user_for_team(amixr_team, role=ROLE_ADMIN)
-# alert_receive_channel = make_alert_receive_channel(amixr_team)
-# alert_group = make_alert_group(alert_receive_channel)
-# make_email_message(
-# receiver=admin, status=SendgridEmailMessageStatuses.ACCEPTED, represents_alert_group=alert_group
-# ),
-#
-# client = APIClient()
-# url = reverse("sendgridapp:verify_email", kwargs={"token": "incorrect_token", "uid": admin.pk, "slackteam": None})
-#
-# response = client.get(path=url, content_type="application/json")
-# assert response.status_code == 403
-# admin.refresh_from_db()
-# assert admin.email_verified is False
-#
-#
-# @pytest.mark.skip(reason="email disabled")
-# @pytest.mark.django_db
-# def test_email_verification_incorrect_uid(
-# make_team,
-# make_user_for_team,
-# make_email_message,
-# make_alert_receive_channel,
-# make_alert_group,
-# ):
-# amixr_team = make_team()
-# admin = make_user_for_team(amixr_team, role=ROLE_ADMIN)
-# alert_receive_channel = make_alert_receive_channel(amixr_team)
-# alert_group = make_alert_group(alert_receive_channel)
-# make_email_message(
-# receiver=admin, status=SendgridEmailMessageStatuses.ACCEPTED, represents_alert_group=alert_group
-# ),
-# client = APIClient()
-#
-# correct_token = email_verification_token_generator.make_token(admin)
-# url = reverse(
-# "sendgridapp:verify_email", kwargs={"token": correct_token, "uid": 100, "slackteam": None} # incorrect user uid
-# )
-# response = client.get(path=url, content_type="application/json")
-# assert response.status_code == 403
-# admin.refresh_from_db()
-# assert admin.email_verified is False
-#
-#
-# @pytest.mark.skip(reason="email disabled")
-# @patch("apps.integrations.helpers.inbound_emails.AllowOnlySendgrid.has_permission", return_value=True)
-# @patch(
-# "apps.slack.helpers.slack_client.SlackClientWithErrorHandling.api_call",
-# return_value={"ok": True, "ts": timezone.now().timestamp()},
-# )
-# @pytest.mark.django_db
-# @pytest.mark.parametrize("status", ["delivered", "bounce", "dropped"])
-# def test_update_email_status(
-# mocked_slack_api_call,
-# mocked_sendgrid_permission,
-# make_team,
-# make_user_for_team,
-# make_email_message,
-# make_alert_receive_channel,
-# make_alert_group,
-# status,
-# ):
-# """The test for Email message status update via api"""
-# amixr_team = make_team()
-# admin = make_user_for_team(amixr_team, role=ROLE_ADMIN)
-# alert_receive_channel = make_alert_receive_channel(amixr_team)
-# alert_group = make_alert_group(alert_receive_channel)
-# email_message = make_email_message(
-# receiver=admin, status=SendgridEmailMessageStatuses.ACCEPTED, represents_alert_group=alert_group
-# )
-# client = APIClient()
-# url = reverse("sendgridapp:email_status_event")
-#
-# data = [
-# {
-# "message_uuid": str(email_message.message_uuid),
-# "event": status,
-# }
-# ]
-# response = client.post(
-# url,
-# data,
-# format="json",
-# )
-#
-# assert response.status_code == 204
-# assert response.data == ""
-# email_message.refresh_from_db()
-# assert email_message.status == SendgridEmailMessageStatuses.DETERMINANT[status]
diff --git a/engine/apps/sendgridapp/urls.py b/engine/apps/sendgridapp/urls.py
deleted file mode 100644
index 1419df32..00000000
--- a/engine/apps/sendgridapp/urls.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from django.urls import path
-
-from apps.sendgridapp.views import EmailStatusCallback
-
-app_name = "sendgridapp"
-
-urlpatterns = [
- path(r"email_status_event/", EmailStatusCallback.as_view(), name="email_status_event"),
-]
diff --git a/engine/apps/sendgridapp/verification_token.py b/engine/apps/sendgridapp/verification_token.py
deleted file mode 100644
index 3efc97c7..00000000
--- a/engine/apps/sendgridapp/verification_token.py
+++ /dev/null
@@ -1,20 +0,0 @@
-"""Based on example https://simpleisbetterthancomplex.com/tutorial/2016/08/24/how-to-create-one-time-link.html"""
-
-from django.conf import settings
-from django.contrib.auth.tokens import PasswordResetTokenGenerator
-
-
-class EmailVerificationTokenGenerator(PasswordResetTokenGenerator):
- # There are the default setting of PASSWORD_RESET_TIMEOUT_DAYS = 3 (days)
-
- key_salt = "EmailVerificationTokenGenerator" + settings.TOKEN_SALT
- secret = settings.TOKEN_SECRET
-
- def _make_hash_value(self, user, timestamp):
- team_datetime_timestamp = (
- "" if user.teams.first() is None else user.teams.first().datetime.replace(microsecond=0, tzinfo=None)
- )
- return str(user.pk) + str(timestamp) + str(team_datetime_timestamp) + str(user.email_verified)
-
-
-email_verification_token_generator = EmailVerificationTokenGenerator()
diff --git a/engine/apps/sendgridapp/views.py b/engine/apps/sendgridapp/views.py
deleted file mode 100644
index 538df2d8..00000000
--- a/engine/apps/sendgridapp/views.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import logging
-
-from django.apps import apps
-from rest_framework import status
-from rest_framework.response import Response
-from rest_framework.views import APIView
-
-from apps.sendgridapp.permissions import AllowOnlySendgrid
-
-logger = logging.getLogger(__name__)
-
-
-# Receive Email Status Update from Sendgrid
-class EmailStatusCallback(APIView):
- # https://sendgrid.com/docs/for-developers/tracking-events/event/#delivery-events
- permission_classes = [AllowOnlySendgrid]
-
- def post(self, request):
- for data in request.data:
- message_uuid = data.get("message_uuid")
- message_status = data.get("event")
- if message_status is not None and "type" in message_status:
- message_status = message_status["type"]
- logger.info(f"UUID: {message_uuid}, Status: {message_status}")
-
- EmailMessage = apps.get_model("sendgridapp", "EmailMessage")
- EmailMessage.objects.update_status(message_uuid=message_uuid, message_status=message_status)
-
- return Response(data="", status=status.HTTP_204_NO_CONTENT)
diff --git a/engine/apps/slack/scenarios/alertgroup_appearance.py b/engine/apps/slack/scenarios/alertgroup_appearance.py
index 8a335fcd..7526843f 100644
--- a/engine/apps/slack/scenarios/alertgroup_appearance.py
+++ b/engine/apps/slack/scenarios/alertgroup_appearance.py
@@ -90,7 +90,7 @@ class OpenAlertAppearanceDialogStep(
blocks.append(block)
blocks.append({"type": "divider"})
- for notification_channel in ["slack", "web", "sms", "phone_call", "email", "telegram"]:
+ for notification_channel in ["slack", "web", "sms", "phone_call", "telegram"]:
blocks.append(
{
"type": "header",
@@ -236,7 +236,7 @@ class UpdateAppearanceStep(scenario_step.ScenarioStep):
prev_state = alert_receive_channel.insight_logs_serialized
for templatizable_attr in ["title", "message", "image_url"]:
- for notification_channel in ["slack", "web", "sms", "phone_call", "email", "telegram"]:
+ for notification_channel in ["slack", "web", "sms", "phone_call", "telegram"]:
attr_name = f"{notification_channel}_{templatizable_attr}_template"
try:
old_value = getattr(alert_receive_channel, attr_name)
diff --git a/engine/apps/slack/scenarios/resolution_note.py b/engine/apps/slack/scenarios/resolution_note.py
index c22a14ad..e7ee417d 100644
--- a/engine/apps/slack/scenarios/resolution_note.py
+++ b/engine/apps/slack/scenarios/resolution_note.py
@@ -358,7 +358,7 @@ class UpdateResolutionNoteStep(scenario_step.ScenarioStep):
author_verbal = resolution_note.author_verbal(mention=True)
resolution_note_text_block = {
"type": "section",
- "text": {"type": "plain_text", "text": resolution_note.text, "emoji": True},
+ "text": {"type": "mrkdwn", "text": resolution_note.text},
}
blocks.append(resolution_note_text_block)
context_block = {
diff --git a/engine/apps/telegram/models/verification/channel.py b/engine/apps/telegram/models/verification/channel.py
index ef8e8b77..8d80f03a 100644
--- a/engine/apps/telegram/models/verification/channel.py
+++ b/engine/apps/telegram/models/verification/channel.py
@@ -23,26 +23,39 @@ class TelegramChannelVerificationCode(models.Model):
def is_active(self) -> bool:
return self.datetime + timezone.timedelta(days=1) < timezone.now()
+ @property
+ def uuid_with_org_id(self) -> str:
+ return f"{self.organization.public_primary_key}_{self.uuid}"
+
+ @classmethod
+ def uuid_without_org_id(cls, verification_code: str) -> str:
+ try:
+ return verification_code.split("_")[1]
+ except IndexError:
+ raise ValidationError("Invalid verification code format")
+
@classmethod
def verify_channel_and_discussion_group(
cls,
- uuid_code: str,
+ verification_code: str,
channel_chat_id: int,
channel_name: str,
discussion_group_chat_id: int,
discussion_group_name: str,
) -> Tuple[Optional[TelegramToOrganizationConnector], bool]:
try:
- verification_code = cls.objects.get(uuid=uuid_code)
+ uuid_code = cls.uuid_without_org_id(verification_code)
+
+ code_instance = cls.objects.get(uuid=uuid_code)
# see if a organization has other channels connected
# if it is the first channel, make it default for the organization
- connector_exists = verification_code.organization.telegram_channel.exists()
+ connector_exists = code_instance.organization.telegram_channel.exists()
connector, created = TelegramToOrganizationConnector.objects.get_or_create(
channel_chat_id=channel_chat_id,
defaults={
- "organization": verification_code.organization,
+ "organization": code_instance.organization,
"channel_name": channel_name,
"discussion_group_chat_id": discussion_group_chat_id,
"discussion_group_name": discussion_group_name,
@@ -51,14 +64,14 @@ class TelegramChannelVerificationCode(models.Model):
)
write_chatops_insight_log(
- author=verification_code.author,
+ author=code_instance.author,
event_name=ChatOpsEvent.CHANNEL_CONNECTED,
chatops_type=ChatOpsType.TELEGRAM,
channel_name=channel_name,
)
if not connector_exists:
write_chatops_insight_log(
- author=verification_code.author,
+ author=code_instance.author,
event_name=ChatOpsEvent.DEFAULT_CHANNEL_CHANGED,
chatops_type=ChatOpsType.TELEGRAM,
prev_channel=None,
diff --git a/engine/apps/telegram/models/verification/personal.py b/engine/apps/telegram/models/verification/personal.py
index 43823312..299c9993 100644
--- a/engine/apps/telegram/models/verification/personal.py
+++ b/engine/apps/telegram/models/verification/personal.py
@@ -21,13 +21,26 @@ class TelegramVerificationCode(models.Model):
def is_active(self) -> bool:
return self.datetime + timezone.timedelta(days=1) < timezone.now()
+ @property
+ def uuid_with_org_id(self) -> str:
+ return f"{self.user.organization.public_primary_key}_{self.uuid}"
+
+ @classmethod
+ def uuid_without_org_id(cls, verification_code: str) -> str:
+ try:
+ return verification_code.split("_")[1]
+ except IndexError:
+ raise ValidationError("Invalid verification code format")
+
@classmethod
def verify_user(
- cls, uuid_code: str, telegram_chat_id: int, telegram_nick_name: str
+ cls, verification_code: str, telegram_chat_id: int, telegram_nick_name: str
) -> Tuple[Optional[TelegramToUserConnector], bool]:
try:
- verification_code = cls.objects.get(uuid=uuid_code)
- user = verification_code.user
+ uuid_code = cls.uuid_without_org_id(verification_code)
+ code_instance = cls.objects.get(uuid=uuid_code)
+
+ user = code_instance.user
connector, created = TelegramToUserConnector.objects.get_or_create(
user=user, defaults={"telegram_nick_name": telegram_nick_name, "telegram_chat_id": telegram_chat_id}
diff --git a/engine/apps/telegram/renderers/keyboard.py b/engine/apps/telegram/renderers/keyboard.py
index ed13cd9f..997f5473 100644
--- a/engine/apps/telegram/renderers/keyboard.py
+++ b/engine/apps/telegram/renderers/keyboard.py
@@ -83,7 +83,10 @@ class TelegramKeyboardRenderer:
callback_data_args = [self.alert_group.pk, action.value]
if action_data is not None:
callback_data_args.append(action_data)
-
+ # Add org id with 'x-oncall-org-id' prefix to callback data.
+ # It's a workaroung to pass org_id to the oncall-gateway while proxying requests.
+ # TODO: switch to json str instead of ':' separated string.
+ callback_data_args.append(f"x-oncall-org-id{self.alert_group.channel.organization.public_primary_key}")
button = InlineKeyboardButton(text=text, callback_data=CallbackQueryFactory.encode_data(*callback_data_args))
return button
diff --git a/engine/apps/telegram/tests/test_keyboard_renderer.py b/engine/apps/telegram/tests/test_keyboard_renderer.py
index a3e614be..50d769d8 100644
--- a/engine/apps/telegram/tests/test_keyboard_renderer.py
+++ b/engine/apps/telegram/tests/test_keyboard_renderer.py
@@ -46,12 +46,31 @@ def test_actions_keyboard_alerting(make_organization, make_alert_receive_channel
keyboard = renderer.render_actions_keyboard()
expected_keyboard = [
- [InlineKeyboardButton(text="Acknowledge", callback_data=f"{alert_group.pk}:acknowledge")],
- [InlineKeyboardButton(text="Resolve", callback_data=f"{alert_group.pk}:resolve")],
[
- InlineKeyboardButton(text="🔕 forever", callback_data=f"{alert_group.pk}:silence"),
- InlineKeyboardButton(text="... for 1h", callback_data=f"{alert_group.pk}:silence:3600"),
- InlineKeyboardButton(text="... for 4h", callback_data=f"{alert_group.pk}:silence:14400"),
+ InlineKeyboardButton(
+ text="Acknowledge",
+ callback_data=f"{alert_group.pk}:acknowledge:x-oncall-org-id{organization.public_primary_key}",
+ )
+ ],
+ [
+ InlineKeyboardButton(
+ text="Resolve",
+ callback_data=f"{alert_group.pk}:resolve:x-oncall-org-id{organization.public_primary_key}",
+ )
+ ],
+ [
+ InlineKeyboardButton(
+ text="🔕 forever",
+ callback_data=f"{alert_group.pk}:silence:x-oncall-org-id{organization.public_primary_key}",
+ ),
+ InlineKeyboardButton(
+ text="... for 1h",
+ callback_data=f"{alert_group.pk}:silence:3600:x-oncall-org-id{organization.public_primary_key}",
+ ),
+ InlineKeyboardButton(
+ text="... for 4h",
+ callback_data=f"{alert_group.pk}:silence:14400:x-oncall-org-id{organization.public_primary_key}",
+ ),
],
]
@@ -75,8 +94,18 @@ def test_actions_keyboard_acknowledged(
keyboard = renderer.render_actions_keyboard()
expected_keyboard = [
- [InlineKeyboardButton(text="Unacknowledge", callback_data=f"{alert_group.pk}:unacknowledge")],
- [InlineKeyboardButton(text="Resolve", callback_data=f"{alert_group.pk}:resolve")],
+ [
+ InlineKeyboardButton(
+ text="Unacknowledge",
+ callback_data=f"{alert_group.pk}:unacknowledge:x-oncall-org-id{organization.public_primary_key}",
+ )
+ ],
+ [
+ InlineKeyboardButton(
+ text="Resolve",
+ callback_data=f"{alert_group.pk}:resolve:x-oncall-org-id{organization.public_primary_key}",
+ )
+ ],
]
assert are_keyboards_equal(keyboard.inline_keyboard, expected_keyboard) is True
@@ -99,7 +128,12 @@ def test_actions_keyboard_resolved(
keyboard = renderer.render_actions_keyboard()
expected_keyboard = [
- [InlineKeyboardButton(text="Unresolve", callback_data=f"{alert_group.pk}:unresolve")],
+ [
+ InlineKeyboardButton(
+ text="Unresolve",
+ callback_data=f"{alert_group.pk}:unresolve:x-oncall-org-id{organization.public_primary_key}",
+ )
+ ],
]
assert are_keyboards_equal(keyboard.inline_keyboard, expected_keyboard) is True
@@ -122,9 +156,24 @@ def test_actions_keyboard_silenced(
keyboard = renderer.render_actions_keyboard()
expected_keyboard = [
- [InlineKeyboardButton(text="Acknowledge", callback_data=f"{alert_group.pk}:acknowledge")],
- [InlineKeyboardButton(text="Resolve", callback_data=f"{alert_group.pk}:resolve")],
- [InlineKeyboardButton(text="Unsilence", callback_data=f"{alert_group.pk}:unsilence")],
+ [
+ InlineKeyboardButton(
+ text="Acknowledge",
+ callback_data=f"{alert_group.pk}:acknowledge:x-oncall-org-id{organization.public_primary_key}",
+ )
+ ],
+ [
+ InlineKeyboardButton(
+ text="Resolve",
+ callback_data=f"{alert_group.pk}:resolve:x-oncall-org-id{organization.public_primary_key}",
+ )
+ ],
+ [
+ InlineKeyboardButton(
+ text="Unsilence",
+ callback_data=f"{alert_group.pk}:unsilence:x-oncall-org-id{organization.public_primary_key}",
+ )
+ ],
]
assert are_keyboards_equal(keyboard.inline_keyboard, expected_keyboard) is True
diff --git a/engine/apps/telegram/tests/test_message_renderer.py b/engine/apps/telegram/tests/test_message_renderer.py
index 44c1248e..7d800975 100644
--- a/engine/apps/telegram/tests/test_message_renderer.py
+++ b/engine/apps/telegram/tests/test_message_renderer.py
@@ -71,9 +71,8 @@ def test_alert_group_message(make_organization, make_alert_receive_channel, make
renderer = TelegramMessageRenderer(alert_group=alert_group)
text = renderer.render_alert_group_message()
-
assert text == (
- f"🔴 #{alert_group.inside_organization_number}, {alert_receive_channel.config.tests['telegram']['title']}\n"
+ f" 🔴 #{alert_group.inside_organization_number}, {alert_receive_channel.config.tests['telegram']['title']}\n"
"Alerting, alerts: 1\n"
"Source: Test integration - Grafana\n"
f"{alert_group.web_link}\n\n"
@@ -157,7 +156,7 @@ def test_personal_message(
text = renderer.render_personal_message()
assert text == (
- f"🟠 #{alert_group.inside_organization_number}, {alert_receive_channel.config.tests['telegram']['title']}\n"
+ f" 🟠 #{alert_group.inside_organization_number}, {alert_receive_channel.config.tests['telegram']['title']}\n"
f"Acknowledged by {user_name}, alerts: 1\n"
"Source: Test integration - Grafana\n"
f"{alert_group.web_link}\n\n"
diff --git a/engine/apps/telegram/tests/test_models.py b/engine/apps/telegram/tests/test_models.py
index 173ac1a1..0a9497e4 100644
--- a/engine/apps/telegram/tests/test_models.py
+++ b/engine/apps/telegram/tests/test_models.py
@@ -17,7 +17,7 @@ def test_user_verification_handler_process_update_another_account_already_linked
user_2 = make_user_for_organization(organization)
code = make_telegram_verification_code(user_2)
- connector, created = TelegramVerificationCode.verify_user(code.uuid, chat_id, "nickname")
+ connector, created = TelegramVerificationCode.verify_user(code.uuid_with_org_id, chat_id, "nickname")
assert created
assert connector.telegram_chat_id == chat_id
@@ -38,7 +38,7 @@ def test_user_verification_handler_process_update_user_already_linked(
other_chat_id = 321
code = make_telegram_verification_code(user_1)
- connector, created = TelegramVerificationCode.verify_user(code.uuid, other_chat_id, "nickname")
+ connector, created = TelegramVerificationCode.verify_user(code.uuid_with_org_id, other_chat_id, "nickname")
assert created is False
assert connector.user == user_1
diff --git a/engine/apps/telegram/updates/update_handlers/button_press.py b/engine/apps/telegram/updates/update_handlers/button_press.py
index 55a8580e..6afa11a5 100644
--- a/engine/apps/telegram/updates/update_handlers/button_press.py
+++ b/engine/apps/telegram/updates/update_handlers/button_press.py
@@ -70,7 +70,7 @@ class ButtonPressHandler(UpdateHandler):
action_name = args[1]
action = Action(action_name)
- action_data = args[2] if len(args) >= 3 else None
+ action_data = args[2] if len(args) >= 3 and not args[2].startswith("x-oncall-org-id") else None
return ActionContext(alert_group=alert_group, action=action, action_data=action_data)
diff --git a/engine/apps/telegram/updates/update_handlers/start_message.py b/engine/apps/telegram/updates/update_handlers/start_message.py
index f70ead7d..9acd0be6 100644
--- a/engine/apps/telegram/updates/update_handlers/start_message.py
+++ b/engine/apps/telegram/updates/update_handlers/start_message.py
@@ -1,15 +1,10 @@
from apps.telegram.client import TelegramClient
-from apps.telegram.models import TelegramToUserConnector
from apps.telegram.updates.update_handlers.update_handler import UpdateHandler
START_TEXT = """Hi!
This is Grafana OnCall notification bot. You can connect your Grafana OnCall account to Telegram on user settings page.
"""
-START_TEXT_FOR_CONNECTED_USER = """Hi!
-This is Grafana OnCall notification bot. Your Telegram account is connected to user {username}
-"""
-
class StartMessageHandler(UpdateHandler):
def matches(self) -> bool:
@@ -24,12 +19,5 @@ class StartMessageHandler(UpdateHandler):
return is_from_private_chat and is_start_message
def process_update(self) -> None:
- connector = TelegramToUserConnector.objects.filter(telegram_chat_id=self.update.effective_user.id).first()
telegram_client = TelegramClient()
-
- if connector is not None:
- user = connector.user
- text = START_TEXT_FOR_CONNECTED_USER.format(username=user.username)
- telegram_client.send_raw_message(chat_id=self.update.effective_user.id, text=text)
- else:
- telegram_client.send_raw_message(chat_id=self.update.effective_user.id, text=START_TEXT)
+ telegram_client.send_raw_message(chat_id=self.update.effective_user.id, text=START_TEXT)
diff --git a/engine/apps/telegram/updates/update_handlers/verification/channel.py b/engine/apps/telegram/updates/update_handlers/verification/channel.py
index edd9f787..07debaa5 100644
--- a/engine/apps/telegram/updates/update_handlers/verification/channel.py
+++ b/engine/apps/telegram/updates/update_handlers/verification/channel.py
@@ -73,7 +73,7 @@ class ChannelVerificationCodeHandler(UpdateHandler):
return
connector, created = TelegramChannelVerificationCode.verify_channel_and_discussion_group(
- uuid_code=verification_code,
+ verification_code=verification_code,
channel_chat_id=channel_chat_id,
channel_name=channel_name,
discussion_group_chat_id=discussion_group_chat_id,
diff --git a/engine/apps/telegram/updates/update_handlers/verification/personal.py b/engine/apps/telegram/updates/update_handlers/verification/personal.py
index 6f17603f..0f30dfc5 100644
--- a/engine/apps/telegram/updates/update_handlers/verification/personal.py
+++ b/engine/apps/telegram/updates/update_handlers/verification/personal.py
@@ -33,7 +33,7 @@ class PersonalVerificationCodeHandler(UpdateHandler):
verification_code = text if is_verification_message(text) else text.split()[1]
connector, created = TelegramVerificationCode.verify_user(
- uuid_code=verification_code, telegram_chat_id=user.id, telegram_nick_name=nickname
+ verification_code=verification_code, telegram_chat_id=user.id, telegram_nick_name=nickname
)
if created:
diff --git a/engine/apps/telegram/utils.py b/engine/apps/telegram/utils.py
index 9568666e..18640c58 100644
--- a/engine/apps/telegram/utils.py
+++ b/engine/apps/telegram/utils.py
@@ -1,11 +1,11 @@
import re
from typing import List, Union
-UUID4_REGEX = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
+TELEGRAM_VERIFICATION_CODE_REGEX = "^[A-Z0-9]*_[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
def is_verification_message(text: str) -> bool:
- return bool(re.match(UUID4_REGEX, text))
+ return bool(re.match(TELEGRAM_VERIFICATION_CODE_REGEX, text))
class CallbackQueryFactory:
diff --git a/engine/apps/user_management/apps.py b/engine/apps/user_management/apps.py
new file mode 100644
index 00000000..2dd0c259
--- /dev/null
+++ b/engine/apps/user_management/apps.py
@@ -0,0 +1,16 @@
+from django.apps import AppConfig
+from django.db import models
+
+
+# enable a __lower field lookup for email fields
+# https://docs.djangoproject.com/en/4.1/howto/custom-lookups/#a-bilateral-transformer-example
+class LowerCase(models.Transform):
+ lookup_name = "lower"
+ function = "LOWER"
+
+
+class UserManagementConfig(AppConfig):
+ name = "apps.user_management"
+
+ def ready(self):
+ models.EmailField.register_lookup(LowerCase)
diff --git a/engine/apps/user_management/models/organization.py b/engine/apps/user_management/models/organization.py
index fd37ba81..2561e3cb 100644
--- a/engine/apps/user_management/models/organization.py
+++ b/engine/apps/user_management/models/organization.py
@@ -218,6 +218,7 @@ class Organization(MaintainableObject):
def sms_left(self, user):
return self.subscription_strategy.sms_left(user)
+ # todo: manage backend specific limits in messaging backend
def emails_left(self, user):
return self.subscription_strategy.emails_left(user)
@@ -244,6 +245,11 @@ class Organization(MaintainableObject):
def web_link(self):
return urljoin(self.grafana_url, "a/grafana-oncall-app/")
+ @property
+ def web_link_with_id(self):
+ # It's a workaround to pass org id to the oncall gateway while proxying telegram requests
+ return urljoin(self.grafana_url, f"a/grafana-oncall-app/?x-oncall-org-id={self.public_primary_key}")
+
def __str__(self):
return f"{self.pk}: {self.org_title}"
diff --git a/engine/apps/user_management/subscription_strategy/free_public_beta_subscription_strategy.py b/engine/apps/user_management/subscription_strategy/free_public_beta_subscription_strategy.py
index 32f9fa69..dcd0be9f 100644
--- a/engine/apps/user_management/subscription_strategy/free_public_beta_subscription_strategy.py
+++ b/engine/apps/user_management/subscription_strategy/free_public_beta_subscription_strategy.py
@@ -1,6 +1,7 @@
-from datetime import datetime
-
from django.apps import apps
+from django.utils import timezone
+
+from apps.email.models import EmailMessage
from .base_subsription_strategy import BaseSubscriptionStrategy
@@ -21,17 +22,16 @@ class FreePublicBetaSubscriptionStrategy(BaseSubscriptionStrategy):
def sms_left(self, user):
return self._calculate_phone_notifications_left(user)
+ # todo: manage backend specific limits in messaging backend
def emails_left(self, user):
- # Email notifications are disabled now.
- EmailMessage = apps.get_model("sendgridapp", "EmailMessage")
- now = datetime.now()
+ now = timezone.now()
day_start = now.replace(hour=0, minute=0, second=0, microsecond=0)
- emails_this_week = EmailMessage.objects.filter(
+ emails_today = EmailMessage.objects.filter(
created_at__gte=day_start,
represents_alert_group__channel__organization=self.organization,
receiver=user,
).count()
- return self._emails_limit - emails_this_week
+ return self._emails_limit - emails_today
def notifications_limit_web_report(self, user):
limits_to_show = []
@@ -59,7 +59,7 @@ class FreePublicBetaSubscriptionStrategy(BaseSubscriptionStrategy):
"""
PhoneCall = apps.get_model("twilioapp", "PhoneCall")
SMSMessage = apps.get_model("twilioapp", "SMSMessage")
- now = datetime.now()
+ now = timezone.now()
day_start = now.replace(hour=0, minute=0, second=0, microsecond=0)
calls_today = PhoneCall.objects.filter(
created_at__gte=day_start,
diff --git a/engine/apps/user_management/tests/test_free_public_beta_subcription_strategy.py b/engine/apps/user_management/tests/test_free_public_beta_subcription_strategy.py
index 0f309570..c26b4216 100644
--- a/engine/apps/user_management/tests/test_free_public_beta_subcription_strategy.py
+++ b/engine/apps/user_management/tests/test_free_public_beta_subcription_strategy.py
@@ -1,8 +1,5 @@
-import sys
-
import pytest
-from apps.sendgridapp.constants import SendgridEmailMessageStatuses
from apps.twilioapp.constants import TwilioCallStatuses, TwilioMessageStatuses
from common.constants.role import Role
@@ -65,7 +62,6 @@ def test_phone_calls_and_sms_counts_together(
assert organization.sms_left(user) == organization.subscription_strategy._phone_notifications_limit
-@pytest.mark.skip(reason="email disabled")
@pytest.mark.django_db
def test_emails_left(
make_organization,
@@ -75,10 +71,11 @@ def test_emails_left(
make_alert_group,
):
organization = make_organization()
- admin = make_user_for_organization(organization, role=Role.ADMIN)
+ user = make_user_for_organization(organization)
+
alert_receive_channel = make_alert_receive_channel(organization)
alert_group = make_alert_group(alert_receive_channel)
- make_email_message(
- receiver=admin, status=SendgridEmailMessageStatuses.DELIVERED, represents_alert_group=alert_group
- ),
- assert organization.emails_left(admin) == sys.maxsize
+
+ make_email_message(receiver=user, represents_alert_group=alert_group)
+
+ assert organization.emails_left(user) == organization.subscription_strategy._emails_limit - 1
diff --git a/engine/apps/user_management/tests/test_user.py b/engine/apps/user_management/tests/test_user.py
index fe615c7c..74440cd1 100644
--- a/engine/apps/user_management/tests/test_user.py
+++ b/engine/apps/user_management/tests/test_user.py
@@ -2,6 +2,7 @@
import pytest
+from apps.user_management.models import User
from common.constants.role import Role
@@ -22,3 +23,16 @@ def test_self_or_admin(
assert admin.self_or_admin(editor, organization) is False
assert admin.self_or_admin(second_admin, organization) is True
assert admin.self_or_admin(admin_from_another_organization, organization) is False
+
+
+@pytest.mark.django_db
+def test_lower_email_filter(
+ make_organization,
+ make_user_for_organization,
+):
+ organization = make_organization()
+ user = make_user_for_organization(organization, email="TestingUser@test.com")
+ make_user_for_organization(organization, email="testing_user@test.com")
+
+ assert User.objects.get(email__lower="testinguser@test.com") == user
+ assert User.objects.filter(email__lower__in=["testinguser@test.com"]).get() == user
diff --git a/engine/common/api_helpers/mixins.py b/engine/common/api_helpers/mixins.py
index cddecdc7..3af06bcc 100644
--- a/engine/common/api_helpers/mixins.py
+++ b/engine/common/api_helpers/mixins.py
@@ -11,7 +11,6 @@ from rest_framework.exceptions import NotFound, Throttled
from rest_framework.response import Response
from apps.alerts.incident_appearance.templaters import (
- AlertEmailTemplater,
AlertPhoneCallTemplater,
AlertSlackTemplater,
AlertSmsTemplater,
@@ -245,9 +244,8 @@ SLACK = "slack"
WEB = "web"
PHONE_CALL = "phone_call"
SMS = "sms"
-EMAIL = "email"
TELEGRAM = "telegram"
-NOTIFICATION_CHANNEL_OPTIONS = [SLACK, WEB, PHONE_CALL, SMS, EMAIL, TELEGRAM]
+NOTIFICATION_CHANNEL_OPTIONS = [SLACK, WEB, PHONE_CALL, SMS, TELEGRAM]
TITLE = "title"
MESSAGE = "message"
IMAGE_URL = "image_url"
@@ -261,7 +259,6 @@ NOTIFICATION_CHANNEL_TO_TEMPLATER_MAP = {
WEB: AlertWebTemplater,
PHONE_CALL: AlertPhoneCallTemplater,
SMS: AlertSmsTemplater,
- EMAIL: AlertEmailTemplater,
TELEGRAM: AlertTelegramTemplater,
}
diff --git a/engine/config_integrations/alertmanager.py b/engine/config_integrations/alertmanager.py
index cc356e26..b2ff3de0 100644
--- a/engine/config_integrations/alertmanager.py
+++ b/engine/config_integrations/alertmanager.py
@@ -73,22 +73,6 @@ web_image_url = slack_image_url
sms_title = '{{ payload.get("labels", {}).get("alertname", "Title undefined") }}'
phone_call_title = sms_title
-email_title = web_title
-
-email_message = """\
-{{- payload.messsage }}
-{%- if "status" in payload -%}
-**Status**: {{ payload.status }}
-{% endif -%}
-**Labels:** {% for k, v in payload["labels"].items() %}
-{{ k }}: {{ v }}{% endfor %}
-**Annotations:**
-{%- for k, v in payload.get("annotations", {}).items() %}
-{#- render annotation as markdown url if it starts with http #}
-{{ k }}: {{v}}
-{% endfor %}
-""" # noqa: W291
-
telegram_title = sms_title
telegram_message = """\
@@ -188,23 +172,6 @@ tests = {
"phone_call": {
"title": "KubeJobCompletion",
},
- "email": {
- "title": "KubeJobCompletion",
- "message": (
- "**Status**: firing\n"
- "**Labels:** \n"
- "job: kube-state-metrics\n"
- "instance: 10.143.139.7:8443\n"
- "job_name: email-tracking-perform-initialization-1.0.50\n"
- "severity: warning\n"
- "alertname: KubeJobCompletion\n"
- "namespace: default\n"
- "prometheus: monitoring/k8s\n"
- "**Annotations:**\n"
- "message: Job default/email-tracking-perform-initialization-1.0.50 is taking more than one hour to complete.\n\n"
- "runbook_url: https://github.com/kubernetes-monitoring/kubernetes-mixin/tree/master/runbook.md#alert-name-kubejobcompletion\n"
- ),
- },
"telegram": {
"title": "KubeJobCompletion",
"message": (
diff --git a/engine/config_integrations/elastalert.py b/engine/config_integrations/elastalert.py
index 73320d53..bb5dc8db 100644
--- a/engine/config_integrations/elastalert.py
+++ b/engine/config_integrations/elastalert.py
@@ -36,10 +36,6 @@ sms_title = web_title
phone_call_title = sms_title
-email_title = web_title
-
-email_message = "{{ payload|tojson_pretty }}"
-
telegram_title = sms_title
telegram_message = "{{ payload|tojson_pretty }}"
diff --git a/engine/config_integrations/formatted_webhook.py b/engine/config_integrations/formatted_webhook.py
index 6847639f..fb6e3061 100644
--- a/engine/config_integrations/formatted_webhook.py
+++ b/engine/config_integrations/formatted_webhook.py
@@ -32,10 +32,6 @@ sms_title = web_title
phone_call_title = sms_title
-email_title = web_title
-
-email_message = slack_message
-
telegram_title = sms_title
telegram_message = slack_message
diff --git a/engine/config_integrations/grafana.py b/engine/config_integrations/grafana.py
index 4feefd61..cc35a778 100644
--- a/engine/config_integrations/grafana.py
+++ b/engine/config_integrations/grafana.py
@@ -81,29 +81,6 @@ sms_title = """\
phone_call_title = sms_title
-email_title = web_title
-
-email_message = """\
-{{- payload.message }}
-{%- for value in payload.get("evalMatches", []) %}
-**{{ value.metric }}**: {{ value.value }}
-{% endfor -%}
-{%- if "status" in payload -%}
-**Status**: {{ payload.status }}
-{% endif -%}
-{%- if "labels" in payload -%}
-**Labels:** {% for k, v in payload["labels"].items() %}
-{{ k }}: {{ v }}{% endfor %}
-{% endif -%}
-{%- if "annotations" in payload -%}
-**Annotations:**
-{%- for k, v in payload.get("annotations", {}).items() %}
-{#- render annotation as markdown url if it starts with http #}
-{{ k }}: {{v}}
-{% endfor %}
-{%- endif -%}
-"""
-
telegram_title = sms_title
telegram_message = """\
@@ -215,23 +192,6 @@ tests = {
"phone_call": {
"title": "KubeJobCompletion",
},
- "email": {
- "title": "KubeJobCompletion",
- "message": (
- "**Status**: firing\n"
- "**Labels:** \n"
- "job: kube-state-metrics\n"
- "instance: 10.143.139.7:8443\n"
- "job_name: email-tracking-perform-initialization-1.0.50\n"
- "severity: warning\n"
- "alertname: KubeJobCompletion\n"
- "namespace: default\n"
- "prometheus: monitoring/k8s\n"
- "**Annotations:**\n"
- "message: Job default/email-tracking-perform-initialization-1.0.50 is taking more than one hour to complete.\n\n"
- "runbook_url: https://github.com/kubernetes-monitoring/kubernetes-mixin/tree/master/runbook.md#alert-name-kubejobcompletion\n"
- ),
- },
"telegram": {
"title": "KubeJobCompletion",
"message": (
diff --git a/engine/config_integrations/grafana_alerting.py b/engine/config_integrations/grafana_alerting.py
index 4eac0135..e44aaaae 100644
--- a/engine/config_integrations/grafana_alerting.py
+++ b/engine/config_integrations/grafana_alerting.py
@@ -77,22 +77,6 @@ web_image_url = slack_image_url
sms_title = '{{ payload.get("labels", {}).get("alertname", "Title undefined") }}'
phone_call_title = sms_title
-email_title = web_title
-
-email_message = """\
-{{- payload.messsage }}
-{%- if "status" in payload -%}
-**Status**: {{ payload.status }}
-{% endif -%}
-**Labels:** {% for k, v in payload["labels"].items() %}
-{{ k }}: {{ v }}{% endfor %}
-**Annotations:**
-{%- for k, v in payload.get("annotations", {}).items() %}
-{#- render annotation as markdown url if it starts with http #}
-{{ k }}: {{v}}
-{% endfor %}
-""" # noqa:W291
-
telegram_title = sms_title
telegram_message = """\
@@ -191,23 +175,6 @@ tests = {
"phone_call": {
"title": "KubeJobCompletion",
},
- "email": {
- "title": "KubeJobCompletion",
- "message": (
- "**Status**: firing\n"
- "**Labels:** \n"
- "job: kube-state-metrics\n"
- "instance: 10.143.139.7:8443\n"
- "job_name: email-tracking-perform-initialization-1.0.50\n"
- "severity: warning\n"
- "alertname: KubeJobCompletion\n"
- "namespace: default\n"
- "prometheus: monitoring/k8s\n"
- "**Annotations:**\n"
- "message: Job default/email-tracking-perform-initialization-1.0.50 is taking more than one hour to complete.\n\n"
- "runbook_url: https://github.com/kubernetes-monitoring/kubernetes-mixin/tree/master/runbook.md#alert-name-kubejobcompletion\n"
- ),
- },
"telegram": {
"title": "KubeJobCompletion",
"message": (
diff --git a/engine/config_integrations/inbound_email.py b/engine/config_integrations/inbound_email.py
index 4ecac8e4..7ddfa0e7 100644
--- a/engine/config_integrations/inbound_email.py
+++ b/engine/config_integrations/inbound_email.py
@@ -32,10 +32,6 @@ sms_title = web_title
phone_call_title = web_title
-email_title = web_title
-
-email_message = slack_message
-
telegram_title = sms_title
telegram_message = slack_message
diff --git a/engine/config_integrations/kapacitor.py b/engine/config_integrations/kapacitor.py
index 3d761766..fd76c695 100644
--- a/engine/config_integrations/kapacitor.py
+++ b/engine/config_integrations/kapacitor.py
@@ -38,10 +38,6 @@ sms_title = web_title
phone_call_title = web_title
-email_title = web_title
-
-email_message = slack_message
-
telegram_title = sms_title
telegram_message = "{{ payload|tojson_pretty }}"
diff --git a/engine/config_integrations/maintenance.py b/engine/config_integrations/maintenance.py
index d27405ef..60b8710b 100644
--- a/engine/config_integrations/maintenance.py
+++ b/engine/config_integrations/maintenance.py
@@ -32,10 +32,6 @@ sms_title = web_title
phone_call_title = sms_title
-email_title = web_title
-
-email_message = slack_message
-
telegram_title = sms_title
telegram_message = slack_message
diff --git a/engine/config_integrations/manual.py b/engine/config_integrations/manual.py
index fdcaadaa..416be3e6 100644
--- a/engine/config_integrations/manual.py
+++ b/engine/config_integrations/manual.py
@@ -41,10 +41,6 @@ sms_title = web_title
phone_call_title = sms_title
-email_title = web_title
-
-email_message = slack_message
-
telegram_title = sms_title
telegram_message = slack_message
diff --git a/engine/config_integrations/webhook.py b/engine/config_integrations/webhook.py
index 4a3b0b73..823bc837 100644
--- a/engine/config_integrations/webhook.py
+++ b/engine/config_integrations/webhook.py
@@ -36,10 +36,6 @@ sms_title = web_title
phone_call_title = sms_title
-email_title = web_title
-
-email_message = "{{ payload|tojson_pretty }}"
-
telegram_title = sms_title
telegram_message = "{{ payload|tojson_pretty }}"
diff --git a/engine/conftest.py b/engine/conftest.py
index 68ef50d5..8291d921 100644
--- a/engine/conftest.py
+++ b/engine/conftest.py
@@ -44,6 +44,7 @@ from apps.base.tests.factories import (
UserNotificationPolicyFactory,
UserNotificationPolicyLogRecordFactory,
)
+from apps.email.tests.factories import EmailMessageFactory
from apps.heartbeat.tests.factories import IntegrationHeartBeatFactory
from apps.schedules.tests.factories import (
CustomOnCallShiftFactory,
@@ -105,7 +106,7 @@ register(ResolutionNoteSlackMessageFactory)
register(PhoneCallFactory)
register(SMSFactory)
-# register(EmailMessageFactory)
+register(EmailMessageFactory)
register(IntegrationHeartBeatFactory)
@@ -627,13 +628,12 @@ def make_sms():
return _make_sms
-# TODO: restore email notifications
-# @pytest.fixture()
-# def make_email_message():
-# def _make_email_message(receiver, status, **kwargs):
-# return EmailMessageFactory(receiver=receiver, status=status, **kwargs)
-#
-# return _make_email_message
+@pytest.fixture()
+def make_email_message():
+ def _make_email_message(receiver, **kwargs):
+ return EmailMessageFactory(receiver=receiver, **kwargs)
+
+ return _make_email_message
@pytest.fixture()
diff --git a/engine/engine/urls.py b/engine/engine/urls.py
index 518c5608..e8080a7f 100644
--- a/engine/engine/urls.py
+++ b/engine/engine/urls.py
@@ -36,7 +36,6 @@ urlpatterns = [
path("api/internal/v1/", include("apps.social_auth.urls", namespace="social_auth")),
path("integrations/v1/", include("apps.integrations.urls", namespace="integrations")),
path("twilioapp/", include("apps.twilioapp.urls")),
- # path('sendgridapp/', include('apps.sendgridapp.urls')), TODO: restore email notifications
path("api/v1/", include("apps.public_api.urls", namespace="api-public")),
path("api/internal/v1/", include("apps.migration_tool.urls", namespace="migration-tool")),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
diff --git a/engine/requirements.txt b/engine/requirements.txt
index 950c1d1e..5232c646 100644
--- a/engine/requirements.txt
+++ b/engine/requirements.txt
@@ -23,7 +23,6 @@ recurring-ical-events==0.1.16b0
slack-export-viewer==1.0.0
beautifulsoup4==4.8.1
social-auth-app-django==3.1.0
-sendgrid==6.1.2
cryptography==3.3.2
pytest==5.4.3
pytest-django==3.9.0
diff --git a/engine/settings/base.py b/engine/settings/base.py
index d9ec9f36..92e759ed 100644
--- a/engine/settings/base.py
+++ b/engine/settings/base.py
@@ -64,14 +64,6 @@ TWILIO_VERIFY_SERVICE_SID = os.environ.get("TWILIO_VERIFY_SERVICE_SID")
TELEGRAM_WEBHOOK_HOST = os.environ.get("TELEGRAM_WEBHOOK_HOST", BASE_URL)
TELEGRAM_TOKEN = os.environ.get("TELEGRAM_TOKEN")
-# For Sending email
-SENDGRID_API_KEY = os.environ.get("SENDGRID_API_KEY")
-SENDGRID_FROM_EMAIL = os.environ.get("SENDGRID_FROM_EMAIL")
-
-# For Inbound email
-SENDGRID_SECRET_KEY = os.environ.get("SENDGRID_SECRET_KEY")
-SENDGRID_INBOUND_EMAIL_DOMAIN = os.environ.get("SENDGRID_INBOUND_EMAIL_DOMAIN")
-
# For Grafana Cloud integration
GRAFANA_CLOUD_ONCALL_API_URL = os.environ.get(
"GRAFANA_CLOUD_ONCALL_API_URL", "https://oncall-prod-us-central-0.grafana.net/oncall"
@@ -198,13 +190,13 @@ INSTALLED_APPS = [
"apps.integrations",
"apps.schedules",
"apps.heartbeat",
+ "apps.email",
"apps.slack",
"apps.telegram",
"apps.twilioapp",
"apps.api",
"apps.api_for_grafana_incident",
"apps.base",
- # "apps.sendgridapp", TODO: restore email notifications
"apps.auth_token",
"apps.public_api",
"apps.grafana_plugin",
@@ -244,6 +236,7 @@ MIDDLEWARE = [
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"social_django.middleware.SocialAuthExceptionMiddleware",
"apps.social_auth.middlewares.SocialAuthAuthCanceledExceptionMiddleware",
+ "apps.integrations.middlewares.IntegrationExceptionMiddleware",
]
LOG_REQUEST_ID_HEADER = "HTTP_X_CLOUD_TRACE_CONTEXT"
@@ -569,6 +562,18 @@ SLOW_THRESHOLD_SECONDS = 2.0
EXTRA_MESSAGING_BACKENDS = []
+# Email messaging backend
+EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
+EMAIL_HOST = os.getenv("EMAIL_HOST")
+EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER")
+EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD")
+EMAIL_PORT = getenv_integer("EMAIL_PORT", 587)
+EMAIL_USE_TLS = getenv_boolean("EMAIL_USE_TLS", True)
+DEFAULT_FROM_EMAIL = os.getenv("DEFAULT_FROM_EMAIL")
+
+if FEATURE_EMAIL_INTEGRATION_ENABLED:
+ EXTRA_MESSAGING_BACKENDS = [("apps.email.backend.EmailBackend", 8)]
+
INSTALLED_ONCALL_INTEGRATIONS = [
"config_integrations.alertmanager",
"config_integrations.grafana",
diff --git a/engine/settings/ci-test.py b/engine/settings/ci-test.py
index 7af883d3..23439c13 100644
--- a/engine/settings/ci-test.py
+++ b/engine/settings/ci-test.py
@@ -36,8 +36,6 @@ if BROKER_TYPE != BrokerTypes.REDIS:
# Dummy Telegram token (fake one)
TELEGRAM_TOKEN = "0000000000:XXXXXXXXXXXXXXXXXXXXXXXXXXXX-XXXXXX"
-SENDGRID_FROM_EMAIL = "dummy_sendgrid_from_email@test.ci-test"
-SENDGRID_SECRET_KEY = "dummy_sendgrid_secret_key"
TWILIO_ACCOUNT_SID = "dummy_twilio_account_sid"
TWILIO_AUTH_TOKEN = "dummy_twilio_auth_token"
diff --git a/grafana-plugin/.eslintrc.js b/grafana-plugin/.eslintrc.js
index 87f1dd00..9bfe88c0 100644
--- a/grafana-plugin/.eslintrc.js
+++ b/grafana-plugin/.eslintrc.js
@@ -9,18 +9,7 @@ module.exports = {
'^assets|^components|^containers|^declare|^icons|^img|^interceptors|^models|^network|^pages|^services|^state|^utils',
},
rules: {
- 'no-unused-vars': ['warn', { vars: 'all', args: 'after-used', ignoreRestSiblings: false }],
- 'react/prop-types': 'warn',
- 'react/display-name': 'warn',
- 'react/jsx-key': 'warn',
- 'react-hooks/exhaustive-deps': 'off',
- 'react/no-unescaped-entities': 'warn',
- 'react/jsx-no-target-blank': 'warn',
- 'react-hooks/exhaustive-deps': 'warn',
- 'no-restricted-imports': 'warn',
eqeqeq: 'warn',
- 'no-duplicate-imports': 'error',
- 'rulesdir/no-relative-import-paths': ['error', { allowSameFolder: true }],
'import/order': [
'error',
{
@@ -47,5 +36,33 @@ module.exports = {
'newlines-between': 'always',
},
],
+ 'no-unused-vars': [
+ 'warn',
+ {
+ vars: 'all',
+ args: 'after-used',
+ argsIgnorePattern: '^_',
+ destructuredArrayIgnorePattern: '^_',
+ ignoreRestSiblings: true,
+ },
+ ],
+ 'no-duplicate-imports': 'error',
+ 'no-restricted-imports': 'warn',
+ 'react/display-name': 'warn',
+ /**
+ * It appears as though the react/prop-types rule has a bug in it
+ * when your props extend an interface
+ * https://github.com/jsx-eslint/eslint-plugin-react/issues/3325
+ */
+ 'react/prop-types': 'off',
+ 'react/jsx-key': 'warn',
+ 'react/jsx-no-target-blank': 'warn',
+ 'react/no-unescaped-entities': 'off',
+ /**
+ * TODO: react-hooks/exhaustive-deps is temporarily disabled
+ * this will be turned back on, and the warnings fixed, in a forthcoming PR
+ */
+ 'react-hooks/exhaustive-deps': 'off',
+ 'rulesdir/no-relative-import-paths': ['error', { allowSameFolder: true }],
},
};
diff --git a/grafana-plugin/.stylelintrc b/grafana-plugin/.stylelintrc
index 7cda5c91..c37d4c08 100644
--- a/grafana-plugin/.stylelintrc
+++ b/grafana-plugin/.stylelintrc
@@ -1,12 +1,14 @@
{
- "extends": "stylelint-config-standard",
- "rules": {
- "block-no-empty": [true,{ "severity": "warning"}],
+ "extends": ["stylelint-config-standard", "stylelint-prettier/recommended"],
+ "plugins": ["stylelint-prettier"],
+ "rules": {
+ "block-no-empty": [true, { "severity": "warning" }],
"selector-pseudo-class-no-unknown": [
true,
{
"ignorePseudoClasses": ["global"]
}
- ]
+ ],
+ "prettier/prettier": true
}
}
diff --git a/grafana-plugin/jest.config.js b/grafana-plugin/jest.config.js
index bcf17c90..31684c09 100644
--- a/grafana-plugin/jest.config.js
+++ b/grafana-plugin/jest.config.js
@@ -1,8 +1,29 @@
-// This file is needed because it is used by vscode and other tools that
-// call `jest` directly. However, unless you are doing anything special
-// do not edit this file
+module.exports = {
+ preset: 'ts-jest',
+ testEnvironment: 'jsdom',
-const standard = require('@grafana/toolkit/src/config/jest.plugin.config');
+ moduleDirectories: ['node_modules', 'src'],
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
-// This process will use the same config that `yarn test` is using
-module.exports = standard.jestConfig();
+ globals: {
+ 'ts-jest': {
+ isolatedModules: true,
+ babelConfig: true
+ },
+ },
+
+ transform: {
+ '^.+\\.js?$': require.resolve('babel-jest'),
+ '^.+\\.jsx?$': require.resolve('babel-jest'),
+ '^.+\\.ts?$': require.resolve('ts-jest'),
+ '^.+\\.tsx?$': require.resolve('ts-jest'),
+ },
+
+ moduleNameMapper: {
+ "grafana/app/(.*)": '/src/jest/grafanaMock.ts',
+ "jest/outgoingWebhooksStub": '/src/jest/outgoingWebhooksStub.ts',
+ "^jest$": '/src/jest',
+ '^.+\\.(css|scss)$': '/src/jest/styleMock.ts',
+ "^lodash-es$": "lodash",
+ }
+};
diff --git a/grafana-plugin/package.json b/grafana-plugin/package.json
index 0093af7d..9398e5c9 100644
--- a/grafana-plugin/package.json
+++ b/grafana-plugin/package.json
@@ -3,12 +3,12 @@
"version": "1.0.0",
"description": "Grafana OnCall Plugin",
"scripts": {
- "lint": "eslint --cache --ext .js,.jsx,.ts,.tsx ./src",
- "lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx --quiet ./src",
+ "lint": "eslint --cache --ext .js,.jsx,.ts,.tsx --max-warnings=0 ./src",
+ "lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx --max-warnings=0 --quiet ./src",
"stylelint": "stylelint ./src/**/*.css",
"stylelint:fix": "stylelint --fix ./src/**/*.css",
"build": "grafana-toolkit plugin:build",
- "test": "grafana-toolkit plugin:test",
+ "test": "jest --verbose",
"dev": "grafana-toolkit plugin:dev",
"watch": "grafana-toolkit plugin:dev --watch",
"sign": "grafana-toolkit plugin:sign",
@@ -52,25 +52,43 @@
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@grafana/data": "^9.1.1",
+ "@grafana/eslint-config": "^5.0.0",
"@grafana/runtime": "^9.1.1",
"@grafana/toolkit": "^9.1.1",
"@grafana/ui": "^9.1.1",
+ "@jest/globals": "^27.5.1",
+ "@testing-library/jest-dom": "^5.16.5",
+ "@testing-library/react": "12",
"@types/dompurify": "^2.3.4",
+ "@types/jest": "^27.5.1",
"@types/lodash-es": "^4.17.6",
"@types/react-copy-to-clipboard": "^5.0.4",
"@types/react-dom": "^18.0.6",
"@types/react-responsive": "^8.0.5",
"@types/react-router-dom": "^5.3.3",
+ "@types/react-test-renderer": "^17.0.2",
"@types/throttle-debounce": "^5.0.0",
+ "@typescript-eslint/eslint-plugin": "^5.40.1",
"copy-webpack-plugin": "^11.0.0",
"dompurify": "^2.3.12",
+ "eslint": "^8.25.0",
+ "eslint-plugin-jsdoc": "^39.3.14",
+ "eslint-plugin-react": "^7.31.10",
+ "eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-rulesdir": "^0.2.1",
+ "jest": "^27.5.1",
+ "jest-environment-jsdom": "^27.5.1",
"lint-staged": "^10.2.11",
"lodash-es": "^4.17.21",
"moment-timezone": "^0.5.35",
"plop": "^2.7.4",
"postcss-loader": "^7.0.1",
+ "react-test-renderer": "^17.0.2",
+ "stylelint-config-prettier": "^9.0.3",
+ "stylelint-prettier": "^2.0.0",
+ "ts-jest": "^27.1.3",
"ts-loader": "^9.3.1",
+ "typescript": "4.6.4",
"webpack-bundle-analyzer": "^4.6.1"
},
"engines": {
diff --git a/grafana-plugin/src/GrafanaPluginRootPage.tsx b/grafana-plugin/src/GrafanaPluginRootPage.tsx
index 4e3f6467..ed69df65 100644
--- a/grafana-plugin/src/GrafanaPluginRootPage.tsx
+++ b/grafana-plugin/src/GrafanaPluginRootPage.tsx
@@ -1,7 +1,7 @@
import React, { useEffect, useMemo } from 'react';
import { AppRootProps } from '@grafana/data';
-import { Button, HorizontalGroup, LinkButton, VerticalGroup } from '@grafana/ui';
+import { Button, HorizontalGroup, LinkButton } from '@grafana/ui';
import dayjs from 'dayjs';
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
@@ -30,8 +30,6 @@ dayjs.extend(isSameOrBefore);
dayjs.extend(isSameOrAfter);
dayjs.extend(isoWeek);
-// dayjs().weekday(0);
-
import './style/vars.css';
import './style/index.css';
diff --git a/grafana-plugin/src/README.md b/grafana-plugin/src/README.md
index 66e4b915..b3c76bb1 100644
--- a/grafana-plugin/src/README.md
+++ b/grafana-plugin/src/README.md
@@ -3,6 +3,7 @@
Developer-Friendly
Alert Management
with Brilliant Slack Integration
+
- Connect monitoring systems
- Collect and analyze data
- On-call rotation
@@ -10,5 +11,6 @@ with Brilliant Slack Integration
- Never miss alerts with calls and SMS
## Documentation
+
- [On Github](http://github.com/grafana/oncall)
- [Grafana OnCall](https://grafana.com/docs/grafana-cloud/oncall/)
diff --git a/grafana-plugin/src/components/AlertTemplates/AlertTemplatesForm.helper.tsx b/grafana-plugin/src/components/AlertTemplates/AlertTemplatesForm.helper.tsx
index e2e01b17..d7bad53f 100644
--- a/grafana-plugin/src/components/AlertTemplates/AlertTemplatesForm.helper.tsx
+++ b/grafana-plugin/src/components/AlertTemplates/AlertTemplatesForm.helper.tsx
@@ -10,7 +10,3 @@ export function getLabelFromTemplateName(templateName: string, group: any) {
}
return arrayWithNeededValues.join(' ');
}
-
-export function includeTemplateGroup(groupName: string) {
- return true;
-}
diff --git a/grafana-plugin/src/components/AlertTemplates/AlertTemplatesForm.tsx b/grafana-plugin/src/components/AlertTemplates/AlertTemplatesForm.tsx
index eaecbbfd..782ea07a 100644
--- a/grafana-plugin/src/components/AlertTemplates/AlertTemplatesForm.tsx
+++ b/grafana-plugin/src/components/AlertTemplates/AlertTemplatesForm.tsx
@@ -8,8 +8,7 @@ import cn from 'classnames/bind';
import { omit } from 'lodash-es';
import { templatesToRender, Template } from 'components/AlertTemplates/AlertTemplatesForm.config';
-import { getLabelFromTemplateName, includeTemplateGroup } from 'components/AlertTemplates/AlertTemplatesForm.helper';
-import Collapse from 'components/Collapse/Collapse';
+import { getLabelFromTemplateName } from 'components/AlertTemplates/AlertTemplatesForm.helper';
import Block from 'components/GBlock/Block';
import MonacoJinja2Editor from 'components/MonacoJinja2Editor/MonacoJinja2Editor';
import SourceCode from 'components/SourceCode/SourceCode';
@@ -41,7 +40,6 @@ const AlertTemplatesForm = (props: AlertTemplatesFormProps) => {
const {
onUpdateTemplates,
templates,
- errors,
alertReceiveChannelId,
alertGroupId,
demoAlertEnabled,
@@ -53,6 +51,8 @@ const AlertTemplatesForm = (props: AlertTemplatesFormProps) => {
const [tempValues, setTempValues] = useState<{
[key: string]: string | null;
}>({});
+ const [activeGroup, setActiveGroup] = useState();
+ const [activeTemplate, setActiveTemplate] = useState();
useEffect(() => {
makeRequest('/preview_template_options/', {});
@@ -80,14 +80,11 @@ const AlertTemplatesForm = (props: AlertTemplatesFormProps) => {
const handleReset = () => {
const temValuesCopy = omit(
tempValues,
- groups[activeGroup].map((group: any) => group.name)
+ groups[activeGroup].map((group) => group.name)
);
setTempValues(temValuesCopy);
};
- const [activeGroup, setActiveGroup] = useState();
- const [activeTemplate, setActiveTemplate] = useState();
-
const filteredTemplatesToRender = useMemo(() => {
return templates
? templatesToRender.filter((template) => {
@@ -97,13 +94,10 @@ const AlertTemplatesForm = (props: AlertTemplatesFormProps) => {
}, [templates]);
const groups = useMemo(() => {
- const groups: { [key: string]: any } = {};
+ const groups: { [key: string]: Template[] } = {};
filteredTemplatesToRender.forEach((templateToRender) => {
if (!groups[templateToRender.group]) {
- if (!includeTemplateGroup(templateToRender.group)) {
- return;
- }
groups[templateToRender.group] = [];
}
groups[templateToRender.group].push(templateToRender);
@@ -113,11 +107,7 @@ const AlertTemplatesForm = (props: AlertTemplatesFormProps) => {
const getGroupByTemplateName = (templateName: string) => {
Object.values(groups).find((group) => {
- const foundTemplate = group.find((obj: any) => {
- if (obj.name == templateName) {
- return obj;
- }
- });
+ const foundTemplate = group.find((obj) => obj.name === templateName);
setActiveGroup(foundTemplate?.group);
});
};
@@ -210,18 +200,18 @@ const AlertTemplatesForm = (props: AlertTemplatesFormProps) => {
suggestions
- {groups[activeGroup].map((activeTemplate: any) => (
+ {groups[activeGroup].map((activeTemplate) => (
-
+
{getLabelFromTemplateName(activeTemplate.name, activeGroup)}
- {activeTemplate.name == 'resolve_condition_template' && (
+ {activeTemplate.name === 'resolve_condition_template' && (
To activate autoresolving change integration
@@ -240,7 +230,7 @@ const AlertTemplatesForm = (props: AlertTemplatesFormProps) => {
Press Ctrl +Space to get suggestions
- {activeGroup === 'web' && activeTemplate.name == 'web_title_template' && (
+ {activeGroup === 'web' && activeTemplate.name === 'web_title_template' && (
Please note that after changing the web title template new alert groups will be searchable by
@@ -271,7 +261,7 @@ const AlertTemplatesForm = (props: AlertTemplatesFormProps) => {
{`${capitalCase(activeGroup)} Preview`}
- {groups[activeGroup].map((template: any) => (
+ {groups[activeGroup].map((template) => (
{
+ const avatarSrc = 'http://avatar.com/';
+ const avatarSizeLarge = 'large';
+ const avatarSizeSmall = 'small';
+
+ test("Avatar's image points to given src attribute", async () => {
+ render( );
+ const imageEl = await screen.findByTestId('test__avatar');
+ expect(imageEl.src).toBe(avatarSrc);
+ });
+
+ test('Avatar appends sizing class', async () => {
+ render( );
+ const imageEl = await screen.findByTestId('test__avatar');
+ expect(imageEl.classList).toContain(`avatarSize-${avatarSizeSmall}`);
+ });
+});
diff --git a/grafana-plugin/src/components/Avatar/Avatar.tsx b/grafana-plugin/src/components/Avatar/Avatar.tsx
index 15b93552..85c7a3c6 100644
--- a/grafana-plugin/src/components/Avatar/Avatar.tsx
+++ b/grafana-plugin/src/components/Avatar/Avatar.tsx
@@ -19,7 +19,7 @@ const Avatar: FC = (props) => {
return null;
}
- return ;
+ return ;
};
export default Avatar;
diff --git a/grafana-plugin/src/components/CardButton/CardButton.module.css b/grafana-plugin/src/components/CardButton/CardButton.module.css
index 44142965..fa007bfb 100644
--- a/grafana-plugin/src/components/CardButton/CardButton.module.css
+++ b/grafana-plugin/src/components/CardButton/CardButton.module.css
@@ -19,7 +19,7 @@
.root_selected::before {
display: block;
- content: "";
+ content: '';
position: absolute;
left: 0;
top: 0;
diff --git a/grafana-plugin/src/components/CardButton/CardButton.test.tsx b/grafana-plugin/src/components/CardButton/CardButton.test.tsx
new file mode 100644
index 00000000..d24adbdc
--- /dev/null
+++ b/grafana-plugin/src/components/CardButton/CardButton.test.tsx
@@ -0,0 +1,36 @@
+import 'jest/matchMedia.ts';
+import React from 'react';
+
+import { describe, expect, test } from '@jest/globals';
+import { fireEvent, render, screen } from '@testing-library/react';
+
+import '@testing-library/jest-dom';
+import CardButton from 'components/CardButton/CardButton';
+
+describe('CardButton', () => {
+ function getProps(onClickMock: jest.Mock = jest.fn()) {
+ return {
+ icon: <>>,
+ description: 'Description',
+ title: 'Title',
+ selected: true,
+ onClick: onClickMock,
+ };
+ }
+
+ test('It updates class and calls onClick prop on click', () => {
+ const onClickMock = jest.fn();
+ render( );
+
+ const rootEl = getRootBlockEl();
+
+ fireEvent.click(rootEl);
+
+ expect(rootEl.classList).toContain('root_selected');
+ expect(onClickMock).toHaveBeenCalled();
+ });
+
+ function getRootBlockEl(): HTMLElement {
+ return screen.queryByTestId('test__cardButton');
+ }
+});
diff --git a/grafana-plugin/src/components/CardButton/CardButton.tsx b/grafana-plugin/src/components/CardButton/CardButton.tsx
index 40259e3c..11076195 100644
--- a/grafana-plugin/src/components/CardButton/CardButton.tsx
+++ b/grafana-plugin/src/components/CardButton/CardButton.tsx
@@ -26,7 +26,12 @@ const CardButton: FC = (props) => {
}, [selected]);
return (
-
+
{icon}
diff --git a/grafana-plugin/src/components/Collapse/Collapse.test.tsx b/grafana-plugin/src/components/Collapse/Collapse.test.tsx
new file mode 100644
index 00000000..d9e94395
--- /dev/null
+++ b/grafana-plugin/src/components/Collapse/Collapse.test.tsx
@@ -0,0 +1,53 @@
+import 'jest/matchMedia.ts';
+import React from 'react';
+
+import { describe, expect, test } from '@jest/globals';
+import { render, fireEvent, screen } from '@testing-library/react';
+
+import Collapse, { CollapseProps } from 'components/Collapse/Collapse';
+
+import '@testing-library/jest-dom';
+
+describe('Collapse', () => {
+ function getProps(isOpen: boolean, onClick: jest.Mock = jest.fn()) {
+ return {
+ label: 'Toggle',
+ isOpen: isOpen,
+ onClick: onClick,
+ } as CollapseProps;
+ }
+
+ test('Content becomes visible on click', () => {
+ render( );
+
+ const hiddenChildrenContent = getChildrenEl();
+ expect(hiddenChildrenContent).toBeNull();
+
+ const toggler = getTogglerEl();
+ fireEvent.click(toggler);
+
+ expect(hiddenChildrenContent).toBeDefined();
+ });
+
+ test('Content is collapsed for [isOpen=false]', () => {
+ render( );
+
+ const content = getChildrenEl();
+ expect(content).toBeNull();
+ });
+
+ test('Content is not collapsed for [isOpen=true]', () => {
+ render( );
+
+ const content = getChildrenEl();
+ expect(content).toBeDefined();
+ });
+
+ function getChildrenEl(): HTMLElement {
+ return screen.queryByTestId('test__children');
+ }
+
+ function getTogglerEl(): HTMLElement {
+ return screen.queryByTestId('test__toggle');
+ }
+});
diff --git a/grafana-plugin/src/components/Collapse/Collapse.tsx b/grafana-plugin/src/components/Collapse/Collapse.tsx
index 940507aa..27644e0d 100644
--- a/grafana-plugin/src/components/Collapse/Collapse.tsx
+++ b/grafana-plugin/src/components/Collapse/Collapse.tsx
@@ -3,11 +3,9 @@ import React, { FC, useCallback, useState } from 'react';
import { Icon } from '@grafana/ui';
import cn from 'classnames/bind';
-import Block from 'components/GBlock/Block';
-
import styles from 'components/Collapse/Collapse.module.css';
-interface CollapseProps {
+export interface CollapseProps {
label: React.ReactNode;
isOpen: boolean;
onToggle?: (isOpen: boolean) => void;
@@ -45,11 +43,19 @@ const Collapse: FC = (props) => {
return (
-
+
- {isOpen &&
{children}
}
+ {isOpen && (
+
+ {children}
+
+ )}
);
};
diff --git a/grafana-plugin/src/components/CursorPagination/CursorPagination.module.css b/grafana-plugin/src/components/CursorPagination/CursorPagination.module.css
deleted file mode 100644
index 63d08ecc..00000000
--- a/grafana-plugin/src/components/CursorPagination/CursorPagination.module.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.root {
- display: block;
-}
diff --git a/grafana-plugin/src/components/CursorPagination/CursorPagination.tsx b/grafana-plugin/src/components/CursorPagination/CursorPagination.tsx
index 33b228e1..907f6a74 100644
--- a/grafana-plugin/src/components/CursorPagination/CursorPagination.tsx
+++ b/grafana-plugin/src/components/CursorPagination/CursorPagination.tsx
@@ -2,12 +2,9 @@ import React, { FC, useCallback, useEffect, useState } from 'react';
import { SelectableValue } from '@grafana/data';
import { Button, HorizontalGroup, Icon, Select } from '@grafana/ui';
-import cn from 'classnames/bind';
import Text from 'components/Text/Text';
-import styles from './CursorPagination.module.css';
-
interface CursorPaginationProps {
current: string;
onChange: (cursor: string, direction: 'prev' | 'next') => void;
@@ -18,8 +15,6 @@ interface CursorPaginationProps {
next: string;
}
-const cx = cn.bind(styles);
-
const CursorPagination: FC
= (props) => {
const { current, onChange, prev, next, itemsPerPage, itemsPerPageOptions, onChangeItemsPerPage } = props;
diff --git a/grafana-plugin/src/components/EscalationsFilters/EscalationsFilters.tsx b/grafana-plugin/src/components/EscalationsFilters/EscalationsFilters.tsx
index c08d2c3d..bcbf3134 100644
--- a/grafana-plugin/src/components/EscalationsFilters/EscalationsFilters.tsx
+++ b/grafana-plugin/src/components/EscalationsFilters/EscalationsFilters.tsx
@@ -1,6 +1,6 @@
import React, { ChangeEvent, FC, useCallback } from 'react';
-import { Icon, Input, Button, IconButton } from '@grafana/ui';
+import { Icon, Input, IconButton } from '@grafana/ui';
import cn from 'classnames/bind';
import styles from './EscalationsFilters.module.css';
diff --git a/grafana-plugin/src/components/GForm/GForm.module.css b/grafana-plugin/src/components/GForm/GForm.module.css
deleted file mode 100644
index 63d08ecc..00000000
--- a/grafana-plugin/src/components/GForm/GForm.module.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.root {
- display: block;
-}
diff --git a/grafana-plugin/src/components/GForm/GForm.tsx b/grafana-plugin/src/components/GForm/GForm.tsx
index 367b420d..a6d65392 100644
--- a/grafana-plugin/src/components/GForm/GForm.tsx
+++ b/grafana-plugin/src/components/GForm/GForm.tsx
@@ -2,18 +2,14 @@ import React, { useCallback } from 'react';
import { Field, Form, Input, InputControl, Select, Switch, TextArea } from '@grafana/ui';
import { capitalCase } from 'change-case';
-import cn from 'classnames/bind';
import { FormItem, FormItemType } from 'components/GForm/GForm.types';
import GSelect from 'containers/GSelect/GSelect';
import RemoteSelect from 'containers/RemoteSelect/RemoteSelect';
-import styles from './GForm.module.css';
-
interface GFormProps {
form: { name: string; fields: FormItem[] };
data: any;
- /* errors: { [key: string]: string }; */
onSubmit: (data: any) => void;
}
@@ -21,8 +17,6 @@ const nullNormalizer = (value: string) => {
return value || null;
};
-const cx = cn.bind(styles);
-
function renderFormControl(formItem: FormItem, register: any, control: any) {
switch (formItem.type) {
case FormItemType.Input:
@@ -99,19 +93,18 @@ const GForm = (props: GFormProps) => {
return (
);
diff --git a/grafana-plugin/src/components/GForm/GForm.types.ts b/grafana-plugin/src/components/GForm/GForm.types.ts
index d24abdb5..06aa38a9 100644
--- a/grafana-plugin/src/components/GForm/GForm.types.ts
+++ b/grafana-plugin/src/components/GForm/GForm.types.ts
@@ -1,5 +1,3 @@
-import { Moment } from 'moment';
-
export enum FormItemType {
'Input' = 'input',
'TextArea' = 'textarea',
@@ -7,13 +5,6 @@ export enum FormItemType {
'GSelect' = 'gselect',
'Switch' = 'switch',
'RemoteSelect' = 'remoteselect',
-
- /* 'InputNumber' = 'input-number',
- 'Select' = 'select',
- 'Switch' = 'switch',
- 'ASelect' = 'aselect',
- 'JustSelect' = 'just-select',
- 'DatePicker' = 'datepicker', */
}
export interface FormItem {
diff --git a/grafana-plugin/src/components/GList/GList.tsx b/grafana-plugin/src/components/GList/GList.tsx
index bb22f8eb..d77817a0 100644
--- a/grafana-plugin/src/components/GList/GList.tsx
+++ b/grafana-plugin/src/components/GList/GList.tsx
@@ -1,4 +1,4 @@
-import React, { FC, useState, useCallback, useRef, useEffect } from 'react';
+import React, { useCallback, useRef, useEffect } from 'react';
import { LoadingPlaceholder } from '@grafana/ui';
import cn from 'classnames/bind';
@@ -37,7 +37,6 @@ const GList = (props: GListProps) => {
const divToScroll = selectedElement.parentElement.parentElement;
const maxScroll = Math.max(0, selectedElement.parentElement.offsetHeight - divToScroll.offsetHeight);
- const minScroll = 0;
const scrollTop =
selectedElement.offsetTop -
diff --git a/grafana-plugin/src/components/GTable/GTable.tsx b/grafana-plugin/src/components/GTable/GTable.tsx
index 0e6aaed5..26ec3c6a 100644
--- a/grafana-plugin/src/components/GTable/GTable.tsx
+++ b/grafana-plugin/src/components/GTable/GTable.tsx
@@ -1,4 +1,4 @@
-import React, { FC, useState, useCallback, useMemo, ChangeEvent } from 'react';
+import React, { FC, useCallback, useMemo, ChangeEvent } from 'react';
import { Pagination, Checkbox, Icon } from '@grafana/ui';
import cn from 'classnames/bind';
@@ -96,7 +96,7 @@ const GTable: FC = (props) => {
const handleMasterCheckboxChange = useCallback(
(event: ChangeEvent) => {
- const { selectedRowKeys, onChange } = rowSelection;
+ const { onChange } = rowSelection;
if (event.target.checked) {
const newRowSelection = data.map((item: any) => item[rowKey as string]);
onChange(newRowSelection);
@@ -107,16 +107,6 @@ const GTable: FC = (props) => {
[data]
);
- /* useEffect(() => { // todo clear selection on data change
- if (rowSelection && rowSelection.selectedRowKeys.length) {
- const { selectedRowKeys, onChange } = rowSelection;
- const newSelectedRowKeys = selectedRowKeys.filter((key: string) =>
- data.some((item: any) => item[rowKey as string] === key)
- );
- onChange(newSelectedRowKeys);
- }
- }, [data?.length]); */
-
const columns = useMemo(() => {
const columns = [...columnsProp];
@@ -146,7 +136,7 @@ const GTable: FC = (props) => {
}, [rowSelection, columnsProp, data]);
return (
-
+
> = (props) => {
contentLabel={title}
className={cx('root')}
overlayClassName={cx('overlay')}
- overlayElement={(props, contentElement) => contentElement} // render without overlay to allow body scroll
- /* bodyOpenClassName={cx('body-open')} */
+ overlayElement={(_props, contentElement) => contentElement} // render without overlay to allow body scroll
contentElement={contentElement}
>
{children}
diff --git a/grafana-plugin/src/components/MonacoJinja2Editor/MonacoJinja2Editor.module.css b/grafana-plugin/src/components/MonacoJinja2Editor/MonacoJinja2Editor.module.css
deleted file mode 100644
index 63d08ecc..00000000
--- a/grafana-plugin/src/components/MonacoJinja2Editor/MonacoJinja2Editor.module.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.root {
- display: block;
-}
diff --git a/grafana-plugin/src/components/MonacoJinja2Editor/MonacoJinja2Editor.tsx b/grafana-plugin/src/components/MonacoJinja2Editor/MonacoJinja2Editor.tsx
index d9198448..24fb3f2b 100644
--- a/grafana-plugin/src/components/MonacoJinja2Editor/MonacoJinja2Editor.tsx
+++ b/grafana-plugin/src/components/MonacoJinja2Editor/MonacoJinja2Editor.tsx
@@ -1,14 +1,11 @@
-import React, { FC, useCallback, useMemo, useRef, useEffect } from 'react';
+import React, { FC, useCallback } from 'react';
import { CodeEditor, CodeEditorSuggestionItemKind, LoadingPlaceholder } from '@grafana/ui';
-import cn from 'classnames/bind';
import { getPaths } from 'utils';
import { conf, language } from './jinja2';
-import styles from './MonacoJinja2Editor.module.css';
-
declare const monaco: any;
interface MonacoJinja2EditorProps {
@@ -19,8 +16,6 @@ interface MonacoJinja2EditorProps {
loading: boolean;
}
-const cx = cn.bind(styles);
-
const PREDEFINED_TERMS = [
'grafana_oncall_link',
'integration_name',
diff --git a/grafana-plugin/src/components/NewScheduleSelector/NewScheduleSelector.tsx b/grafana-plugin/src/components/NewScheduleSelector/NewScheduleSelector.tsx
index f70df5b5..a9786716 100644
--- a/grafana-plugin/src/components/NewScheduleSelector/NewScheduleSelector.tsx
+++ b/grafana-plugin/src/components/NewScheduleSelector/NewScheduleSelector.tsx
@@ -1,6 +1,5 @@
import React, { FC, useCallback, useState } from 'react';
-import { getLocationSrv } from '@grafana/runtime';
import { Button, Drawer, HorizontalGroup, Icon, VerticalGroup } from '@grafana/ui';
import cn from 'classnames/bind';
@@ -39,10 +38,6 @@ const NewScheduleSelector: FC = (props) => {
- {/*
- Manage on-call schedules using your favourite calendar app, such as Google Calendar or Microsoft Outlook. To
- schedule on-call shifts create a new calendar and use events with the teammates usernames
- */}
diff --git a/grafana-plugin/src/components/PageErrorHandlingWrapper/PageErrorHandlingWrapper.tsx b/grafana-plugin/src/components/PageErrorHandlingWrapper/PageErrorHandlingWrapper.tsx
index 5d0445ba..6ca5b9c3 100644
--- a/grafana-plugin/src/components/PageErrorHandlingWrapper/PageErrorHandlingWrapper.tsx
+++ b/grafana-plugin/src/components/PageErrorHandlingWrapper/PageErrorHandlingWrapper.tsx
@@ -2,7 +2,6 @@ import React, { useEffect } from 'react';
import { Button, VerticalGroup } from '@grafana/ui';
import cn from 'classnames/bind';
-import { PropTypes } from 'mobx-react';
import PluginLink from 'components/PluginLink/PluginLink';
import Text from 'components/Text/Text';
@@ -48,7 +47,9 @@ export default function PageErrorHandlingWrapper({
const store = useStore();
- if (!errorData.isWrongTeamError) {return children();}
+ if (!errorData.isWrongTeamError) {
+ return children();
+ }
const currentTeamId = store.userStore.currentUser?.current_team;
const currentTeam = store.grafanaTeamStore.items[currentTeamId]?.name;
diff --git a/grafana-plugin/src/components/Policy/EscalationPolicy.tsx b/grafana-plugin/src/components/Policy/EscalationPolicy.tsx
index 0a8d609b..52c47cd1 100644
--- a/grafana-plugin/src/components/Policy/EscalationPolicy.tsx
+++ b/grafana-plugin/src/components/Policy/EscalationPolicy.tsx
@@ -1,7 +1,7 @@
import React, { ChangeEvent } from 'react';
import { SelectableValue } from '@grafana/data';
-import { Button, Input, Select, Tooltip, IconButton } from '@grafana/ui';
+import { Button, Input, Select, IconButton } from '@grafana/ui';
import cn from 'classnames/bind';
import moment from 'moment-timezone';
import { SortableElement } from 'react-sortable-hoc';
@@ -11,7 +11,6 @@ import PluginLink from 'components/PluginLink/PluginLink';
import TimeRange from 'components/TimeRange/TimeRange';
import Timeline from 'components/Timeline/Timeline';
import GSelect from 'containers/GSelect/GSelect';
-import RemoteSelect from 'containers/RemoteSelect/RemoteSelect';
import UserTooltip from 'containers/UserTooltip/UserTooltip';
import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl';
import { prepareEscalationPolicy } from 'models/escalation_policy/escalation_policy.helpers';
@@ -147,7 +146,7 @@ export class EscalationPolicy extends React.Component }
+ getOptionLabel={({ value }: SelectableValue) => }
/>
);
diff --git a/grafana-plugin/src/components/ScheduleBorderedAvatar/ScheduleBorderedAvatar.tsx b/grafana-plugin/src/components/ScheduleBorderedAvatar/ScheduleBorderedAvatar.tsx
index e6c287e0..396ef49d 100644
--- a/grafana-plugin/src/components/ScheduleBorderedAvatar/ScheduleBorderedAvatar.tsx
+++ b/grafana-plugin/src/components/ScheduleBorderedAvatar/ScheduleBorderedAvatar.tsx
@@ -1,15 +1,9 @@
-import React, { useState, useEffect } from 'react';
+import React from 'react';
-import { FadeTransition } from '@grafana/ui';
import cn from 'classnames/bind';
-import dayjs from 'dayjs';
-import { CSSTransition } from 'react-transition-group';
import styles from './ScheduleBorderedAvatar.module.scss';
-import animationStyles from 'containers/Rotations/Rotations.module.css';
-
-
const cx = cn.bind(styles);
interface ScheduleBorderedAvatarProps {
@@ -52,7 +46,9 @@ export default function ScheduleBorderedAvatar({
}
function renderColorPaths(colors: string[]) {
- if (!colors?.length) {return null;}
+ if (!colors?.length) {
+ return null;
+ }
const colorSchemeList = colors;
if (colors.length === 1) {
@@ -75,7 +71,7 @@ export default function ScheduleBorderedAvatar({
lastX = x;
lastY = y;
- return ;
+ return ;
});
}
}
diff --git a/grafana-plugin/src/components/ScheduleCounter/ScheduleCounter.module.css b/grafana-plugin/src/components/ScheduleCounter/ScheduleCounter.module.css
index f0f2dc1f..b0eea531 100644
--- a/grafana-plugin/src/components/ScheduleCounter/ScheduleCounter.module.css
+++ b/grafana-plugin/src/components/ScheduleCounter/ScheduleCounter.module.css
@@ -28,15 +28,3 @@
.tooltip {
width: auto;
}
-
-/*
-.tooltip__type_link {
- border: 1px solid #6CCF8E;
- background: #132322;
-}
-
-.tooltip__type_warning {
- border: 1px solid #F8D06B;
- background: #3A301E;
-}
-*/
diff --git a/grafana-plugin/src/components/ScheduleCounter/ScheduleCounter.tsx b/grafana-plugin/src/components/ScheduleCounter/ScheduleCounter.tsx
index 9f7293c1..45c17f99 100644
--- a/grafana-plugin/src/components/ScheduleCounter/ScheduleCounter.tsx
+++ b/grafana-plugin/src/components/ScheduleCounter/ScheduleCounter.tsx
@@ -1,6 +1,6 @@
-import React, { FC, useCallback } from 'react';
+import React, { FC } from 'react';
-import { HorizontalGroup, VerticalGroup, Icon, IconButton, Tooltip, IconName } from '@grafana/ui';
+import { HorizontalGroup, VerticalGroup, Icon, Tooltip, IconName } from '@grafana/ui';
import cn from 'classnames/bind';
import Text, { TextType } from 'components/Text/Text';
@@ -25,16 +25,6 @@ const typeToColor = {
warning: 'warning',
};
-const typeToBorderColor = {
- link: '#6CCF8E',
- warning: '#F8D06B',
-};
-
-const typeToBackgroundColor = {
- link: '#132322',
- warning: '#3A301E',
-};
-
const cx = cn.bind(styles);
const ScheduleCounter: FC = (props) => {
diff --git a/grafana-plugin/src/components/ScheduleUserDetails/ScheduleUserDetails.module.css b/grafana-plugin/src/components/ScheduleUserDetails/ScheduleUserDetails.module.css
index 84906035..d07b93c4 100644
--- a/grafana-plugin/src/components/ScheduleUserDetails/ScheduleUserDetails.module.css
+++ b/grafana-plugin/src/components/ScheduleUserDetails/ScheduleUserDetails.module.css
@@ -25,7 +25,7 @@
.hr {
width: 100%;
- margin: 0 -11px;
+ margin: 0 -11px;
}
.times {
diff --git a/grafana-plugin/src/components/ScheduleUserDetails/ScheduleUserDetails.tsx b/grafana-plugin/src/components/ScheduleUserDetails/ScheduleUserDetails.tsx
index 423fb074..0a31abff 100644
--- a/grafana-plugin/src/components/ScheduleUserDetails/ScheduleUserDetails.tsx
+++ b/grafana-plugin/src/components/ScheduleUserDetails/ScheduleUserDetails.tsx
@@ -1,6 +1,6 @@
import React, { FC } from 'react';
-import { Icon, Button, HorizontalGroup, VerticalGroup } from '@grafana/ui';
+import { HorizontalGroup, VerticalGroup } from '@grafana/ui';
import cn from 'classnames/bind';
import dayjs from 'dayjs';
@@ -9,8 +9,6 @@ import Text from 'components/Text/Text';
import { getTzOffsetString } from 'models/timezone/timezone.helpers';
import { User } from 'models/user/user.types';
-import Line from './img/line.svg';
-
import styles from './ScheduleUserDetails.module.css';
interface ScheduleUserDetailsProps {
@@ -20,30 +18,9 @@ interface ScheduleUserDetailsProps {
const cx = cn.bind(styles);
-enum UserOncallStatus {
- Now = 'now',
- Outside = 'outside',
- Inside = 'inside',
-}
-
-const userOncallStatusToText = {
- [UserOncallStatus.Now]: 'Oncall now',
- [UserOncallStatus.Inside]: 'Inside working hours',
- [UserOncallStatus.Outside]: 'Outside working hours',
-};
-
const ScheduleUserDetails: FC = (props) => {
const { user, currentMoment } = props;
-
- const userStatus =
- Math.random() > 0.66
- ? UserOncallStatus.Now
- : Math.random() > 0.33
- ? UserOncallStatus.Inside
- : UserOncallStatus.Outside;
-
const userMoment = currentMoment.tz(user.timezone);
-
const userOffsetHoursStr = getTzOffsetString(userMoment);
return (
@@ -51,67 +28,12 @@ const ScheduleUserDetails: FC = (props) => {
- {/*
-
-
- Push
-
- */}
{user.username}
{`${userMoment.tz(user.timezone).format('DD MMM, HH:mm')}`} {userOffsetHoursStr}
- {/*
- {userOncallStatusToText[userStatus]}
-
-
-
- Next shift
-
-
-
-
- 30 apr, 00:00
- 30 apr, 23:59
-
-
-
-
-
- Last shift
-
-
-
-
- 30 apr, 00:00
- 30 apr, 23:59
-
-
-
-
-
-
-
-
- Contacts
-
-
- mail@grafana.com
-
-
-
- @slackid
-
-
-
- +39 555 449 00 00
- */}
diff --git a/grafana-plugin/src/components/SchedulesFilters/SchedulesFilters.helpers.ts b/grafana-plugin/src/components/SchedulesFilters/SchedulesFilters.helpers.ts
index 3cfbe028..1b35ebb3 100644
--- a/grafana-plugin/src/components/SchedulesFilters/SchedulesFilters.helpers.ts
+++ b/grafana-plugin/src/components/SchedulesFilters/SchedulesFilters.helpers.ts
@@ -1,4 +1,4 @@
-import moment from 'moment';
+import moment from 'moment-timezone';
export function optionToDateString(option: string) {
switch (option) {
diff --git a/grafana-plugin/src/components/SchedulesFilters/SchedulesFilters.tsx b/grafana-plugin/src/components/SchedulesFilters/SchedulesFilters.tsx
index 68fdc946..ce99674f 100644
--- a/grafana-plugin/src/components/SchedulesFilters/SchedulesFilters.tsx
+++ b/grafana-plugin/src/components/SchedulesFilters/SchedulesFilters.tsx
@@ -1,8 +1,8 @@
-import React, { ChangeEvent, useCallback, useMemo, useState } from 'react';
+import React, { useCallback, useMemo } from 'react';
import { DatePickerWithInput, Field, HorizontalGroup, RadioButtonGroup } from '@grafana/ui';
import cn from 'classnames/bind';
-import moment from 'moment';
+import moment from 'moment-timezone';
import { dateStringToOption, optionToDateString } from './SchedulesFilters.helpers';
import { SchedulesFiltersType } from './SchedulesFilters.types';
@@ -17,18 +17,22 @@ interface SchedulesFiltersProps {
className?: string;
}
-const SchedulesFilters = (props: SchedulesFiltersProps) => {
- const { value, onChange, className } = props;
-
- const handleDateChange = useCallback((date: Date) => {
- onChange({ selectedDate: moment(date).format('YYYY-MM-DD') });
- }, []);
+const SchedulesFilters = ({ value, onChange, className }: SchedulesFiltersProps) => {
+ const handleDateChange = useCallback(
+ (date: Date) => {
+ onChange({ selectedDate: moment(date).format('YYYY-MM-DD') });
+ },
+ [onChange]
+ );
const option = useMemo(() => dateStringToOption(value.selectedDate), [value]);
- const handleOptionChange = useCallback((option: string) => {
- onChange({ ...value, selectedDate: optionToDateString(option) });
- }, []);
+ const handleOptionChange = useCallback(
+ (option: string) => {
+ onChange({ ...value, selectedDate: optionToDateString(option) });
+ },
+ [onChange, value]
+ );
const datePickerValue = useMemo(() => moment(value.selectedDate).toDate(), [value]);
diff --git a/grafana-plugin/src/components/SchedulesFilters/SchedulesFilters.types.ts b/grafana-plugin/src/components/SchedulesFilters/SchedulesFilters.types.ts
index cb43e74c..4ec857f9 100644
--- a/grafana-plugin/src/components/SchedulesFilters/SchedulesFilters.types.ts
+++ b/grafana-plugin/src/components/SchedulesFilters/SchedulesFilters.types.ts
@@ -1,5 +1,3 @@
-import { Moment } from 'moment';
-
export interface SchedulesFiltersType {
selectedDate: string;
}
diff --git a/grafana-plugin/src/components/SchedulesFilters_NEW/SchedulesFilters.helpers.ts b/grafana-plugin/src/components/SchedulesFilters_NEW/SchedulesFilters.helpers.ts
index 3cfbe028..1b35ebb3 100644
--- a/grafana-plugin/src/components/SchedulesFilters_NEW/SchedulesFilters.helpers.ts
+++ b/grafana-plugin/src/components/SchedulesFilters_NEW/SchedulesFilters.helpers.ts
@@ -1,4 +1,4 @@
-import moment from 'moment';
+import moment from 'moment-timezone';
export function optionToDateString(option: string) {
switch (option) {
diff --git a/grafana-plugin/src/components/SchedulesFilters_NEW/SchedulesFilters.tsx b/grafana-plugin/src/components/SchedulesFilters_NEW/SchedulesFilters.tsx
index dbcbd942..dcb30d78 100644
--- a/grafana-plugin/src/components/SchedulesFilters_NEW/SchedulesFilters.tsx
+++ b/grafana-plugin/src/components/SchedulesFilters_NEW/SchedulesFilters.tsx
@@ -1,11 +1,10 @@
-import React, { ChangeEvent, useCallback, useMemo, useState } from 'react';
+import React, { ChangeEvent, useCallback } from 'react';
-import { DatePickerWithInput, Field, HorizontalGroup, Icon, Input, RadioButtonGroup } from '@grafana/ui';
+import { Field, HorizontalGroup, Icon, Input, RadioButtonGroup } from '@grafana/ui';
import cn from 'classnames/bind';
import { ScheduleType } from 'models/schedule/schedule.types';
-import { dateStringToOption, optionToDateString } from './SchedulesFilters.helpers';
import { SchedulesFiltersType } from './SchedulesFilters.types';
import styles from './SchedulesFilters.module.css';
diff --git a/grafana-plugin/src/components/SourceCode/SourceCode.module.scss b/grafana-plugin/src/components/SourceCode/SourceCode.module.scss
index 0b281c05..ec139080 100644
--- a/grafana-plugin/src/components/SourceCode/SourceCode.module.scss
+++ b/grafana-plugin/src/components/SourceCode/SourceCode.module.scss
@@ -26,4 +26,4 @@
}
.copyButton {
opacity: 0;
-}
\ No newline at end of file
+}
diff --git a/grafana-plugin/src/components/SourceCode/SourceCode.test.tsx b/grafana-plugin/src/components/SourceCode/SourceCode.test.tsx
new file mode 100644
index 00000000..592e65e8
--- /dev/null
+++ b/grafana-plugin/src/components/SourceCode/SourceCode.test.tsx
@@ -0,0 +1,34 @@
+import 'jest/matchMedia.ts';
+import React from 'react';
+
+import { describe, expect, test } from '@jest/globals';
+import { render, screen } from '@testing-library/react';
+
+import '@testing-library/jest-dom';
+import SourceCode from './SourceCode';
+
+describe('SourceCode', () => {
+ test("SourceCode doesn't render clipboard for [showCopyToClipboard=false]", () => {
+ render( );
+ const codeEl = screen.queryByRole('code');
+ expect(codeEl).toBeNull();
+ });
+
+ test('SourceCode renders clipboard for [showCopyToClipboard=true]', () => {
+ render( );
+ const codeEl = screen.queryByRole('code');
+ expect(codeEl).toBeDefined();
+ });
+
+ test('SourceCode displays just copy icon for [showClipboardIconOnly=true]', () => {
+ render( );
+ expect(screen.queryByTestId('test__copyIcon')).toBeDefined();
+ expect(screen.queryByTestId('test__copyIconWithText')).toBeNull();
+ });
+
+ test('SourceCode displays copy icon and text for [showClipboardIconOnly=false]', () => {
+ render( );
+ expect(screen.queryByTestId('test__copyIcon')).toBeNull();
+ expect(screen.queryByTestId('test__copyIconWithText')).toBeDefined();
+ });
+});
diff --git a/grafana-plugin/src/components/SourceCode/SourceCode.tsx b/grafana-plugin/src/components/SourceCode/SourceCode.tsx
index de97190c..7e9ff5da 100644
--- a/grafana-plugin/src/components/SourceCode/SourceCode.tsx
+++ b/grafana-plugin/src/components/SourceCode/SourceCode.tsx
@@ -1,6 +1,6 @@
import React, { FC } from 'react';
-import { Button, Icon, IconButton } from '@grafana/ui';
+import { Button, IconButton } from '@grafana/ui';
import cn from 'classnames/bind';
import CopyToClipboard from 'react-copy-to-clipboard';
@@ -31,9 +31,15 @@ const SourceCode: FC = (props) => {
}}
>
{showClipboardIconOnly ? (
-
+
) : (
-
+
Copy
)}
diff --git a/grafana-plugin/src/components/Table/Table.tsx b/grafana-plugin/src/components/Table/Table.tsx
index 8c656de5..026b18af 100644
--- a/grafana-plugin/src/components/Table/Table.tsx
+++ b/grafana-plugin/src/components/Table/Table.tsx
@@ -1,6 +1,6 @@
-import React, { FC, useState, useCallback, useMemo, ChangeEvent } from 'react';
+import React, { FC, useMemo } from 'react';
-import { Pagination, Checkbox, Icon, VerticalGroup } from '@grafana/ui';
+import { Pagination, VerticalGroup } from '@grafana/ui';
import cn from 'classnames/bind';
import Table from 'rc-table';
import { TableProps } from 'rc-table/lib/Table';
@@ -34,21 +34,20 @@ export interface Props extends TableProps {
const GTable: FC = (props) => {
const { columns, data, className, pagination, loading, rowKey, expandable, ...restProps } = props;
-
const { page, total: numberOfPages, onChange: onNavigate } = pagination || {};
const expandableFn = useMemo(() => {
return expandable
? {
...expandable,
- expandIcon: ({ expanded, record }) => {
+ expandIcon: ({ expanded }) => {
return (
);
},
- expandedRowClassName: (record, index) => (index % 2 === 0 ? cx('row-even') : cx('row-odd')),
+ expandedRowClassName: (_record, index) => (index % 2 === 0 ? cx('row-even') : cx('row-odd')),
}
: null;
}, [expandable]);
@@ -61,7 +60,7 @@ const GTable: FC = (props) => {
columns={columns}
data={data}
expandable={expandableFn}
- rowClassName={(record, index) => (index % 2 === 0 ? cx('row-even') : cx('row-odd'))}
+ rowClassName={(_record, index) => (index % 2 === 0 ? cx('row-even') : cx('row-odd'))}
{...restProps}
/>
{pagination && (
diff --git a/grafana-plugin/src/components/Text/Text.module.scss b/grafana-plugin/src/components/Text/Text.module.scss
index 411ffd33..febd6c75 100644
--- a/grafana-plugin/src/components/Text/Text.module.scss
+++ b/grafana-plugin/src/components/Text/Text.module.scss
@@ -40,7 +40,6 @@
white-space: nowrap;
}
-
.keyboard {
margin: 0 0.2em;
padding: 0.15em 0.4em 0.1em;
diff --git a/grafana-plugin/src/components/Text/Text.tsx b/grafana-plugin/src/components/Text/Text.tsx
index ca9e4ff2..1570635f 100644
--- a/grafana-plugin/src/components/Text/Text.tsx
+++ b/grafana-plugin/src/components/Text/Text.tsx
@@ -69,9 +69,8 @@ const Text: TextInterface = (props) => {
const handleConfirmEdit = useCallback(() => {
setIsEditMode(false);
-
onTextChange(value);
- }, [value]);
+ }, [value, onTextChange]);
const handleInputChange = useCallback((e: ChangeEvent) => {
setValue(e.target.value);
diff --git a/grafana-plugin/src/components/Timeline/Timeline.tsx b/grafana-plugin/src/components/Timeline/Timeline.tsx
index ab0ff47d..2599f56a 100644
--- a/grafana-plugin/src/components/Timeline/Timeline.tsx
+++ b/grafana-plugin/src/components/Timeline/Timeline.tsx
@@ -1,4 +1,4 @@
-import React, { FC } from 'react';
+import React from 'react';
import cn from 'classnames/bind';
diff --git a/grafana-plugin/src/components/Timeline/TimelineItem.tsx b/grafana-plugin/src/components/Timeline/TimelineItem.tsx
index dec3f52d..59000cfb 100644
--- a/grafana-plugin/src/components/Timeline/TimelineItem.tsx
+++ b/grafana-plugin/src/components/Timeline/TimelineItem.tsx
@@ -1,4 +1,4 @@
-import React, { FC } from 'react';
+import React from 'react';
import cn from 'classnames/bind';
@@ -15,21 +15,19 @@ export interface TimelineItemProps {
children?: any;
}
-const TimelineItem: React.FC = (props) => {
- const { className, contentClassName, children, color = '#3274D9', number } = props;
-
- const style = { backgroundColor: color };
-
- return (
-
- {/**/}
-
- {number}
-
- {/* */}
- {children}
-
- );
-};
+const TimelineItem: React.FC = ({
+ className,
+ contentClassName,
+ children,
+ color = '#3274D9',
+ number,
+}) => (
+
+
+ {number}
+
+ {children}
+
+);
export default TimelineItem;
diff --git a/grafana-plugin/src/components/TimelineMarks/TimelineMarks.tsx b/grafana-plugin/src/components/TimelineMarks/TimelineMarks.tsx
index 82244568..63022c80 100644
--- a/grafana-plugin/src/components/TimelineMarks/TimelineMarks.tsx
+++ b/grafana-plugin/src/components/TimelineMarks/TimelineMarks.tsx
@@ -49,8 +49,9 @@ const TimelineMarks: FC = (props) => {
{debug && (
- {cuts.map((cut, index) => (
+ {cuts.map((_cut, index) => (
{
const items: Item[] = [];
- groups.forEach((group: string[], groupIndex: number) => {
+ groups.forEach((_group: string[], groupIndex: number) => {
items.push({
key: `group-${groupIndex}`,
type: 'group',
diff --git a/grafana-plugin/src/components/UserGroups/UserGroups.module.css b/grafana-plugin/src/components/UserGroups/UserGroups.module.css
index d48834b8..df6ec4f8 100644
--- a/grafana-plugin/src/components/UserGroups/UserGroups.module.css
+++ b/grafana-plugin/src/components/UserGroups/UserGroups.module.css
@@ -24,7 +24,7 @@
.separator::before {
display: block;
- content: "";
+ content: '';
flex-grow: 1;
border-bottom: var(--border-medium);
height: 0;
@@ -33,7 +33,7 @@
.separator::after {
display: block;
- content: "";
+ content: '';
flex-grow: 1;
border-bottom: var(--border-medium);
height: 0;
diff --git a/grafana-plugin/src/components/UserGroups/UserGroups.tsx b/grafana-plugin/src/components/UserGroups/UserGroups.tsx
index e7953645..af1fb44f 100644
--- a/grafana-plugin/src/components/UserGroups/UserGroups.tsx
+++ b/grafana-plugin/src/components/UserGroups/UserGroups.tsx
@@ -1,6 +1,6 @@
-import React, { useCallback, useEffect, useMemo } from 'react';
+import React, { useCallback, useMemo } from 'react';
-import { VerticalGroup, HorizontalGroup, IconButton, Field, Input } from '@grafana/ui';
+import { VerticalGroup, HorizontalGroup, IconButton } from '@grafana/ui';
import { arrayMoveImmutable } from 'array-move';
import cn from 'classnames/bind';
import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
@@ -45,7 +45,7 @@ const UserGroups = (props: UserGroupsProps) => {
k++;
if (k === index) {
- newGroups[i] = newGroups[i].filter((item, itemIndex) => itemIndex !== j);
+ newGroups[i] = newGroups[i].filter((_item, itemIndex) => itemIndex !== j);
onChange(newGroups.filter((group) => group.length));
return;
}
diff --git a/grafana-plugin/src/components/UserTimezoneSelect/UserTimezoneSelect.tsx b/grafana-plugin/src/components/UserTimezoneSelect/UserTimezoneSelect.tsx
index 83a4882f..df0e3226 100644
--- a/grafana-plugin/src/components/UserTimezoneSelect/UserTimezoneSelect.tsx
+++ b/grafana-plugin/src/components/UserTimezoneSelect/UserTimezoneSelect.tsx
@@ -3,7 +3,6 @@ import React, { FC, useCallback, useMemo } from 'react';
import { Select } from '@grafana/ui';
import cn from 'classnames/bind';
import dayjs from 'dayjs';
-import { get } from 'lodash-es';
import { getTzOffsetString } from 'models/timezone/timezone.helpers';
import { Timezone } from 'models/timezone/timezone.types';
diff --git a/grafana-plugin/src/components/UsersFilters/UsersFilters.tsx b/grafana-plugin/src/components/UsersFilters/UsersFilters.tsx
index 342ee934..ba2c6567 100644
--- a/grafana-plugin/src/components/UsersFilters/UsersFilters.tsx
+++ b/grafana-plugin/src/components/UsersFilters/UsersFilters.tsx
@@ -70,6 +70,7 @@ const UsersFilters = (props: UsersFiltersProps) => {
{roleOptions.map((option) => (
= ({ children }) => {
+ return <>{children}>;
+};
+
interface VerticalTabsBarProps {
children: Array> | React.ReactElement;
activeTab: string;
onChange: (id: string) => void;
}
-const cx = cn.bind(styles);
-
const VerticalTabsBar = (props: VerticalTabsBarProps) => {
const { children, activeTab, onChange } = props;
@@ -25,8 +33,9 @@ const VerticalTabsBar = (props: VerticalTabsBarProps) => {
{React.Children.toArray(children)
.filter(Boolean)
- .map((child: React.ReactElement) => (
+ .map((child: React.ReactElement, idx) => (
@@ -38,12 +47,3 @@ const VerticalTabsBar = (props: VerticalTabsBarProps) => {
};
export default VerticalTabsBar;
-
-interface TabProps {
- id: string;
- children?: any;
-}
-
-export const VerticalTab: FC
= ({ children }) => {
- return <>{children}>;
-};
diff --git a/grafana-plugin/src/components/WithConfirm/WithConfirm.module.css b/grafana-plugin/src/components/WithConfirm/WithConfirm.module.css
deleted file mode 100644
index 63d08ecc..00000000
--- a/grafana-plugin/src/components/WithConfirm/WithConfirm.module.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.root {
- display: block;
-}
diff --git a/grafana-plugin/src/components/WithConfirm/WithConfirm.tsx b/grafana-plugin/src/components/WithConfirm/WithConfirm.tsx
index 67a53cd7..e16e288b 100644
--- a/grafana-plugin/src/components/WithConfirm/WithConfirm.tsx
+++ b/grafana-plugin/src/components/WithConfirm/WithConfirm.tsx
@@ -1,9 +1,6 @@
-import React, { FC, ReactElement, useCallback, useState } from 'react';
+import React, { ReactElement, useCallback, useState } from 'react';
import { ConfirmModal } from '@grafana/ui';
-import cn from 'classnames/bind';
-
-import styles from './WithConfirm.module.css';
interface WithConfirmProps {
children: ReactElement;
@@ -13,8 +10,6 @@ interface WithConfirmProps {
disabled?: boolean;
}
-const cx = cn.bind(styles);
-
const WithConfirm = (props: WithConfirmProps) => {
const { children, title = 'Are you sure to delete?', body, confirmText = 'Delete', disabled } = props;
diff --git a/grafana-plugin/src/components/WorkingHours/WorkingHours.helpers.ts b/grafana-plugin/src/components/WorkingHours/WorkingHours.helpers.ts
index 52c7579f..d468870f 100644
--- a/grafana-plugin/src/components/WorkingHours/WorkingHours.helpers.ts
+++ b/grafana-plugin/src/components/WorkingHours/WorkingHours.helpers.ts
@@ -71,7 +71,7 @@ export const getNonWorkingMoments = (startMoment, endMoment, workingHours) => {
const nonWorkingMoments = [{ start: startMoment, end: endMoment }];
let lastNonWorkingRange = nonWorkingMoments[0];
- for (const [i, range] of workingHours.entries()) {
+ for (const [_i, range] of workingHours.entries()) {
lastNonWorkingRange.end = range.start;
lastNonWorkingRange = { start: range.end, end: undefined };
diff --git a/grafana-plugin/src/components/WorkingHours/WorkingHours.tsx b/grafana-plugin/src/components/WorkingHours/WorkingHours.tsx
index 39b925f1..13ef9bc3 100644
--- a/grafana-plugin/src/components/WorkingHours/WorkingHours.tsx
+++ b/grafana-plugin/src/components/WorkingHours/WorkingHours.tsx
@@ -2,7 +2,6 @@ import React, { FC, useMemo } from 'react';
import cn from 'classnames/bind';
import dayjs from 'dayjs';
-import localeData from 'dayjs/plugin/localeData';
import { Timezone } from 'models/timezone/timezone.types';
@@ -11,8 +10,6 @@ import { getNonWorkingMoments, getWorkingMoments } from './WorkingHours.helpers'
import styles from './WorkingHours.module.css';
-import { start } from 'repl';
-
interface WorkingHoursProps {
timezone: Timezone;
workingHours: any;
@@ -34,33 +31,11 @@ const WorkingHours: FC = (props) => {
[startMoment, endMoment, workingHours, timezone]
);
- /*console.log(
- workingMoments.map(({ start, end }) => `${start.diff(startMoment, 'hours')} - ${end.diff(startMoment, 'hours')}`)
- );*/
-
const nonWorkingMoments = useMemo(
() => getNonWorkingMoments(startMoment, endMoment, workingMoments),
[startMoment, endMoment, workingMoments]
);
- // console.log(startMoment, startMoment.toString());
-
- /* console.log(
- workingMoments.map(
- (range) =>
- `${range.start.tz(timezone).format('D MMM ddd HH:ss')} - ${range.end.tz(timezone).format('D MMM ddd HH:ss')}`
- )
- ); */
-
- // console.log(workingHours);
-
- /*console.log(
- nonWorkingMoments.map(
- (range) =>
- `${range.start.tz(timezone).format('D MMM ddd HH:ss')} - ${range.end.tz(timezone).format('D MMM ddd HH:ss')}`
- )
- );*/
-
return (
(
+
+ Demo alert was generated. Find it on the
+
"Alert Groups"
+ page and make sure it didn't freak out your colleagues 😉
+
+);
+
@observer
class AlertRules extends React.Component {
state: AlertRulesState = {
@@ -77,9 +84,7 @@ class AlertRules extends React.Component {
}
}
- componentDidUpdate(prevProps: Readonly, prevState: Readonly, snapshot?: any) {
- const { store } = this.props;
-
+ componentDidUpdate(prevProps: Readonly, _prevState: Readonly, _snapshot?: any) {
if (this.props.alertReceiveChannelId && prevProps.alertReceiveChannelId !== this.props.alertReceiveChannelId) {
if (prevProps.alertReceiveChannelId) {
this.setState({
@@ -130,14 +135,12 @@ class AlertRules extends React.Component {
render() {
const {
alertReceiveChannelIdToCreateChannelFilter,
- channelFilterToEdit,
- settingsVisible,
routeToDelete,
escalationChainIdToCopy,
channelFilterIdToCopyEscalationChain,
editIntegrationName,
} = this.state;
- const { store, alertReceiveChannelId, onEditAlertReceiveChannelTemplates, onShowSettings } = this.props;
+ const { store, alertReceiveChannelId, onShowSettings } = this.props;
const { alertReceiveChannelStore } = store;
const alertReceiveChannel = alertReceiveChannelStore.items[alertReceiveChannelId];
@@ -153,7 +156,6 @@ class AlertRules extends React.Component {
- {/*
*/}
Escalate
@@ -197,7 +199,6 @@ class AlertRules extends React.Component {
)}
- {/* */}
{
handleEscalationChainCreate = async (id: EscalationChain['id']) => {
const { store } = this.props;
const { alertReceiveChannelStore } = store;
- const { escalationChainIdToCopy, channelFilterIdToCopyEscalationChain } = this.state;
+ const { channelFilterIdToCopyEscalationChain } = this.state;
await alertReceiveChannelStore
.saveChannelFilter(channelFilterIdToCopyEscalationChain, { escalation_chain: id })
@@ -389,8 +390,7 @@ class AlertRules extends React.Component {
};
handleDeleteAlertReceiveChannel = () => {
- const { store, alertReceiveChannelId, onDelete } = this.props;
-
+ const { alertReceiveChannelId, onDelete } = this.props;
onDelete(alertReceiveChannelId);
};
@@ -460,12 +460,13 @@ class AlertRules extends React.Component {
return (
- {channelFilterIds.map((channelFilterId: ChannelFilter['id'], index: number) => {
+ {channelFilterIds.map((channelFilterId: ChannelFilter['id']) => {
const channelFilter = store.alertReceiveChannelStore.channelFilters[channelFilterId];
if (channelFilterId === channelFilterToEdit?.id) {
return (
{
};
getChannelFilterToggleHandler = (channelFilterId: ChannelFilter['id']) => {
- const { store } = this.props;
-
return (isOpen: boolean) => {
const { expandedRoutes } = this.state;
@@ -685,17 +684,9 @@ class AlertRules extends React.Component {
channelFilterId: ChannelFilter['id']
) => {
const { store } = this.props;
-
- const { telegramChannelStore, teamStore } = store;
const channelFilterIds = store.alertReceiveChannelStore.channelFilterIds[alertReceiveChannelId];
-
const channelFilter = store.alertReceiveChannelStore.channelFilters[channelFilterId];
- const telegramChannel =
- channelFilter.telegram_channel && telegramChannelStore.items[channelFilter.telegram_channel];
-
- const slackChannelName = getSlackChannelName(channelFilter.slack_channel || teamStore.currentTeam?.slack_channel);
-
const index = channelFilterIds.indexOf(channelFilterId);
return (
@@ -760,9 +751,7 @@ class AlertRules extends React.Component
{
_renderEscalationPolicies = (channelFilterId: ChannelFilter['id']) => {
const { store } = this.props;
-
const channelFilter = store.alertReceiveChannelStore.channelFilters[channelFilterId];
-
const escalationChainId = channelFilter.escalation_chain;
return (
@@ -802,13 +791,7 @@ class AlertRules extends React.Component {
return () => {
alertReceiveChannelStore.sendDemoAlert(id).then(() => {
alertReceiveChannelStore.updateCounters();
- openNotification(
-
- Demo alert was generated. Find it on the
-
"Alert Groups"
- page and make sure it didn't freak out your colleagues 😉
-
- );
+ openNotification( );
});
};
};
@@ -819,13 +802,7 @@ class AlertRules extends React.Component {
} = this.props;
return () => {
alertReceiveChannelStore.sendDemoAlertToParticularRoute(id).then(() => {
- openNotification(
-
- Demo alert was generated. Find it on the
-
"Alert Groups"
- page and make sure it didn't freak out your colleagues 😉
-
- );
+ openNotification( );
});
};
};
diff --git a/grafana-plugin/src/containers/AlertRules/parts/connectors/SlackConnector.tsx b/grafana-plugin/src/containers/AlertRules/parts/connectors/SlackConnector.tsx
index a5997925..3861b596 100644
--- a/grafana-plugin/src/containers/AlertRules/parts/connectors/SlackConnector.tsx
+++ b/grafana-plugin/src/containers/AlertRules/parts/connectors/SlackConnector.tsx
@@ -30,7 +30,7 @@ const SlackConnector = (props: SlackConnectorProps) => {
const channelFilter = store.alertReceiveChannelStore.channelFilters[channelFilterId];
- const handleSlackChannelChange = useCallback((value: SlackChannel['id'], slackChannel: SlackChannel) => {
+ const handleSlackChannelChange = useCallback((_value: SlackChannel['id'], slackChannel: SlackChannel) => {
// @ts-ignore actually slack_channel is just slack_channel_id when saving
alertReceiveChannelStore.saveChannelFilter(channelFilterId, { slack_channel: slackChannel?.slack_id || null });
}, []);
diff --git a/grafana-plugin/src/containers/AlertRules/parts/connectors/TelegramConnector.tsx b/grafana-plugin/src/containers/AlertRules/parts/connectors/TelegramConnector.tsx
index 090fbe71..26593c94 100644
--- a/grafana-plugin/src/containers/AlertRules/parts/connectors/TelegramConnector.tsx
+++ b/grafana-plugin/src/containers/AlertRules/parts/connectors/TelegramConnector.tsx
@@ -18,15 +18,11 @@ interface TelegramConnectorProps {
channelFilterId: ChannelFilter['id'];
}
-const TelegramConnector = (props: TelegramConnectorProps) => {
- const { channelFilterId } = props;
+const TelegramConnector = ({ channelFilterId }: TelegramConnectorProps) => {
+ const { alertReceiveChannelStore } = useStore();
+ const channelFilter = alertReceiveChannelStore.channelFilters[channelFilterId];
- const store = useStore();
- const { teamStore, alertReceiveChannelStore } = store;
-
- const channelFilter = store.alertReceiveChannelStore.channelFilters[channelFilterId];
-
- const handleTelegramChannelChange = useCallback((value: TelegramChannel['id'], telegramChannel: TelegramChannel) => {
+ const handleTelegramChannelChange = useCallback((_value: TelegramChannel['id'], telegramChannel: TelegramChannel) => {
alertReceiveChannelStore.saveChannelFilter(channelFilterId, { telegram_channel: telegramChannel?.id || null });
}, []);
diff --git a/grafana-plugin/src/containers/AlertRules/parts/index.module.css b/grafana-plugin/src/containers/AlertRules/parts/index.module.css
deleted file mode 100644
index 63d08ecc..00000000
--- a/grafana-plugin/src/containers/AlertRules/parts/index.module.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.root {
- display: block;
-}
diff --git a/grafana-plugin/src/containers/AlertRules/parts/index.tsx b/grafana-plugin/src/containers/AlertRules/parts/index.tsx
index 6f3911d3..fdff1405 100644
--- a/grafana-plugin/src/containers/AlertRules/parts/index.tsx
+++ b/grafana-plugin/src/containers/AlertRules/parts/index.tsx
@@ -1,7 +1,6 @@
import React from 'react';
import { VerticalGroup } from '@grafana/ui';
-import cn from 'classnames/bind';
import Timeline from 'components/Timeline/Timeline';
import SlackConnector from 'containers/AlertRules/parts/connectors/SlackConnector';
@@ -9,10 +8,6 @@ import TelegramConnector from 'containers/AlertRules/parts/connectors/TelegramCo
import { ChannelFilter } from 'models/channel_filter';
import { useStore } from 'state/useStore';
-import styles from 'containers/AlertRules/parts/index.module.css';
-
-const cx = cn.bind(styles);
-
interface ChatOpsConnectorsProps {
channelFilterId: ChannelFilter['id'];
}
diff --git a/grafana-plugin/src/containers/AlertTemplatesFormContainer/AlertTemplatesFormContainer.tsx b/grafana-plugin/src/containers/AlertTemplatesFormContainer/AlertTemplatesFormContainer.tsx
index ac782296..f1ef2f51 100644
--- a/grafana-plugin/src/containers/AlertTemplatesFormContainer/AlertTemplatesFormContainer.tsx
+++ b/grafana-plugin/src/containers/AlertTemplatesFormContainer/AlertTemplatesFormContainer.tsx
@@ -1,12 +1,10 @@
import React, { useCallback, useEffect, useState } from 'react';
-import { Button } from '@grafana/ui';
import { observer } from 'mobx-react';
import AlertTemplatesForm from 'components/AlertTemplates/AlertTemplatesForm';
import { AlertReceiveChannel } from 'models/alert_receive_channel';
import { Alert } from 'models/alertgroup/alertgroup.types';
-import { RootStore } from 'state';
import { useStore } from 'state/useStore';
import { openNotification } from 'utils';
diff --git a/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenForm.tsx b/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenForm.tsx
index cf471d17..a6047a34 100644
--- a/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenForm.tsx
+++ b/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenForm.tsx
@@ -10,7 +10,6 @@ import SourceCode from 'components/SourceCode/SourceCode';
import { ApiToken } from 'models/api_token/api_token.types';
import { useStore } from 'state/useStore';
import { openErrorNotification, openNotification } from 'utils';
-import { getItem } from 'utils/localStorage';
import styles from './ApiTokenForm.module.css';
diff --git a/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenSettings.tsx b/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenSettings.tsx
index f9a9f0bb..1d4e866b 100644
--- a/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenSettings.tsx
+++ b/grafana-plugin/src/containers/ApiTokenSettings/ApiTokenSettings.tsx
@@ -3,7 +3,7 @@ import React from 'react';
import { Button, HorizontalGroup } from '@grafana/ui';
import cn from 'classnames/bind';
import { observer } from 'mobx-react';
-import moment from 'moment';
+import moment from 'moment-timezone';
import GTable from 'components/GTable/GTable';
import Text from 'components/Text/Text';
@@ -74,13 +74,6 @@ class ApiTokens extends React.Component {
API Tokens
- {/*
- API Docs
-
- |
-
- Terraform Docs
- */}
void;
}
-const AttachIncidentForm = observer((props: AttachIncidentFormProps) => {
- const { id, onUpdate, onHide } = props;
+interface GroupedAlertNumberProps {
+ value: Alert['pk'];
+}
+const AttachIncidentForm = observer(({ id, onUpdate, onHide }: AttachIncidentFormProps) => {
const store = useStore();
const { alertGroupStore } = store;
@@ -43,17 +43,10 @@ const AttachIncidentForm = observer((props: AttachIncidentFormProps) => {
onHide();
onUpdate();
});
- }, [selected]);
+ }, [selected, alertGroupStore, id, onHide, onUpdate]);
- interface GroupedAlertNumberProps {
- value: Alert['pk'];
- }
-
- const GroupedAlertNumber = observer((props: GroupedAlertNumberProps) => {
- const store = useStore();
- const { value } = props;
-
- const { alertGroupStore } = store;
+ const GroupedAlertNumber = observer(({ value }: GroupedAlertNumberProps) => {
+ const { alertGroupStore } = useStore();
const alert = alertGroupStore.items[value];
return (
@@ -88,7 +81,7 @@ const AttachIncidentForm = observer((props: AttachIncidentFormProps) => {
displayField="render_for_web.title"
placeholder="Select Incident"
className={cx('select', 'control')}
- filterOptions={(id) => id !== props.id}
+ filterOptions={(optionId) => optionId !== id}
value={selected}
onChange={getChangeHandler}
getDescription={(item: Alert) => moment(item.started_at).format('MMM DD, YYYY hh:mm A')}
diff --git a/grafana-plugin/src/containers/CreateAlertReceiveChannelContainer/CreateAlertReceiveChannelContainer.tsx b/grafana-plugin/src/containers/CreateAlertReceiveChannelContainer/CreateAlertReceiveChannelContainer.tsx
index 7d3c8ff1..289b44f7 100644
--- a/grafana-plugin/src/containers/CreateAlertReceiveChannelContainer/CreateAlertReceiveChannelContainer.tsx
+++ b/grafana-plugin/src/containers/CreateAlertReceiveChannelContainer/CreateAlertReceiveChannelContainer.tsx
@@ -1,6 +1,6 @@
import React, { ChangeEvent, useCallback, useState } from 'react';
-import { Card, EmptySearchResult, HorizontalGroup, Input, Modal, VerticalGroup, Tag } from '@grafana/ui';
+import { EmptySearchResult, HorizontalGroup, Input, Modal, VerticalGroup, Tag } from '@grafana/ui';
import cn from 'classnames/bind';
import { observer } from 'mobx-react';
@@ -63,7 +63,7 @@ const CreateAlertReceiveChannelContainer = observer((props: CreateAlertReceiveCh
{options.length ? (
- options.map((alertReceiveChannelChoice, index) => {
+ options.map((alertReceiveChannelChoice) => {
return (
Could not find anything matching your query
)}
- {/* Need to add documentation link to Integrations
- */}
);
});
diff --git a/grafana-plugin/src/containers/DefaultPageLayout/DefaultPageLayout.helpers.tsx b/grafana-plugin/src/containers/DefaultPageLayout/DefaultPageLayout.helpers.tsx
index d680f609..983597c3 100644
--- a/grafana-plugin/src/containers/DefaultPageLayout/DefaultPageLayout.helpers.tsx
+++ b/grafana-plugin/src/containers/DefaultPageLayout/DefaultPageLayout.helpers.tsx
@@ -22,7 +22,7 @@ export function getSlackMessage(slackError: SlackError, team: Team) {
if (slackError === SlackError.USER_ALREADY_CONNECTED) {
return (
- <>Couldn’t connect to Slack. This Slack account has already been connected to another user in this organization>
+ <>Couldn't connect to Slack. This Slack account has already been connected to another user in this organization>
);
}
diff --git a/grafana-plugin/src/containers/DefaultPageLayout/helper.ts b/grafana-plugin/src/containers/DefaultPageLayout/helper.ts
index 5af787af..80c58bb8 100644
--- a/grafana-plugin/src/containers/DefaultPageLayout/helper.ts
+++ b/grafana-plugin/src/containers/DefaultPageLayout/helper.ts
@@ -1,5 +1,3 @@
-import React from 'react';
-
import { User } from 'models/user/user.types';
export const getIfChatOpsConnected = (user: User) => {
diff --git a/grafana-plugin/src/containers/EscalationChainCard/EscalationChainCard.tsx b/grafana-plugin/src/containers/EscalationChainCard/EscalationChainCard.tsx
index f483b8d6..22203807 100644
--- a/grafana-plugin/src/containers/EscalationChainCard/EscalationChainCard.tsx
+++ b/grafana-plugin/src/containers/EscalationChainCard/EscalationChainCard.tsx
@@ -49,22 +49,6 @@ const EscalationChainCard = observer((props: AlertReceiveChannelCardProps) => {
)}
- {/*
-
- {alertReceiveChannel.alert_count} alerts in {alertReceiveChannel.alert_groups_count} {' '}
- incidents
-
-
- |
-
-
-
- {integration?.display_name}
-
- */}
diff --git a/grafana-plugin/src/containers/EscalationChainForm/EscalationChainForm.tsx b/grafana-plugin/src/containers/EscalationChainForm/EscalationChainForm.tsx
index a927d56e..92d93925 100644
--- a/grafana-plugin/src/containers/EscalationChainForm/EscalationChainForm.tsx
+++ b/grafana-plugin/src/containers/EscalationChainForm/EscalationChainForm.tsx
@@ -3,7 +3,6 @@ import React, { ChangeEvent, FC, useCallback, useState } from 'react';
import { Button, Field, HorizontalGroup, Input, Modal } from '@grafana/ui';
import cn from 'classnames/bind';
-import { ChannelFilter } from 'models/channel_filter/channel_filter.types';
import { EscalationChain } from 'models/escalation_chain/escalation_chain.types';
import { useStore } from 'state/useStore';
diff --git a/grafana-plugin/src/containers/EscalationChainSteps/EscalationChainSteps.tsx b/grafana-plugin/src/containers/EscalationChainSteps/EscalationChainSteps.tsx
index 8f9174aa..66ec99a8 100644
--- a/grafana-plugin/src/containers/EscalationChainSteps/EscalationChainSteps.tsx
+++ b/grafana-plugin/src/containers/EscalationChainSteps/EscalationChainSteps.tsx
@@ -62,13 +62,10 @@ const EscalationChainSteps = observer((props: EscalationChainStepsProps) => {
{addonBefore}
{escalationPolicyIds ? (
escalationPolicyIds.map((escalationPolicyId, index) => {
- // const COLOR_RED = '#FF0000';
const COLOR_RED = '#E60000';
- // const STEP_COLORS = ['#52C41A', '#A0D911', '#FADB14', '#FAAD14', COLOR_RED];
const STEP_COLORS = ['#1A7F4B', '#33cc33', '#ffbf00', '#FF8000', COLOR_RED];
const { escalationPolicyStore } = store;
-
const escalationPolicy = escalationPolicyStore.items[escalationPolicyId];
if (!escalationPolicy) {
@@ -102,7 +99,6 @@ const EscalationChainSteps = observer((props: EscalationChainStepsProps) => {
menuShouldPortal
placeholder="Add escalation step..."
onChange={handleCreateEscalationStep}
- /* isOptionDisabled={(...rest) => console.log(rest)}*/
options={escalationPolicyStore.webEscalationChoices.map((choice: EscalationPolicyOption) => ({
value: choice.value,
label: choice.create_display_name,
diff --git a/grafana-plugin/src/containers/GSelect/GSelect.tsx b/grafana-plugin/src/containers/GSelect/GSelect.tsx
index 07e8c562..d448e75d 100644
--- a/grafana-plugin/src/containers/GSelect/GSelect.tsx
+++ b/grafana-plugin/src/containers/GSelect/GSelect.tsx
@@ -1,12 +1,10 @@
-import React, { ReactElement, useCallback, useEffect, useState, useMemo } from 'react';
+import React, { ReactElement, useCallback, useEffect } from 'react';
import { SelectableValue } from '@grafana/data';
-import { Select, MultiSelect, AsyncMultiSelect, AsyncSelect, Tooltip } from '@grafana/ui';
+import { AsyncMultiSelect, AsyncSelect } from '@grafana/ui';
import cn from 'classnames/bind';
import { get, isNil } from 'lodash-es';
import { observer } from 'mobx-react';
-import Emoji from 'react-emoji-render';
-import { debounce } from 'throttle-debounce';
import { useStore } from 'state/useStore';
diff --git a/grafana-plugin/src/containers/GrafanaTeamSelect/GrafanaTeamSelect.tsx b/grafana-plugin/src/containers/GrafanaTeamSelect/GrafanaTeamSelect.tsx
index b2984341..31de26c6 100644
--- a/grafana-plugin/src/containers/GrafanaTeamSelect/GrafanaTeamSelect.tsx
+++ b/grafana-plugin/src/containers/GrafanaTeamSelect/GrafanaTeamSelect.tsx
@@ -40,8 +40,10 @@ const GrafanaTeamSelect = observer((props: GrafanaTeamSelectProps) => {
window.location.search = queryParams.toString();
function mapCurrentPage() {
- if (currentPage === 'incident') {return 'incidents'}
- return currentPage
+ if (currentPage === 'incident') {
+ return 'incidents';
+ }
+ return currentPage;
}
};
diff --git a/grafana-plugin/src/containers/HeartbeatModal/HeartbeatForm.tsx b/grafana-plugin/src/containers/HeartbeatModal/HeartbeatForm.tsx
index 2d9f9eba..8695d4e6 100644
--- a/grafana-plugin/src/containers/HeartbeatModal/HeartbeatForm.tsx
+++ b/grafana-plugin/src/containers/HeartbeatModal/HeartbeatForm.tsx
@@ -1,7 +1,7 @@
import React, { useCallback, useEffect, useState } from 'react';
import { SelectableValue } from '@grafana/data';
-import { Button, HorizontalGroup, Modal, Select } from '@grafana/ui';
+import { Button, HorizontalGroup, Select } from '@grafana/ui';
import cn from 'classnames/bind';
import { observer } from 'mobx-react';
import Emoji from 'react-emoji-render';
diff --git a/grafana-plugin/src/containers/IncidentsFilters/IncidentFilters.helpers.ts b/grafana-plugin/src/containers/IncidentsFilters/IncidentFilters.helpers.ts
index 3e84706a..58868ab4 100644
--- a/grafana-plugin/src/containers/IncidentsFilters/IncidentFilters.helpers.ts
+++ b/grafana-plugin/src/containers/IncidentsFilters/IncidentFilters.helpers.ts
@@ -1,6 +1,3 @@
-import { capitalCase } from 'change-case';
-import qs from 'query-string';
-
import { convertRelativeToAbsoluteDate } from 'utils/datetime';
import { FilterOption } from './IncidentFilters.types';
diff --git a/grafana-plugin/src/containers/IncidentsFilters/IncidentFilters.types.ts b/grafana-plugin/src/containers/IncidentsFilters/IncidentFilters.types.ts
index fc32b882..a2fd4683 100644
--- a/grafana-plugin/src/containers/IncidentsFilters/IncidentFilters.types.ts
+++ b/grafana-plugin/src/containers/IncidentsFilters/IncidentFilters.types.ts
@@ -1,5 +1,3 @@
-import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types';
-import { IncidentStatus } from 'models/alertgroup/alertgroup.types';
import { SelectOption } from 'state/types';
export interface IncidentsFiltersType {}
diff --git a/grafana-plugin/src/containers/IncidentsFilters/IncidentsFilters.tsx b/grafana-plugin/src/containers/IncidentsFilters/IncidentsFilters.tsx
index fef3571b..adb54919 100644
--- a/grafana-plugin/src/containers/IncidentsFilters/IncidentsFilters.tsx
+++ b/grafana-plugin/src/containers/IncidentsFilters/IncidentsFilters.tsx
@@ -106,7 +106,7 @@ class IncidentsFilters extends Component
{filters.map((filterOption: FilterOption) => (
-
+
{capitalCase(filterOption.name)}: {this.renderFilterOption(filterOption)}
@@ -130,24 +130,14 @@ class IncidentsFilters extends Component
{
- const { filters, values } = this.state;
+ const { filters } = this.state;
const searchFilter = filters.find((filter: FilterOption) => filter.name === 'search');
@@ -217,7 +207,7 @@ class IncidentsFilters extends Component {
- const { filters, values } = this.state;
+ const { filters } = this.state;
return () => {
const newFilters = filters.filter((filterOption: FilterOption) => filterOption.name !== filterName);
@@ -306,11 +296,6 @@ class IncidentsFilters extends Component {
- return (value: SelectableValue[], items: any[]) => {
+ return (value: SelectableValue[], _items: any[]) => {
this.onFiltersValueChange(name, value);
};
};
diff --git a/grafana-plugin/src/containers/IntegrationSettings/IntegrationSettings.tsx b/grafana-plugin/src/containers/IntegrationSettings/IntegrationSettings.tsx
index e0192f1c..2d35e3d8 100644
--- a/grafana-plugin/src/containers/IntegrationSettings/IntegrationSettings.tsx
+++ b/grafana-plugin/src/containers/IntegrationSettings/IntegrationSettings.tsx
@@ -1,17 +1,7 @@
import React, { useCallback, useEffect, useState } from 'react';
-import { getLocationSrv, setLocationSrv } from '@grafana/runtime';
-import {
- Drawer,
- Tab,
- TabContent,
- TabsBar,
- IconButton,
- Button,
- HorizontalGroup,
- VerticalGroup,
- Input,
-} from '@grafana/ui';
+import { getLocationSrv } from '@grafana/runtime';
+import { Drawer, Tab, TabContent, TabsBar, Button, VerticalGroup, Input } from '@grafana/ui';
import cn from 'classnames/bind';
import { observer } from 'mobx-react';
import CopyToClipboard from 'react-copy-to-clipboard';
@@ -21,16 +11,13 @@ import IntegrationLogo from 'components/IntegrationLogo/IntegrationLogo';
import Text from 'components/Text/Text';
import AlertTemplatesFormContainer from 'containers/AlertTemplatesFormContainer/AlertTemplatesFormContainer';
import HeartbeatForm from 'containers/HeartbeatModal/HeartbeatForm';
-import { UserSettingsTab } from 'containers/UserSettings/UserSettings.types';
import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types';
import { Alert } from 'models/alertgroup/alertgroup.types';
-import { SelectOption } from 'state/types';
import { useStore } from 'state/useStore';
import { openNotification } from 'utils';
import { IntegrationSettingsTab } from './IntegrationSettings.types';
import Autoresolve from './parts/Autoresolve';
-import LiveLogs from './parts/LiveLogs';
import styles from 'containers/IntegrationSettings/IntegrationSettings.module.css';
@@ -74,7 +61,7 @@ const IntegrationSettings = observer((props: IntegrationSettingsProps) => {
const integration = alertReceiveChannelStore.getIntegration(alertReceiveChannel);
- const [expanded, setExpanded] = useState(false);
+ const [expanded, _setExpanded] = useState(false);
const handleSwitchToTemplate = (templateName: string) => {
setSelectedTemplate(templateName);
@@ -85,34 +72,17 @@ const IntegrationSettings = observer((props: IntegrationSettingsProps) => {
scrollableContent
expandable
title={
- <>
- {/*
- {
- if (expanded) {
- setExpanded(false);
- } else {
- setExpanded(true);
- }
- }}
- />
-
-
*/}
-
- {integration &&
}
-
- {alertReceiveChannel && (
-
- settings
-
- )}
- {integration && Type: {integration.display_name} }
-
+
+ {integration &&
}
+
+ {alertReceiveChannel && (
+
+ settings
+
+ )}
+ {integration && Type: {integration.display_name} }
- >
+
}
width={expanded ? '100%' : '70%'}
onClose={onHide}
@@ -144,14 +114,6 @@ const IntegrationSettings = observer((props: IntegrationSettingsProps) => {
key={IntegrationSettingsTab.Autoresolve}
onChangeTab={getTabClickHandler(IntegrationSettingsTab.Autoresolve)}
/>
-
- {/* Removed untill backend is ready
-
*/}
{activeTab === IntegrationSettingsTab.Templates && (
@@ -176,7 +138,6 @@ const IntegrationSettings = observer((props: IntegrationSettingsProps) => {
alertGroupId={alertGroupId}
/>
)}
- {/*{activeTab === IntegrationSettingsTab.LiveLogs && }*/}
{activeTab === IntegrationSettingsTab.HowToConnect && (
diff --git a/grafana-plugin/src/containers/IntegrationSettings/parts/Autoresolve.tsx b/grafana-plugin/src/containers/IntegrationSettings/parts/Autoresolve.tsx
index 916789a6..3fdf07bf 100644
--- a/grafana-plugin/src/containers/IntegrationSettings/parts/Autoresolve.tsx
+++ b/grafana-plugin/src/containers/IntegrationSettings/parts/Autoresolve.tsx
@@ -6,7 +6,6 @@ import cn from 'classnames/bind';
import { get } from 'lodash-es';
import Block from 'components/GBlock/Block';
-import PluginLink from 'components/PluginLink/PluginLink';
import Text from 'components/Text/Text';
import GSelect from 'containers/GSelect/GSelect';
import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl';
@@ -55,8 +54,7 @@ const Autoresolve = ({ alertReceiveChannelId, onSwitchToTemplate, alertGroupId }
store.alertReceiveChannelStore.templates[alertReceiveChannelId],
'resolve_condition_template'
);
- // @ts-ignore
- if (autoresolveCondition == ['invalid template']) {
+ if (autoresolveCondition === 'invalid template') {
setAutoresolveConditionInvalid(true);
}
}, [store.alertReceiveChannelStore.templates[alertReceiveChannelId]]);
diff --git a/grafana-plugin/src/containers/IntegrationSettings/parts/LiveLogs.tsx b/grafana-plugin/src/containers/IntegrationSettings/parts/LiveLogs.tsx
index 9dc59f0f..259107ba 100644
--- a/grafana-plugin/src/containers/IntegrationSettings/parts/LiveLogs.tsx
+++ b/grafana-plugin/src/containers/IntegrationSettings/parts/LiveLogs.tsx
@@ -1,6 +1,6 @@
-import React, { ReactElement, useCallback, useEffect, useState } from 'react';
+import React, { useCallback, useEffect, useState } from 'react';
-import { Alert, Button, EmptySearchResult, LoadingPlaceholder } from '@grafana/ui';
+import { Button, EmptySearchResult, LoadingPlaceholder } from '@grafana/ui';
import SourceCode from 'components/SourceCode/SourceCode';
import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types';
diff --git a/grafana-plugin/src/containers/MaintenanceForm/MaintenanceForm.config.tsx b/grafana-plugin/src/containers/MaintenanceForm/MaintenanceForm.config.tsx
index 74d5c32f..bd2a6c39 100644
--- a/grafana-plugin/src/containers/MaintenanceForm/MaintenanceForm.config.tsx
+++ b/grafana-plugin/src/containers/MaintenanceForm/MaintenanceForm.config.tsx
@@ -1,4 +1,4 @@
-import React, { ReactElement } from 'react';
+import React from 'react';
import { SelectableValue } from '@grafana/data';
import Emoji from 'react-emoji-render';
diff --git a/grafana-plugin/src/containers/MaintenanceForm/MaintenanceForm.helpers.ts b/grafana-plugin/src/containers/MaintenanceForm/MaintenanceForm.helpers.ts
deleted file mode 100644
index cbb6ec0d..00000000
--- a/grafana-plugin/src/containers/MaintenanceForm/MaintenanceForm.helpers.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { Maintenance } from 'models/maintenance/maintenance.types';
-import { Schedule } from 'models/schedule/schedule.types';
-
-export function prepareForEdit(item: Maintenance) {
- return {};
-}
diff --git a/grafana-plugin/src/containers/MobileAppVerification/MobileAppVerification.tsx b/grafana-plugin/src/containers/MobileAppVerification/MobileAppVerification.tsx
index bf77cfc7..d629b90f 100644
--- a/grafana-plugin/src/containers/MobileAppVerification/MobileAppVerification.tsx
+++ b/grafana-plugin/src/containers/MobileAppVerification/MobileAppVerification.tsx
@@ -1,15 +1,12 @@
-import React, { HTMLAttributes, useCallback, useEffect, useRef, useState } from 'react';
+import React, { HTMLAttributes, useEffect, useState } from 'react';
-import { Button, HorizontalGroup, Icon, LoadingPlaceholder } from '@grafana/ui';
+import { Button, LoadingPlaceholder } from '@grafana/ui';
import cn from 'classnames/bind';
import { observer } from 'mobx-react';
-import GTable from 'components/GTable/GTable';
import Text from 'components/Text/Text';
-import { UserSettingsTab } from 'containers/UserSettings/UserSettings.types';
import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl';
import { User } from 'models/user/user.types';
-import { makeRequest } from 'network';
import { useStore } from 'state/useStore';
import { UserAction } from 'state/userAction';
@@ -33,8 +30,6 @@ const MobileAppVerification = observer((props: MobileAppVerificationProps) => {
const isCurrent = userStore.currentUserPk === user.pk;
const action = isCurrent ? UserAction.UpdateOwnSettings : UserAction.UpdateOtherUsersSettings;
- const { id = UserSettingsTab.UserInfo } = props;
-
const [showMobileAppVerificationToken, setShowMobileAppVerificationToken] = useState(undefined);
const [isMobileAppVerificationTokenExisting, setIsMobileAppVerificationTokenExisting] = useState(false);
const [MobileAppVerificationTokenLoading, setMobileAppVerificationTokenLoading] = useState(true);
@@ -42,11 +37,11 @@ const MobileAppVerification = observer((props: MobileAppVerificationProps) => {
useEffect(() => {
userStore
.getMobileAppVerificationToken(userPk)
- .then((res) => {
+ .then((_res) => {
setIsMobileAppVerificationTokenExisting(true);
setMobileAppVerificationTokenLoading(false);
})
- .catch((res) => {
+ .catch((_res) => {
setIsMobileAppVerificationTokenExisting(false);
setMobileAppVerificationTokenLoading(false);
});
@@ -59,27 +54,6 @@ const MobileAppVerification = observer((props: MobileAppVerificationProps) => {
.then((res) => setShowMobileAppVerificationToken(res?.token));
};
- // const [devices, setDevices] = useState();
- //
- // const updateDevices = useCallback(() => {
- // makeRequest(`/device/apns/`, {
- // method: 'GET',
- // }).then((data) => {
- // setDevices(data);
- // });
- // }, []);
- //
- // useEffect(() => {
- // updateDevices();
- // }, []);
- //
- // const columns = [
- // {
- // title: 'Name',
- // dataIndex: 'name',
- // },
- // ];
-
return (
{MobileAppVerificationTokenLoading ? (
@@ -114,41 +88,23 @@ const MobileAppVerification = observer((props: MobileAppVerificationProps) => {
)}
>
) : (
- <>
-
-
-
- Get the code
-
-
-
- >
+
+
+
+ Get the code
+
+
+
)}
* Only iOS is currently supported
>
)}
- {/*<>*/}
- {/*
(*/}
- {/* */}
- {/* */}
- {/* Your devices */}
- {/* */}
- {/*
*/}
- {/* )}*/}
- {/* rowKey="id"*/}
- {/* className="api-keys"*/}
- {/* data={devices}*/}
- {/* emptyText={devices ? 'No devices connected' : 'Loading...'}*/}
- {/* columns={columns}*/}
- {/* />*/}
- {/*>*/}
);
});
diff --git a/grafana-plugin/src/containers/OrganizationLogFilters/OrganizationLogFilters.tsx b/grafana-plugin/src/containers/OrganizationLogFilters/OrganizationLogFilters.tsx
index 8c188a80..2e0831a8 100644
--- a/grafana-plugin/src/containers/OrganizationLogFilters/OrganizationLogFilters.tsx
+++ b/grafana-plugin/src/containers/OrganizationLogFilters/OrganizationLogFilters.tsx
@@ -1,12 +1,11 @@
import React, { ChangeEvent, useCallback, useMemo, useState } from 'react';
import { RawTimeRange } from '@grafana/data';
-import { Button, HorizontalGroup, Input, TimeRangeInput } from '@grafana/ui';
+import { HorizontalGroup, Input, TimeRangeInput } from '@grafana/ui';
import cn from 'classnames/bind';
import { observer } from 'mobx-react';
import RemoteSelect from 'containers/RemoteSelect/RemoteSelect';
-import { useStore } from 'state/useStore';
import styles from './OrganizationLogFilters.module.css';
@@ -23,8 +22,6 @@ const OrganizationLogFilters = observer((props: OrganizationLogFiltersProps) =>
const [createAtRaw, setCreateAtRaw] = useState();
- const store = useStore();
-
const onSearchTermChangeCallback = useCallback(
(e: ChangeEvent) => {
const filters = {
@@ -46,10 +43,6 @@ const OrganizationLogFilters = observer((props: OrganizationLogFiltersProps) =>
};
};
- const handleClear = useCallback(() => {
- onChange({});
- }, [onChange]);
-
const handleChangeCreatedAt = useCallback(
(filter) => {
onChange({
diff --git a/grafana-plugin/src/containers/OutgoingWebhookForm/OutgoingWebhookForm.config.ts b/grafana-plugin/src/containers/OutgoingWebhookForm/OutgoingWebhookForm.config.ts
index 836f1bcf..682c2b01 100644
--- a/grafana-plugin/src/containers/OutgoingWebhookForm/OutgoingWebhookForm.config.ts
+++ b/grafana-plugin/src/containers/OutgoingWebhookForm/OutgoingWebhookForm.config.ts
@@ -1,7 +1,4 @@
-import { ReactElement } from 'react';
-
import { FormItem, FormItemType } from 'components/GForm/GForm.types';
-import { DEFAULT_USER_ROLES } from 'models/user/user.config';
export const form: { name: string; fields: FormItem[] } = {
name: 'OutgoingWebhook',
diff --git a/grafana-plugin/src/containers/OutgoingWebhookForm/OutgoingWebhookForm.tsx b/grafana-plugin/src/containers/OutgoingWebhookForm/OutgoingWebhookForm.tsx
index 76891c47..47317d42 100644
--- a/grafana-plugin/src/containers/OutgoingWebhookForm/OutgoingWebhookForm.tsx
+++ b/grafana-plugin/src/containers/OutgoingWebhookForm/OutgoingWebhookForm.tsx
@@ -54,7 +54,7 @@ const OutgoingWebhookForm = observer((props: OutgoingWebhookFormProps) => {
onClose={onHide}
closeOnMaskClick
>
-
+
diff --git a/grafana-plugin/src/containers/PluginConfigPage/PluginConfigPage.tsx b/grafana-plugin/src/containers/PluginConfigPage/PluginConfigPage.tsx
index 3f30d628..ea9c77e1 100644
--- a/grafana-plugin/src/containers/PluginConfigPage/PluginConfigPage.tsx
+++ b/grafana-plugin/src/containers/PluginConfigPage/PluginConfigPage.tsx
@@ -2,16 +2,8 @@ import React, { useCallback, useEffect, useState } from 'react';
import { AppPluginMeta, PluginConfigPageProps } from '@grafana/data';
import { getBackendSrv } from '@grafana/runtime';
-import {
- Button,
- Field,
- HorizontalGroup,
- VerticalGroup,
- Input,
- Label,
- Legend,
- LoadingPlaceholder,
-} from '@grafana/ui';
+import { Button, Field, HorizontalGroup, VerticalGroup, Input, Label, Legend, LoadingPlaceholder } from '@grafana/ui';
+import { AxiosError } from 'axios';
import cn from 'classnames/bind';
import { OnCallAppSettings } from 'types';
@@ -23,9 +15,10 @@ import { makeRequest } from 'network';
import {
createGrafanaToken,
getPluginSyncStatus,
- startPluginSync, SYNC_STATUS_RETRY_LIMIT,
+ startPluginSync,
+ SYNC_STATUS_RETRY_LIMIT,
syncStatusDelay,
- updateGrafanaToken
+ updateGrafanaToken,
} from 'state/plugin';
import { GRAFANA_LICENSE_OSS } from 'utils/consts';
import { getItem, setItem } from 'utils/localStorage';
@@ -49,7 +42,9 @@ export const PluginConfigPage = (props: Props) => {
const [isSelfHostedInstall, setIsSelfHostedInstall] = useState(true);
const [retrySync, setRetrySync] = useState(false);
- const INVALID_INVITE_TOKEN_ERROR_MSG = `It seems like your invite token may be invalid. ${constructErrorActionMessage('generating a new invite token')}`;
+ const INVALID_INVITE_TOKEN_ERROR_MSG = `It seems like your invite token may be invalid. ${constructErrorActionMessage(
+ 'generating a new invite token'
+ )}`;
const setupPlugin = useCallback(async () => {
setItem('onCallApiUrl', onCallApiUrl);
@@ -134,23 +129,30 @@ export const PluginConfigPage = (props: Props) => {
setGrafanaUrl(e.target.value);
}, []);
- const handleSyncException = useCallback((e) => {
- const buildErrMsg = (msg: string): string =>
- constructSyncErrorMessage(msg, plugin.meta.jsonData?.onCallApiUrl);
+ const handleSyncException = useCallback((e: AxiosError) => {
+ const buildErrMsg = (msg: string): string => constructSyncErrorMessage(msg, plugin.meta.jsonData?.onCallApiUrl);
if (plugin.meta.jsonData?.onCallApiUrl) {
- const { status: statusCode } = e.response;
+ const { status: statusCode } = e.response;
let statusMessage: string;
- if (statusCode == 403) {
+ if (statusCode === 403) {
statusMessage = buildErrMsg(INVALID_INVITE_TOKEN_ERROR_MSG);
} else if (statusCode === 404) {
- statusMessage = buildErrMsg('If Grafana OnCall was just installed, restart Grafana for OnCall routes to be available.');
+ statusMessage = buildErrMsg(
+ 'If Grafana OnCall was just installed, restart Grafana for OnCall routes to be available.'
+ );
} else if (statusCode === 502) {
- statusMessage = buildErrMsg(`Unable to communicate with either the Grafana API, or Grafana OnCall engine API. ${constructErrorActionMessage('verify that the API URLs that you entered are correct')}`);
+ statusMessage = buildErrMsg(
+ `Unable to communicate with either the Grafana API, or Grafana OnCall engine API. ${constructErrorActionMessage(
+ 'verify that the API URLs that you entered are correct'
+ )}`
+ );
} else {
- statusMessage = buildErrMsg(`An unknown error occured. ${constructErrorActionMessage()}. If the error still occurs please reach out to support.`)
+ statusMessage = buildErrMsg(
+ `An unknown error occured. ${constructErrorActionMessage()}. If the error still occurs please reach out to support.`
+ );
}
setPluginStatusMessage(statusMessage);
setRetrySync(true);
@@ -168,17 +170,18 @@ export const PluginConfigPage = (props: Props) => {
? ` (${getSyncResponse.license}, ${getSyncResponse.version})`
: '';
- let pluginStatusMessage = `Connected to OnCall${versionInfo}\n - OnCall URL: ${plugin.meta.jsonData.onCallApiUrl}\n`
+ let pluginStatusMessage = `Connected to OnCall${versionInfo}\n - OnCall URL: ${plugin.meta.jsonData.onCallApiUrl}\n`;
if (plugin.meta.jsonData.grafanaUrl) {
- pluginStatusMessage = `${pluginStatusMessage} - Grafana URL: ${plugin.meta.jsonData.grafanaUrl}`
+ pluginStatusMessage = `${pluginStatusMessage} - Grafana URL: ${plugin.meta.jsonData.grafanaUrl}`;
}
- setPluginStatusMessage(pluginStatusMessage)
+ setPluginStatusMessage(pluginStatusMessage);
setIsSelfHostedInstall(plugin.meta.jsonData?.license === GRAFANA_LICENSE_OSS);
setPluginStatusOk(true);
} else {
- setPluginStatusMessage(constructSyncErrorMessage(INVALID_INVITE_TOKEN_ERROR_MSG,
- plugin.meta.jsonData.grafanaUrl));
+ setPluginStatusMessage(
+ constructSyncErrorMessage(INVALID_INVITE_TOKEN_ERROR_MSG, plugin.meta.jsonData.grafanaUrl)
+ );
setRetrySync(true);
}
setPluginConfigLoading(false);
@@ -195,16 +198,16 @@ export const PluginConfigPage = (props: Props) => {
return;
}
- getPluginSyncStatus().then((get_sync_response) => {
- if (get_sync_response.hasOwnProperty('token_ok')) {
- finishSync(get_sync_response);
- } else {
- syncStatusDelay(retryCount + 1).then(() => waitForSyncStatus(retryCount + 1))
- }
- }).catch((e) => {
- handleSyncException(e);
- });
- }
+ getPluginSyncStatus()
+ .then((get_sync_response) => {
+ if (get_sync_response.hasOwnProperty('token_ok')) {
+ finishSync(get_sync_response);
+ } else {
+ syncStatusDelay(retryCount + 1).then(() => waitForSyncStatus(retryCount + 1));
+ }
+ })
+ .catch(handleSyncException);
+ };
const startSync = useCallback(() => {
setRetrySync(false);
@@ -214,9 +217,7 @@ export const PluginConfigPage = (props: Props) => {
.catch(handleSyncException);
}, []);
- useEffect(() => {
- startSync();
- }, []);
+ useEffect(startSync, []);
return (
diff --git a/grafana-plugin/src/containers/PluginConfigPage/helpers.tsx b/grafana-plugin/src/containers/PluginConfigPage/helpers.tsx
index c91a391c..e6d4da0c 100644
--- a/grafana-plugin/src/containers/PluginConfigPage/helpers.tsx
+++ b/grafana-plugin/src/containers/PluginConfigPage/helpers.tsx
@@ -1,5 +1,6 @@
-export const constructSyncErrorMessage = (errMsg: string, url?: string): string =>
- `${url ? `${url}\n` : ''}${errMsg}`;
+export const constructSyncErrorMessage = (errMsg: string, url?: string): string => `${url ? `${url}\n` : ''}${errMsg}`;
export const constructErrorActionMessage = (msg?: string): string =>
- `Try removing your current configuration, ${msg ? msg : 'double checking your settings'}, and re-initializing the plugin.\nBy removing your current configuration, you will need to ensure that you regenerate a new invite token, and input this in your new configuration.`
+ `Try removing your current configuration, ${
+ msg ? msg : 'double checking your settings'
+ }, and re-initializing the plugin.\nBy removing your current configuration, you will need to ensure that you regenerate a new invite token, and input this in your new configuration.`;
diff --git a/grafana-plugin/src/containers/RemoteSelect/RemoteSelect.module.css b/grafana-plugin/src/containers/RemoteSelect/RemoteSelect.module.css
deleted file mode 100644
index 63d08ecc..00000000
--- a/grafana-plugin/src/containers/RemoteSelect/RemoteSelect.module.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.root {
- display: block;
-}
diff --git a/grafana-plugin/src/containers/RemoteSelect/RemoteSelect.tsx b/grafana-plugin/src/containers/RemoteSelect/RemoteSelect.tsx
index 4f281542..753b3326 100644
--- a/grafana-plugin/src/containers/RemoteSelect/RemoteSelect.tsx
+++ b/grafana-plugin/src/containers/RemoteSelect/RemoteSelect.tsx
@@ -2,15 +2,10 @@ import React, { useCallback, useEffect, useMemo, useReducer } from 'react';
import { SelectableValue } from '@grafana/data';
import { AsyncMultiSelect, AsyncSelect } from '@grafana/ui';
-import cn from 'classnames/bind';
import { inject, observer } from 'mobx-react';
import { makeRequest } from 'network';
-import styles from './RemoteSelect.module.css';
-
-const cx = cn.bind(styles);
-
interface RemoteSelectProps {
autoFocus?: boolean;
href: string;
diff --git a/grafana-plugin/src/containers/Rotation/Rotation.tsx b/grafana-plugin/src/containers/Rotation/Rotation.tsx
index 0add0728..0cb126e3 100644
--- a/grafana-plugin/src/containers/Rotation/Rotation.tsx
+++ b/grafana-plugin/src/containers/Rotation/Rotation.tsx
@@ -1,14 +1,12 @@
-import React, { FC, useMemo, useState, useEffect, useRef, useCallback } from 'react';
+import React, { FC, useMemo, useState } from 'react';
import { HorizontalGroup, LoadingPlaceholder } from '@grafana/ui';
import cn from 'classnames/bind';
import dayjs from 'dayjs';
import ScheduleSlot from 'containers/ScheduleSlot/ScheduleSlot';
-import { getFromString } from 'models/schedule/schedule.helpers';
-import { Rotation as RotationType, Schedule, Event } from 'models/schedule/schedule.types';
+import { Schedule, Event } from 'models/schedule/schedule.types';
import { Timezone } from 'models/timezone/timezone.types';
-import { usePrevious } from 'utils/hooks';
import { getLabel } from './Rotation.helpers';
@@ -16,8 +14,6 @@ import styles from './Rotation.module.css';
const cx = cn.bind(styles);
-interface ScheduleSlotState {}
-
interface RotationProps {
scheduleId: Schedule['id'];
startMoment: dayjs.Dayjs;
@@ -45,38 +41,7 @@ const Rotation: FC
= (props) => {
transparent = false,
} = props;
- const [animate, setAnimate] = useState(true);
- const [width, setWidth] = useState();
-
- const startMomentString = useMemo(() => getFromString(startMoment), [startMoment]);
-
- const prevStartMomentString = usePrevious(startMomentString);
-
- // console.log(events);
-
- // const rotation = store.scheduleStore.rotations[id]?.[prevStartMomentString];
-
- /* useEffect(() => {
- setTransparent(false);
- }, [rotation]);
-
- useEffect(() => {
- setTransparent(true);
- }, [startMoment]);*/
-
- useEffect(() => {
- const startMomentString = startMoment.utc().format('YYYY-MM-DDTHH:mm:ss.000Z');
-
- // console.log('CHANGE START MOMENT', startMomentString);
-
- // store.scheduleStore.updateEvents(scheduleId, startMomentString, currentTimezone);
- }, [startMomentString]);
-
- const slots = useCallback((node) => {
- if (node) {
- setWidth(node.offsetWidth);
- }
- }, []);
+ const [animate, _setAnimate] = useState(true);
const handleClick = (event) => {
const rect = event.currentTarget.getBoundingClientRect();
@@ -94,11 +59,8 @@ const Rotation: FC = (props) => {
}
const firstShift = events[0];
-
const firstShiftOffset = dayjs(firstShift.start).diff(startMoment, 'seconds');
-
const base = 60 * 60 * 24 * days;
- // const utcOffset = dayjs().tz(currentTimezone).utcOffset();
return firstShiftOffset / base;
}, [events]);
diff --git a/grafana-plugin/src/containers/RotationForm/DateTimePicker.tsx b/grafana-plugin/src/containers/RotationForm/DateTimePicker.tsx
index c8174b94..bc265215 100644
--- a/grafana-plugin/src/containers/RotationForm/DateTimePicker.tsx
+++ b/grafana-plugin/src/containers/RotationForm/DateTimePicker.tsx
@@ -1,20 +1,10 @@
import React, { useCallback, useMemo } from 'react';
import { DateTime, dateTime } from '@grafana/data';
-import { DatePickerWithInput, HorizontalGroup, TimeOfDayPicker, Tooltip } from '@grafana/ui';
-import cn from 'classnames/bind';
+import { DatePickerWithInput, HorizontalGroup, TimeOfDayPicker } from '@grafana/ui';
import dayjs from 'dayjs';
-import { observer } from 'mobx-react';
-import { Moment } from 'moment-timezone';
import { Timezone } from 'models/timezone/timezone.types';
-import { getUserNotificationsSummary } from 'models/user/user.helpers';
-import { User } from 'models/user/user.types';
-import { useStore } from 'state/useStore';
-
-import styles from 'containers/UserTooltip/UserTooltip.module.css';
-
-const cx = cn.bind(styles);
interface UserTooltipProps {
value: dayjs.Dayjs;
diff --git a/grafana-plugin/src/containers/RotationForm/RotationForm.tsx b/grafana-plugin/src/containers/RotationForm/RotationForm.tsx
index c370c2b8..1242abca 100644
--- a/grafana-plugin/src/containers/RotationForm/RotationForm.tsx
+++ b/grafana-plugin/src/containers/RotationForm/RotationForm.tsx
@@ -1,18 +1,6 @@
import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
-import { dateTime, DateTime } from '@grafana/data';
-import {
- IconButton,
- VerticalGroup,
- HorizontalGroup,
- Field,
- Input,
- Button,
- Select,
- InlineSwitch,
- DatePickerWithInput,
- TimeOfDayPicker,
-} from '@grafana/ui';
+import { IconButton, VerticalGroup, HorizontalGroup, Field, Button, Select, InlineSwitch } from '@grafana/ui';
import cn from 'classnames/bind';
import dayjs from 'dayjs';
import { observer } from 'mobx-react';
@@ -21,16 +9,14 @@ import Draggable from 'react-draggable';
import Modal from 'components/Modal/Modal';
import Text from 'components/Text/Text';
import UserGroups from 'components/UserGroups/UserGroups';
-import { Item } from 'components/UserGroups/UserGroups.types';
import WithConfirm from 'components/WithConfirm/WithConfirm';
import WorkingHours from 'components/WorkingHours/WorkingHours';
import RemoteSelect from 'containers/RemoteSelect/RemoteSelect';
import { getFromString } from 'models/schedule/schedule.helpers';
-import { Rotation, Schedule, Shift } from 'models/schedule/schedule.types';
+import { Schedule, Shift } from 'models/schedule/schedule.types';
import { getTzOffsetString } from 'models/timezone/timezone.helpers';
import { Timezone } from 'models/timezone/timezone.types';
import { User } from 'models/user/user.types';
-import { makeRequest } from 'network';
import { getDateTime, getUTCString } from 'pages/schedule/Schedule.helpers';
import { SelectOption } from 'state/types';
import { useStore } from 'state/useStore';
@@ -38,7 +24,6 @@ import { getCoords, waitForElement } from 'utils/DOM';
import { useDebouncedCallback } from 'utils/hooks';
import DateTimePicker from './DateTimePicker';
-import { RotationCreateData } from './RotationForm.types';
import styles from './RotationForm.module.css';
@@ -77,10 +62,8 @@ const RotationForm: FC = observer((props) => {
shiftColor = '#3D71D9',
} = props;
- // console.log('shiftColor', shiftColor);
-
const [isOpen, setIsOpen] = useState(false);
-
+ const [offsetTop, setOffsetTop] = useState(0);
const [repeatEveryValue, setRepeatEveryValue] = useState(1);
const [repeatEveryPeriod, setRepeatEveryPeriod] = useState(0);
const [selectedDays, setSelectedDays] = useState([]);
@@ -90,6 +73,9 @@ const RotationForm: FC = observer((props) => {
const [endLess, setEndless] = useState(true);
const [rotationEnd, setRotationEnd] = useState(shiftMoment.add(1, 'month'));
+ const store = useStore();
+ const shift = store.scheduleStore.shifts[shiftId];
+
useEffect(() => {
if (rotationStart.isBefore(shiftStart)) {
setRotationStart(shiftStart);
@@ -106,22 +92,12 @@ const RotationForm: FC = observer((props) => {
[shiftStart, shiftEnd]
);
- const store = useStore();
-
- const shift = store.scheduleStore.shifts[shiftId];
-
- const [offsetTop, setOffsetTop] = useState(0);
-
useEffect(() => {
if (isOpen) {
waitForElement(`#layer${shiftId === 'new' ? layerPriority : shift?.priority_level}`).then((elm) => {
const modal = document.querySelector(`.${cx('draggable')}`) as HTMLDivElement;
-
const coords = getCoords(elm);
- // elm.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'nearest' });
- // setOffsetTop(Math.max(coords.top + elm.offsetHeight, 0));
-
const offsetTop = Math.min(
Math.max(coords.top - modal?.offsetHeight - 10, 10),
document.body.offsetHeight - modal?.offsetHeight - 10
@@ -277,8 +253,6 @@ const RotationForm: FC = observer((props) => {
- {/*
- */}
{shiftId !== 'new' && (
@@ -287,7 +261,6 @@ const RotationForm: FC = observer((props) => {
- {/* */}
@@ -348,7 +321,6 @@ const RotationForm: FC
= observer((props) => {
{repeatEveryPeriod === 1 && (
- /**/
= observer((props) => {
onChange={(value) => setSelectedDays(value)}
/>
- /* */
)}
{
{options.map(({ display_name, value: itemValue }) => (
diff --git a/grafana-plugin/src/containers/RotationForm/ScheduleOverrideForm.tsx b/grafana-plugin/src/containers/RotationForm/ScheduleOverrideForm.tsx
index f0423b5b..7e235df0 100644
--- a/grafana-plugin/src/containers/RotationForm/ScheduleOverrideForm.tsx
+++ b/grafana-plugin/src/containers/RotationForm/ScheduleOverrideForm.tsx
@@ -1,7 +1,6 @@
import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
-import { dateTime, DateTime } from '@grafana/data';
-import { IconButton, VerticalGroup, HorizontalGroup, Field, Input, Button, Select, InlineSwitch } from '@grafana/ui';
+import { IconButton, VerticalGroup, HorizontalGroup, Field, Button } from '@grafana/ui';
import cn from 'classnames/bind';
import dayjs from 'dayjs';
import Draggable from 'react-draggable';
@@ -12,7 +11,7 @@ import UserGroups from 'components/UserGroups/UserGroups';
import WithConfirm from 'components/WithConfirm/WithConfirm';
import WorkingHours from 'components/WorkingHours/WorkingHours';
import { getFromString } from 'models/schedule/schedule.helpers';
-import { Rotation, Schedule, Shift } from 'models/schedule/schedule.types';
+import { Schedule, Shift } from 'models/schedule/schedule.types';
import { getTzOffsetString } from 'models/timezone/timezone.helpers';
import { Timezone } from 'models/timezone/timezone.types';
import { User } from 'models/user/user.types';
@@ -22,7 +21,6 @@ import { getCoords, waitForElement } from 'utils/DOM';
import { useDebouncedCallback } from 'utils/hooks';
import DateTimePicker from './DateTimePicker';
-import { RotationCreateData } from './RotationForm.types';
import styles from './RotationForm.module.css';
@@ -189,8 +187,6 @@ const ScheduleOverrideForm: FC
= (props) => {
{shiftId === 'new' ? 'New Override' : 'Update Override'}
- {/*
- */}
{shiftId !== 'new' && (
diff --git a/grafana-plugin/src/containers/Rotations/Rotations.helpers.ts b/grafana-plugin/src/containers/Rotations/Rotations.helpers.ts
index 91225e8b..f4c255e0 100644
--- a/grafana-plugin/src/containers/Rotations/Rotations.helpers.ts
+++ b/grafana-plugin/src/containers/Rotations/Rotations.helpers.ts
@@ -7,8 +7,8 @@ export const findColor = (shiftId: Shift['id'], layers: Layer[], overrides?) =>
let layerIndex = -1;
let rotationIndex = -1;
if (layers) {
- outer: for (var i = 0; i < layers.length; i++) {
- for (var j = 0; j < layers[i].shifts.length; j++) {
+ outer: for (let i = 0; i < layers.length; i++) {
+ for (let j = 0; j < layers[i].shifts.length; j++) {
const shift = layers[i].shifts[j];
if (shift.shiftId === shiftId || (shiftId === 'new' && shift.isPreview)) {
layerIndex = i;
@@ -21,7 +21,7 @@ export const findColor = (shiftId: Shift['id'], layers: Layer[], overrides?) =>
let overrideIndex = -1;
if (layerIndex === -1 && rotationIndex === -1 && overrides) {
- for (var k = 0; k < overrides.length; k++) {
+ for (let k = 0; k < overrides.length; k++) {
const shift = overrides[k];
if (shift.shiftId === shiftId || (shiftId === 'new' && shift.isPreview)) {
overrideIndex = k;
diff --git a/grafana-plugin/src/containers/Rotations/Rotations.tsx b/grafana-plugin/src/containers/Rotations/Rotations.tsx
index 5b16fa84..7e52a5bc 100644
--- a/grafana-plugin/src/containers/Rotations/Rotations.tsx
+++ b/grafana-plugin/src/containers/Rotations/Rotations.tsx
@@ -1,11 +1,9 @@
-import React, { Component, useMemo, useState } from 'react';
+import React, { Component } from 'react';
import { SelectableValue } from '@grafana/data';
-import { ValuePicker, IconButton, Icon, HorizontalGroup, Button, LoadingPlaceholder } from '@grafana/ui';
+import { ValuePicker, HorizontalGroup, Button } from '@grafana/ui';
import cn from 'classnames/bind';
import dayjs from 'dayjs';
-import utc from 'dayjs/plugin/utc';
-import { toJS } from 'mobx';
import { observer } from 'mobx-react';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
@@ -13,11 +11,10 @@ import Text from 'components/Text/Text';
import TimelineMarks from 'components/TimelineMarks/TimelineMarks';
import Rotation from 'containers/Rotation/Rotation';
import RotationForm from 'containers/RotationForm/RotationForm';
-import { RotationCreateData } from 'containers/RotationForm/RotationForm.types';
import { getColor, getFromString } from 'models/schedule/schedule.helpers';
-import { Event, Layer, Schedule, Shift } from 'models/schedule/schedule.types';
+import { Layer, Schedule, Shift } from 'models/schedule/schedule.types';
import { Timezone } from 'models/timezone/timezone.types';
-import { SelectOption, WithStoreProps } from 'state/types';
+import { WithStoreProps } from 'state/types';
import { withMobXProviderContext } from 'state/withStore';
import { DEFAULT_TRANSITION_TIMEOUT } from './Rotations.config';
@@ -122,7 +119,6 @@ class Rotations extends Component {
Layer {layer.priority}
- {/* */}
diff --git a/grafana-plugin/src/containers/Rotations/ScheduleFinal.tsx b/grafana-plugin/src/containers/Rotations/ScheduleFinal.tsx
index 99339140..7fa585d8 100644
--- a/grafana-plugin/src/containers/Rotations/ScheduleFinal.tsx
+++ b/grafana-plugin/src/containers/Rotations/ScheduleFinal.tsx
@@ -1,6 +1,6 @@
-import React, { Component, useEffect } from 'react';
+import React, { Component } from 'react';
-import { Button, HorizontalGroup, Icon, Input, ValuePicker } from '@grafana/ui';
+import { HorizontalGroup } from '@grafana/ui';
import cn from 'classnames/bind';
import dayjs from 'dayjs';
import { observer } from 'mobx-react';
@@ -9,8 +9,8 @@ import { CSSTransition, TransitionGroup } from 'react-transition-group';
import Text from 'components/Text/Text';
import TimelineMarks from 'components/TimelineMarks/TimelineMarks';
import Rotation from 'containers/Rotation/Rotation';
-import { getColor, getFromString, getLayersFromStore, getOverrideColor, getOverridesFromStore, getShiftsFromStore } from 'models/schedule/schedule.helpers';
-import { Event, Layer, Schedule, Shift } from 'models/schedule/schedule.types';
+import { getLayersFromStore, getOverridesFromStore, getShiftsFromStore } from 'models/schedule/schedule.helpers';
+import { Schedule, Shift } from 'models/schedule/schedule.types';
import { Timezone } from 'models/timezone/timezone.types';
import { WithStoreProps } from 'state/types';
import { withMobXProviderContext } from 'state/withStore';
@@ -51,7 +51,7 @@ class ScheduleFinal extends Component 1;
@@ -67,12 +67,6 @@ class ScheduleFinal extends Component
- {/* }
- placeholder="Search..."
- value={searchTerm}
- onChange={this.onSearchTermChangeCallback}
- />*/}
)}
diff --git a/grafana-plugin/src/containers/Rotations/ScheduleOverrides.tsx b/grafana-plugin/src/containers/Rotations/ScheduleOverrides.tsx
index e9e4048e..a0eff285 100644
--- a/grafana-plugin/src/containers/Rotations/ScheduleOverrides.tsx
+++ b/grafana-plugin/src/containers/Rotations/ScheduleOverrides.tsx
@@ -1,6 +1,6 @@
import React, { Component } from 'react';
-import { Button, HorizontalGroup, Icon, ValuePicker } from '@grafana/ui';
+import { Button, HorizontalGroup } from '@grafana/ui';
import cn from 'classnames/bind';
import dayjs from 'dayjs';
import { observer } from 'mobx-react';
@@ -9,15 +9,9 @@ import { CSSTransition, TransitionGroup } from 'react-transition-group';
import Text from 'components/Text/Text';
import TimelineMarks from 'components/TimelineMarks/TimelineMarks';
import Rotation from 'containers/Rotation/Rotation';
-import { RotationCreateData } from 'containers/RotationForm/RotationForm.types';
import ScheduleOverrideForm from 'containers/RotationForm/ScheduleOverrideForm';
-import {
- getFromString,
- getOverrideColor,
- getOverridesFromStore,
- getShiftsFromStore,
-} from 'models/schedule/schedule.helpers';
-import { Event, Schedule, Shift, ShiftEvents } from 'models/schedule/schedule.types';
+import { getOverrideColor, getOverridesFromStore } from 'models/schedule/schedule.helpers';
+import { Schedule, Shift, ShiftEvents } from 'models/schedule/schedule.types';
import { Timezone } from 'models/timezone/timezone.types';
import { WithStoreProps } from 'state/types';
import { withMobXProviderContext } from 'state/withStore';
@@ -125,9 +119,6 @@ class ScheduleOverrides extends Component
- {/*
- + Add override
-
*/}
{shiftIdToShowRotationForm && (
Boolean(value),
- // label: 'Send reports about empty shifts to Slack',
- // type: FormItemType.Switch,
- // },
];
export const iCalForm: { name: string; fields: FormItem[] } = {
diff --git a/grafana-plugin/src/containers/ScheduleForm/ScheduleForm.tsx b/grafana-plugin/src/containers/ScheduleForm/ScheduleForm.tsx
index fe84dfeb..2fb0f480 100644
--- a/grafana-plugin/src/containers/ScheduleForm/ScheduleForm.tsx
+++ b/grafana-plugin/src/containers/ScheduleForm/ScheduleForm.tsx
@@ -1,11 +1,9 @@
import React, { useCallback, useMemo } from 'react';
-import { SelectableValue } from '@grafana/data';
-import { Button, Drawer, HorizontalGroup, VerticalGroup } from '@grafana/ui';
+import { Button, Drawer, VerticalGroup } from '@grafana/ui';
import cn from 'classnames/bind';
import { observer } from 'mobx-react';
-import Avatar from 'components/Avatar/Avatar';
import GForm from 'components/GForm/GForm';
import Text from 'components/Text/Text';
import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl';
@@ -78,10 +76,6 @@ const ScheduleForm = observer((props: ScheduleFormProps) => {
>
- {/*
- Manage on-call schedules using your favourite calendar app, such as Google Calendar or Microsoft Outlook. To
- schedule on-call shifts create a new calendar and use events with the teammates usernames
- */}
diff --git a/grafana-plugin/src/containers/ScheduleIcalLink/ScheduleIcalLink.tsx b/grafana-plugin/src/containers/ScheduleIcalLink/ScheduleIcalLink.tsx
index 83dca931..de52736d 100644
--- a/grafana-plugin/src/containers/ScheduleIcalLink/ScheduleIcalLink.tsx
+++ b/grafana-plugin/src/containers/ScheduleIcalLink/ScheduleIcalLink.tsx
@@ -57,7 +57,7 @@ const ScheduleICalSettings: FC = observer((props) =>
iCal link:
Secret iCal export link to export schedule's on call shifts to Google Calendar, iCal, etc. If you forget it,
- you’ll need to revoke this link and create another one
+ you'll need to revoke this link and create another one
{isICalLinkLoading ? (
diff --git a/grafana-plugin/src/containers/ScheduleSlot/ScheduleSlot.helpers.ts b/grafana-plugin/src/containers/ScheduleSlot/ScheduleSlot.helpers.ts
index f66d5306..f1fcf687 100644
--- a/grafana-plugin/src/containers/ScheduleSlot/ScheduleSlot.helpers.ts
+++ b/grafana-plugin/src/containers/ScheduleSlot/ScheduleSlot.helpers.ts
@@ -1,25 +1,5 @@
-import dayjs from 'dayjs';
-
-import { Shift } from 'models/schedule/schedule.types';
import { User } from 'models/user/user.types';
-const USERS = [
- 'Innokentii Konstantinov',
- 'Ildar Iskhakov',
- 'Matias Bordese',
- 'Michael Derynck',
- 'Vadim Stepanov',
- 'Matvey Kukuy',
- 'Yulya Artyukhina',
- 'Raphael Batyrbaev',
-];
-
-export const getRandomUser = () => {
- return USERS[Math.floor(Math.random() * USERS.length)];
-};
-
export const getTitle = (user: User) => {
return user ? user.username.split(' ')[0] : null;
};
-
-export const getOuRanges = (shift: Shift, user: User) => {};
diff --git a/grafana-plugin/src/containers/ScheduleSlot/ScheduleSlot.tsx b/grafana-plugin/src/containers/ScheduleSlot/ScheduleSlot.tsx
index 374b0e3c..b56f65b7 100644
--- a/grafana-plugin/src/containers/ScheduleSlot/ScheduleSlot.tsx
+++ b/grafana-plugin/src/containers/ScheduleSlot/ScheduleSlot.tsx
@@ -1,6 +1,6 @@
import React, { FC, useCallback, useState } from 'react';
-import { HorizontalGroup, Icon, Tooltip, VerticalGroup } from '@grafana/ui';
+import { HorizontalGroup, Tooltip, VerticalGroup } from '@grafana/ui';
import cn from 'classnames/bind';
import dayjs from 'dayjs';
import { observer } from 'mobx-react';
@@ -30,7 +30,7 @@ interface ScheduleSlotProps {
const cx = cn.bind(styles);
const ScheduleSlot: FC = observer((props) => {
- const { event, scheduleId, startMoment, currentTimezone, color, label } = props;
+ const { event, scheduleId, currentTimezone, color, label } = props;
const { users } = event;
const trackMouse = false;
@@ -55,7 +55,7 @@ const ScheduleSlot: FC = observer((props) => {
const onCallNow = store.scheduleStore.items[scheduleId]?.on_call_now;
return (
-
+
{event.is_gap ? (
}>
@@ -95,6 +95,7 @@ const ScheduleSlot: FC
= observer((props) => {
return (
{
- {/*
-
- 30 apr, 7:54
- */}
@@ -176,7 +173,6 @@ const ScheduleSlotDetails = (props: ScheduleSlotDetailsProps) => {
{currentTimezone}
- {/* 30 apr, 12:54 */}
{dayjs(event.start).tz(currentTimezone).format('DD MMM, HH:mm')}
{dayjs(event.end).tz(currentTimezone).format('DD MMM, HH:mm')}
@@ -204,15 +200,6 @@ const ScheduleGapDetails = (props: ScheduleGapDetailsProps) => {
{dayjs(event.end).tz(currentTimezone).format('DD MMM, HH:mm')}
- {/*Gaps this week
-
- Number of gaps
- 12
-
-
- Time
- 23h 12m
- */}
);
diff --git a/grafana-plugin/src/containers/SchedulesFilters/SchedulesFilters.module.css b/grafana-plugin/src/containers/SchedulesFilters/SchedulesFilters.module.css
deleted file mode 100644
index bedeb67b..00000000
--- a/grafana-plugin/src/containers/SchedulesFilters/SchedulesFilters.module.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.root {
-
-}
diff --git a/grafana-plugin/src/containers/SchedulesFilters/SchedulesFilters.tsx b/grafana-plugin/src/containers/SchedulesFilters/SchedulesFilters.tsx
deleted file mode 100644
index d6358951..00000000
--- a/grafana-plugin/src/containers/SchedulesFilters/SchedulesFilters.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import React from 'react';
-
-import cn from 'classnames/bind';
-import { observer } from 'mobx-react';
-
-import { useStore } from 'state/useStore';
-
-import styles from './SchedulesFilters.module.css';
-
-const cx = cn.bind(styles);
-
-interface SchedulesFiltersProps {}
-
-const SchedulesFilters = observer((props: SchedulesFiltersProps) => {
- const {} = props;
-
- const store = useStore();
-
- const {} = store;
-
- return
;
-});
-
-export default SchedulesFilters;
diff --git a/grafana-plugin/src/containers/SlackIntegrationButton/SlackIntegrationButton.tsx b/grafana-plugin/src/containers/SlackIntegrationButton/SlackIntegrationButton.tsx
index 2909b2f4..f5e9d366 100644
--- a/grafana-plugin/src/containers/SlackIntegrationButton/SlackIntegrationButton.tsx
+++ b/grafana-plugin/src/containers/SlackIntegrationButton/SlackIntegrationButton.tsx
@@ -3,7 +3,6 @@ import React, { useCallback, useState } from 'react';
import { Button, Modal } from '@grafana/ui';
import { observer } from 'mobx-react';
-import Text from 'components/Text/Text';
import WithConfirm from 'components/WithConfirm/WithConfirm';
import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl';
import { useStore } from 'state/useStore';
diff --git a/grafana-plugin/src/containers/TelegramIntegrationButton/TelegramIntegrationButton.tsx b/grafana-plugin/src/containers/TelegramIntegrationButton/TelegramIntegrationButton.tsx
index 4e5524ae..692e1fd7 100644
--- a/grafana-plugin/src/containers/TelegramIntegrationButton/TelegramIntegrationButton.tsx
+++ b/grafana-plugin/src/containers/TelegramIntegrationButton/TelegramIntegrationButton.tsx
@@ -6,7 +6,6 @@ import { observer } from 'mobx-react';
import CopyToClipboard from 'react-copy-to-clipboard';
import Text from 'components/Text/Text';
-import WithConfirm from 'components/WithConfirm/WithConfirm';
import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl';
import { useStore } from 'state/useStore';
import { UserAction } from 'state/userAction';
@@ -27,8 +26,6 @@ const TelegramIntegrationButton = observer((props: TelegramIntegrationProps) =>
const [showModal, setShowModal] = useState
(false);
- const store = useStore();
-
const onInstallModalHideCallback = useCallback(() => {
setShowModal(false);
}, []);
@@ -63,7 +60,7 @@ interface TelegramModalProps {
const TelegramModal = (props: TelegramModalProps) => {
const { onHide, onUpdate } = props;
const store = useStore();
- const { telegramChannelStore, userStore } = store;
+ const { telegramChannelStore } = store;
const [verificationCode, setVerificationCode] = useState();
const [botLink, setBotLink] = useState();
diff --git a/grafana-plugin/src/containers/TemplatePreview/TemplatePreview.tsx b/grafana-plugin/src/containers/TemplatePreview/TemplatePreview.tsx
index af4edbce..5f337ce2 100644
--- a/grafana-plugin/src/containers/TemplatePreview/TemplatePreview.tsx
+++ b/grafana-plugin/src/containers/TemplatePreview/TemplatePreview.tsx
@@ -1,7 +1,6 @@
import React, { useEffect, useState } from 'react';
import { LoadingPlaceholder } from '@grafana/ui';
-import { capitalCase } from 'change-case';
import cn from 'classnames/bind';
import { observer } from 'mobx-react';
@@ -24,10 +23,8 @@ interface TemplatePreviewProps {
active?: boolean;
}
-// web_title_template, web_message_template, web_image_url_template
-
const TemplatePreview = observer((props: TemplatePreviewProps) => {
- const { templateName, templateBody, alertReceiveChannelId, alertGroupId, onEditClick, active } = props;
+ const { templateName, templateBody, alertReceiveChannelId, alertGroupId } = props;
const [result, setResult] = useState<{ preview: string | null } | undefined>(undefined);
diff --git a/grafana-plugin/src/containers/UserSettings/UserSettings.tsx b/grafana-plugin/src/containers/UserSettings/UserSettings.tsx
index 75ba3c1c..14d20420 100644
--- a/grafana-plugin/src/containers/UserSettings/UserSettings.tsx
+++ b/grafana-plugin/src/containers/UserSettings/UserSettings.tsx
@@ -25,14 +25,11 @@ interface UserFormProps {
tab?: UserSettingsTab;
}
-const UserSettings = observer((props: UserFormProps) => {
- const { id, onHide, tab = UserSettingsTab.UserInfo } = props;
-
+const UserSettings = observer(({ id, onHide, tab = UserSettingsTab.UserInfo }: UserFormProps) => {
const store = useStore();
const { userStore, teamStore } = store;
const storeUser = userStore.items[id];
-
const isCurrent = id === store.userStore.currentUserPk;
const [activeTab, setActiveTab] = useState(tab);
@@ -45,7 +42,7 @@ const UserSettings = observer((props: UserFormProps) => {
if (isDesktopOrLaptop && activeTab === UserSettingsTab.NotificationSettings) {
setActiveTab(UserSettingsTab.UserInfo);
}
- }, [isDesktopOrLaptop]);
+ }, [isDesktopOrLaptop, activeTab]);
const onTabChange = useCallback((tab: UserSettingsTab) => {
setActiveTab(tab);
diff --git a/grafana-plugin/src/containers/UserSettings/parts/connectors/ICalConnector.tsx b/grafana-plugin/src/containers/UserSettings/parts/connectors/ICalConnector.tsx
index 1f672962..d5637b0e 100644
--- a/grafana-plugin/src/containers/UserSettings/parts/connectors/ICalConnector.tsx
+++ b/grafana-plugin/src/containers/UserSettings/parts/connectors/ICalConnector.tsx
@@ -33,11 +33,11 @@ const ICalConnector = (props: ICalConnectorProps) => {
useEffect(() => {
userStore
.getiCalLink(id)
- .then((res) => {
+ .then((_res) => {
setIsiCalLinkExisting(true);
setiCalLoading(false);
})
- .catch((res) => {
+ .catch((_res) => {
setIsiCalLinkExisting(false);
setiCalLoading(false);
});
diff --git a/grafana-plugin/src/containers/UserSettings/parts/connectors/MobileAppConnector.tsx b/grafana-plugin/src/containers/UserSettings/parts/connectors/MobileAppConnector.tsx
index 49f33b2f..16cb5a9e 100644
--- a/grafana-plugin/src/containers/UserSettings/parts/connectors/MobileAppConnector.tsx
+++ b/grafana-plugin/src/containers/UserSettings/parts/connectors/MobileAppConnector.tsx
@@ -22,7 +22,7 @@ const SlackConnector = (props: SlackConnectorProps) => {
const handleClickConfirmMobileAppButton = useCallback(() => {
onTabChange(UserSettingsTab.MobileAppVerification);
- }, []);
+ }, [onTabChange]);
if (!store.hasFeature(AppFeature.MobileApp)) {
return null;
@@ -32,7 +32,6 @@ const SlackConnector = (props: SlackConnectorProps) => {
Mobile App:
- {/*
Mobile App is not added */}
Click to add a mobile app
diff --git a/grafana-plugin/src/containers/UserSettings/parts/connectors/PhoneConnector.tsx b/grafana-plugin/src/containers/UserSettings/parts/connectors/PhoneConnector.tsx
index 05ec4509..8b2e57c0 100644
--- a/grafana-plugin/src/containers/UserSettings/parts/connectors/PhoneConnector.tsx
+++ b/grafana-plugin/src/containers/UserSettings/parts/connectors/PhoneConnector.tsx
@@ -28,7 +28,7 @@ const PhoneConnector = (props: PhoneConnectorProps) => {
const handleClickConfirmPhoneButton = useCallback(() => {
onTabChange(UserSettingsTab.PhoneVerification);
- }, [storeUser?.unverified_phone_number]);
+ }, [storeUser?.unverified_phone_number, onTabChange]);
const cloudVersionPhone = (user: User) => {
switch (user.cloud_connection_status) {
diff --git a/grafana-plugin/src/containers/UserSettings/parts/connectors/SlackConnector.tsx b/grafana-plugin/src/containers/UserSettings/parts/connectors/SlackConnector.tsx
index 2a8f141c..f0410f89 100644
--- a/grafana-plugin/src/containers/UserSettings/parts/connectors/SlackConnector.tsx
+++ b/grafana-plugin/src/containers/UserSettings/parts/connectors/SlackConnector.tsx
@@ -31,7 +31,7 @@ const SlackConnector = (props: SlackConnectorProps) => {
const handleConnectButtonClick = useCallback(() => {
onTabChange(UserSettingsTab.SlackInfo);
- }, []);
+ }, [onTabChange]);
const handleUnlinkSlackAccount = useCallback(() => {
userStore.unlinkSlack(userStore.currentUserPk);
diff --git a/grafana-plugin/src/containers/UserSettings/parts/connectors/TelegramConnector.tsx b/grafana-plugin/src/containers/UserSettings/parts/connectors/TelegramConnector.tsx
index 0e82b883..144ebd1c 100644
--- a/grafana-plugin/src/containers/UserSettings/parts/connectors/TelegramConnector.tsx
+++ b/grafana-plugin/src/containers/UserSettings/parts/connectors/TelegramConnector.tsx
@@ -29,7 +29,7 @@ const TelegramConnector = (props: TelegramConnectorProps) => {
const handleConnectButtonClick = useCallback(() => {
onTabChange(UserSettingsTab.TelegramInfo);
- }, []);
+ }, [onTabChange]);
const handleUnlinkTelegramAccount = useCallback(() => {
userStore.unlinkTelegram(userStore.currentUserPk);
diff --git a/grafana-plugin/src/containers/UserSettings/parts/index.tsx b/grafana-plugin/src/containers/UserSettings/parts/index.tsx
index 89e0f3ce..24221f4b 100644
--- a/grafana-plugin/src/containers/UserSettings/parts/index.tsx
+++ b/grafana-plugin/src/containers/UserSettings/parts/index.tsx
@@ -40,11 +40,14 @@ export const Tabs = (props: TabsProps) => {
showTelegramConnectionTab,
} = props;
- const getTabClickHandler = useCallback((tab: UserSettingsTab) => {
- return () => {
- onTabChange(tab);
- };
- }, []);
+ const getTabClickHandler = useCallback(
+ (tab: UserSettingsTab) => {
+ return () => {
+ onTabChange(tab);
+ };
+ },
+ [onTabChange]
+ );
return (
diff --git a/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.module.css b/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.module.css
deleted file mode 100644
index ab86c434..00000000
--- a/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.module.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.test {
- color: grey;
-}
diff --git a/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.tsx b/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.tsx
index 4d03a306..7758b450 100644
--- a/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.tsx
+++ b/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.tsx
@@ -1,26 +1,10 @@
-import React, { useCallback, useEffect, useState } from 'react';
+import React, { useEffect, useState } from 'react';
-import { getLocationSrv, LocationUpdate } from '@grafana/runtime';
-import {
- Field,
- Input,
- Button,
- Modal,
- HorizontalGroup,
- Alert,
- Icon,
- VerticalGroup,
- Table,
- LoadingPlaceholder,
-} from '@grafana/ui';
-import cn from 'classnames/bind';
+import { Button, HorizontalGroup, VerticalGroup, LoadingPlaceholder } from '@grafana/ui';
import { observer } from 'mobx-react';
-import Block from 'components/GBlock/Block';
-import GTable from 'components/GTable/GTable';
import PluginLink from 'components/PluginLink/PluginLink';
import Text from 'components/Text/Text';
-import WithConfirm from 'components/WithConfirm/WithConfirm';
import { User } from 'models/user/user.types';
import { AppFeature } from 'state/features';
import { WithStoreProps } from 'state/types';
@@ -28,10 +12,6 @@ import { useStore } from 'state/useStore';
import { UserAction } from 'state/userAction';
import { withMobXProviderContext } from 'state/withStore';
-import styles from './CloudPhoneSettings.module.css';
-
-const cx = cn.bind(styles);
-
interface CloudPhoneSettingsProps extends WithStoreProps {
userPk?: User['pk'];
}
diff --git a/grafana-plugin/src/containers/UserSettings/parts/tabs/PhoneVerification/PhoneVerification.tsx b/grafana-plugin/src/containers/UserSettings/parts/tabs/PhoneVerification/PhoneVerification.tsx
index 8d0f57cb..a779efec 100644
--- a/grafana-plugin/src/containers/UserSettings/parts/tabs/PhoneVerification/PhoneVerification.tsx
+++ b/grafana-plugin/src/containers/UserSettings/parts/tabs/PhoneVerification/PhoneVerification.tsx
@@ -35,11 +35,26 @@ const PHONE_REGEX = /^\+\d{8,15}$/;
const PhoneVerification = observer((props: PhoneVerificationProps) => {
const { userPk: propsUserPk } = props;
- const store = useStore();
- const { userStore, teamStore } = store;
+ const {
+ userStore: {
+ items: users,
+ currentUserPk,
+ updateUser,
+ makeTestCall,
+ forgetPhone,
+ loadUser,
+ isTestCallInProgress,
+ verifyPhone,
+ fetchVerificationCode,
+ },
+ teamStore,
+ isUserActionAllowed,
+ hasFeature,
+ } = useStore();
- const userPk = (propsUserPk || userStore.currentUserPk) as User['pk'];
- let user = userStore.items[userPk];
+ const userPk = (propsUserPk || currentUserPk) as User['pk'];
+ const user = users[userPk];
+ const isCurrentUser = currentUserPk === user.pk;
const [{ showForgetScreen, phone, code, isCodeSent, isPhoneNumberHidden, isLoading }, setState] = useReducer(
(state: PhoneVerificationState, newState: Partial) => ({
@@ -62,12 +77,11 @@ const PhoneVerification = observer((props: PhoneVerificationProps) => {
async ({ currentTarget: { checked: isPhoneNumberHidden } }: React.ChangeEvent) => {
setState({ isPhoneNumberHidden, isLoading: true });
- await userStore.updateUser({ pk: userPk, hide_phone_number: isPhoneNumberHidden });
- user = userStore.items[userPk];
+ await updateUser({ pk: userPk, hide_phone_number: isPhoneNumberHidden });
setState({ phone: user.verified_phone_number, isLoading: false });
},
- []
+ [user, userPk, updateUser]
);
const onChangePhoneCallback = useCallback((event: React.ChangeEvent) => {
@@ -79,37 +93,33 @@ const PhoneVerification = observer((props: PhoneVerificationProps) => {
}, []);
const handleMakeTestCallClick = useCallback(() => {
- userStore.makeTestCall(userPk);
- }, [userPk]);
+ makeTestCall(userPk);
+ }, [userPk, makeTestCall]);
const handleForgetNumberClick = useCallback(() => {
- userStore.forgetPhone(userPk).then(async () => {
- await userStore.loadUser(userPk);
+ forgetPhone(userPk).then(async () => {
+ await loadUser(userPk);
setState({ phone: '', showForgetScreen: false, isCodeSent: false });
});
- }, [userPk]);
-
- const { isTestCallInProgress } = userStore;
+ }, [userPk, forgetPhone, loadUser]);
const onSubmitCallback = useCallback(async () => {
if (isCodeSent) {
- userStore
- .verifyPhone(userPk, code)
+ verifyPhone(userPk, code)
.then(() => {
- userStore.loadUser(userPk);
+ loadUser(userPk);
})
.catch((error) => {
openErrorNotification(error.response.data);
});
} else {
- await userStore.updateUser({
+ await updateUser({
pk: userPk,
email: user.email,
unverified_phone_number: phone,
});
- userStore
- .fetchVerificationCode(userPk)
+ fetchVerificationCode(userPk)
.then(() => {
setState({ isCodeSent: true });
@@ -123,7 +133,7 @@ const PhoneVerification = observer((props: PhoneVerificationProps) => {
);
});
}
- }, [code, isCodeSent, phone, store, user.email, userPk, userStore]);
+ }, [code, isCodeSent, phone, user.email, userPk, verifyPhone, updateUser, fetchVerificationCode]);
const isTwilioConfigured = teamStore.currentTeam?.env_status.twilio_configured;
const phoneHasMinimumLength = phone?.length > 8;
@@ -131,14 +141,13 @@ const PhoneVerification = observer((props: PhoneVerificationProps) => {
const isPhoneValid = phoneHasMinimumLength && PHONE_REGEX.test(phone);
const showPhoneInputError = phoneHasMinimumLength && !isPhoneValid && !isPhoneNumberHidden && !isLoading;
- const isCurrent = userStore.currentUserPk === user.pk;
- const action = isCurrent ? UserAction.UpdateOwnSettings : UserAction.UpdateOtherUsersSettings;
+ const action = isCurrentUser ? UserAction.UpdateOwnSettings : UserAction.UpdateOtherUsersSettings;
const isButtonDisabled =
phone === user.verified_phone_number || (!isCodeSent && !isPhoneValid) || !isTwilioConfigured;
const isPhoneDisabled = !!user.verified_phone_number;
- const isCodeFieldDisabled = !isCodeSent || !store.isUserActionAllowed(action);
- const showToggle = user.verified_phone_number && user.pk === userStore.currentUserPk;
+ const isCodeFieldDisabled = !isCodeSent || !isUserActionAllowed(action);
+ const showToggle = user.verified_phone_number && isCurrentUser;
if (showForgetScreen) {
return (
@@ -159,7 +168,7 @@ const PhoneVerification = observer((props: PhoneVerificationProps) => {
>
)}
- {!isTwilioConfigured && store.hasFeature(AppFeature.LiveSettings) && (
+ {!isTwilioConfigured && hasFeature(AppFeature.LiveSettings) && (
<>
{}
-const TelegramInfo = observer((props: TelegramInfoProps) => {
+const TelegramInfo = observer((_props: TelegramInfoProps) => {
const store = useStore();
const { userStore, teamStore } = store;
diff --git a/grafana-plugin/src/containers/UserSummary/UserSummary.tsx b/grafana-plugin/src/containers/UserSummary/UserSummary.tsx
index 4fb9b595..422f159f 100644
--- a/grafana-plugin/src/containers/UserSummary/UserSummary.tsx
+++ b/grafana-plugin/src/containers/UserSummary/UserSummary.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect } from 'react';
+import { useEffect } from 'react';
import { observer } from 'mobx-react';
diff --git a/grafana-plugin/src/containers/UserTooltip/UserTooltip.module.css b/grafana-plugin/src/containers/UserTooltip/UserTooltip.module.css
deleted file mode 100644
index 63d08ecc..00000000
--- a/grafana-plugin/src/containers/UserTooltip/UserTooltip.module.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.root {
- display: block;
-}
diff --git a/grafana-plugin/src/containers/UserTooltip/UserTooltip.tsx b/grafana-plugin/src/containers/UserTooltip/UserTooltip.tsx
index 63a607bb..020a18cb 100644
--- a/grafana-plugin/src/containers/UserTooltip/UserTooltip.tsx
+++ b/grafana-plugin/src/containers/UserTooltip/UserTooltip.tsx
@@ -1,17 +1,12 @@
import React from 'react';
import { Tooltip } from '@grafana/ui';
-import cn from 'classnames/bind';
import { observer } from 'mobx-react';
import { getUserNotificationsSummary } from 'models/user/user.helpers';
import { User } from 'models/user/user.types';
import { useStore } from 'state/useStore';
-import styles from 'containers/UserTooltip/UserTooltip.module.css';
-
-const cx = cn.bind(styles);
-
interface UserTooltipProps {
id: User['pk'];
}
diff --git a/grafana-plugin/src/containers/UsersTimezones/UsersTimezones.module.css b/grafana-plugin/src/containers/UsersTimezones/UsersTimezones.module.css
index 746f8609..863519c2 100644
--- a/grafana-plugin/src/containers/UsersTimezones/UsersTimezones.module.css
+++ b/grafana-plugin/src/containers/UsersTimezones/UsersTimezones.module.css
@@ -89,14 +89,7 @@
--color: rgba(61, 113, 217, 0.2);
- background:
- repeating-linear-gradient(
- -45deg,
- var(--color),
- var(--color) 4px,
- transparent 4px,
- transparent 8px
- );
+ background: repeating-linear-gradient(-45deg, var(--color), var(--color) 4px, transparent 4px, transparent 8px);
}
.current-user-stripe {
diff --git a/grafana-plugin/src/containers/UsersTimezones/UsersTimezones.tsx b/grafana-plugin/src/containers/UsersTimezones/UsersTimezones.tsx
index 1147882f..b364eca3 100644
--- a/grafana-plugin/src/containers/UsersTimezones/UsersTimezones.tsx
+++ b/grafana-plugin/src/containers/UsersTimezones/UsersTimezones.tsx
@@ -9,11 +9,10 @@ import ScheduleBorderedAvatar from 'components/ScheduleBorderedAvatar/ScheduleBo
import ScheduleUserDetails from 'components/ScheduleUserDetails/ScheduleUserDetails';
import Text from 'components/Text/Text';
import { IsOncallIcon } from 'icons';
-import { Event, Layer, Schedule } from 'models/schedule/schedule.types';
+import { Schedule } from 'models/schedule/schedule.types';
import { Timezone } from 'models/timezone/timezone.types';
import { User } from 'models/user/user.types';
import { getColorSchemeMappingForUsers } from 'pages/schedule/Schedule.helpers';
-import { RootStore } from 'state';
import { useStore } from 'state/useStore';
import styles from './UsersTimezones.module.css';
@@ -83,10 +82,6 @@ const UsersTimezones: FC = (props) => {
Schedule team and timezones
- {/*
-
- Current schedule users only
- */}
@@ -175,7 +170,7 @@ const UserAvatars = (props: UserAvatarsProps) => {
return (
- {userGroups.map((group) => {
+ {userGroups.map((group, idx) => {
const userCurrentMoment = dayjs(currentMoment).tz(group.users[0].timezone); // TODO try using group.utcOffset
const diff = userCurrentMoment.diff(userCurrentMoment.startOf('day'), 'minutes');
@@ -183,6 +178,7 @@ const UserAvatars = (props: UserAvatarsProps) => {
return (
{
return 0;
});
- }, [propsUsers]);
+ }, [propsUsers, onCallNow]);
- const getAvatarClickHandler = useCallback((timezone: Timezone) => {
- return () => {
- onTzChange(timezone);
- };
- }, []);
+ const getAvatarClickHandler = useCallback(
+ (timezone: Timezone) => {
+ return () => {
+ onTzChange(timezone);
+ };
+ },
+ [onTzChange]
+ );
const colorSchemeMapping = getColorSchemeMappingForUsers(store, scheduleId, startMoment);
const width = active ? users.length * AVATAR_WIDTH + (users.length - 1) * AVATAR_GAP : AVATAR_WIDTH;
diff --git a/grafana-plugin/src/containers/WithPermissionControl/WithPermissionControl.tsx b/grafana-plugin/src/containers/WithPermissionControl/WithPermissionControl.tsx
index 7a95a8a3..2215b7a8 100644
--- a/grafana-plugin/src/containers/WithPermissionControl/WithPermissionControl.tsx
+++ b/grafana-plugin/src/containers/WithPermissionControl/WithPermissionControl.tsx
@@ -1,4 +1,4 @@
-import React, { ReactElement, useCallback, useState } from 'react';
+import React, { ReactElement, useCallback } from 'react';
import { Tooltip } from '@grafana/ui';
import cn from 'classnames/bind';
@@ -19,7 +19,7 @@ interface WithPermissionControlProps {
}
export const WithPermissionControl = observer((props: WithPermissionControlProps) => {
- const { userAction, children, disableByPaywall = false, className } = props;
+ const { userAction, children, className } = props;
const store = useStore();
diff --git a/grafana-plugin/src/dummy/dummy.ts b/grafana-plugin/src/dummy/dummy.ts
deleted file mode 100644
index e2e7845b..00000000
--- a/grafana-plugin/src/dummy/dummy.ts
+++ /dev/null
@@ -1 +0,0 @@
-interface Dummy {}
diff --git a/grafana-plugin/src/icons/index.tsx b/grafana-plugin/src/icons/index.tsx
index 18e64b85..896d4576 100644
--- a/grafana-plugin/src/icons/index.tsx
+++ b/grafana-plugin/src/icons/index.tsx
@@ -2,7 +2,7 @@ import React from 'react';
interface IconProps {}
-export const NewIncidentIcon = (props: IconProps) => (
+export const NewIncidentIcon = (_props: IconProps) => (
(
);
-export const AcknowledgedIncidentIcon = (props: IconProps) => (
+export const AcknowledgedIncidentIcon = (_props: IconProps) => (
(
);
-export const SilencedIncidentIcon = (props: IconProps) => (
+export const SilencedIncidentIcon = (_props: IconProps) => (
(
);
-export const SentryIcon = (props: IconProps) => (
+export const SentryIcon = (_props: IconProps) => (
(
);
-export const SilencedIncidentIconTransparent = (props: IconProps) => (
+export const SilencedIncidentIconTransparent = (_props: IconProps) => (
(
);
-export const CurlerIcon = (props: IconProps) => (
+export const CurlerIcon = (_props: IconProps) => (
);
-export const TelegramIcon = (props: IconProps) => (
+export const TelegramIcon = (_props: IconProps) => (
(
);
-export const AmixrIcon = (props: IconProps) => (
+export const AmixrIcon = (_props: IconProps) => (
(
);
-export const AmixrIconColored = (props: IconProps) => (
+export const AmixrIconColored = (_props: IconProps) => (
(
);
-export const HeartGreenIcon = (props: IconProps) => (
+export const HeartGreenIcon = (_props: IconProps) => (
(
);
-export const HeartRedIcon = (props: IconProps) => (
+export const HeartRedIcon = (_props: IconProps) => (
(
);
-export const HeartIcon = (props: IconProps) => (
+export const HeartIcon = (_props: IconProps) => (
(
);
-export const CrossCircleIcon = (props: IconProps) => (
+export const CrossCircleIcon = (_props: IconProps) => (
(
);
-export const ChangeTeamIcon = (props: IconProps) => (
+export const ChangeTeamIcon = (_props: IconProps) => (
);
-export const GrafanaIcon = (props: IconProps) => (
+export const GrafanaIcon = (_props: IconProps) => (
(
);
-export const ExpandIcon = (props: IconProps) => {
+export const ExpandIcon = (_props: IconProps) => {
return (
({
+ useStore: () => ({
+ isUserActionAllowed: jest.fn().mockReturnValue(true),
+ }),
+ }));
+}
+
+export function mockGrafanaLocationSrv() {
+ jest.mock('@grafana/runtime', () => ({
+ getLocationSrv: jest.fn(),
+ }));
+}
diff --git a/grafana-plugin/src/models/alert_receive_channel/alert_receive_channel.ts b/grafana-plugin/src/models/alert_receive_channel/alert_receive_channel.ts
index ab8808cf..fc29706f 100644
--- a/grafana-plugin/src/models/alert_receive_channel/alert_receive_channel.ts
+++ b/grafana-plugin/src/models/alert_receive_channel/alert_receive_channel.ts
@@ -1,5 +1,5 @@
import { omit } from 'lodash-es';
-import { action, observable, toJS } from 'mobx';
+import { action, observable } from 'mobx';
import { ActionDTO } from 'models/action';
import { AlertTemplatesDTO } from 'models/alert_templates';
@@ -12,7 +12,7 @@ import { Team } from 'models/team/team.types';
import { makeRequest } from 'network';
import { Mixpanel } from 'services/mixpanel';
import { RootStore } from 'state';
-import { getAnims, move } from 'state/helpers';
+import { move } from 'state/helpers';
import { SelectOption } from 'state/types';
import { showApiError } from 'utils';
@@ -22,8 +22,6 @@ import {
AlertReceiveChannelCounters,
} from './alert_receive_channel.types';
-const UPDATE_TIMER_INTERVAL = 10000;
-
export class AlertReceiveChannelStore extends BaseStore {
@observable.shallow
searchResult: Array;
@@ -60,7 +58,7 @@ export class AlertReceiveChannelStore extends BaseStore {
this.path = '/alert_receive_channels/';
}
- getSearchResult(query = '') {
+ getSearchResult(_query = '') {
if (!this.searchResult) {
return undefined;
}
@@ -76,10 +74,10 @@ export class AlertReceiveChannelStore extends BaseStore {
this.items = {
...this.items,
- [id]: alertReceiveChannel
- }
+ [id]: alertReceiveChannel,
+ };
- return alertReceiveChannel
+ return alertReceiveChannel;
}
@action
diff --git a/grafana-plugin/src/models/alert_receive_channel_filters/alert_receive_channel_filters.ts b/grafana-plugin/src/models/alert_receive_channel_filters/alert_receive_channel_filters.ts
index 37ec9b31..39f4cd78 100644
--- a/grafana-plugin/src/models/alert_receive_channel_filters/alert_receive_channel_filters.ts
+++ b/grafana-plugin/src/models/alert_receive_channel_filters/alert_receive_channel_filters.ts
@@ -1,4 +1,4 @@
-import { action, observable, toJS } from 'mobx';
+import { action, observable } from 'mobx';
import BaseStore from 'models/base_store';
import { makeRequest } from 'network';
diff --git a/grafana-plugin/src/models/alertgroup/alertgroup.types.ts b/grafana-plugin/src/models/alertgroup/alertgroup.types.ts
index d7e55b4f..0a435c59 100644
--- a/grafana-plugin/src/models/alertgroup/alertgroup.types.ts
+++ b/grafana-plugin/src/models/alertgroup/alertgroup.types.ts
@@ -1,7 +1,3 @@
-import React from 'react';
-
-import { Icon } from '@grafana/ui';
-
import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types';
import { Channel } from 'models/channel';
import { User } from 'models/user/user.types';
diff --git a/grafana-plugin/src/models/cloud/cloud.ts b/grafana-plugin/src/models/cloud/cloud.ts
index fa19125a..5fe25082 100644
--- a/grafana-plugin/src/models/cloud/cloud.ts
+++ b/grafana-plugin/src/models/cloud/cloud.ts
@@ -1,13 +1,8 @@
-import { get } from 'lodash-es';
-import { action, computed, observable } from 'mobx';
+import { action, observable } from 'mobx';
import BaseStore from 'models/base_store';
-import { NotificationPolicyType } from 'models/notification_policy';
-import { User } from 'models/user/user.types';
import { makeRequest } from 'network';
-import { Mixpanel } from 'services/mixpanel';
import { RootStore } from 'state';
-import { move } from 'state/helpers';
import { Cloud } from './cloud.types';
diff --git a/grafana-plugin/src/models/current_subscription.ts b/grafana-plugin/src/models/current_subscription.ts
index 4f7a8256..547bcf60 100644
--- a/grafana-plugin/src/models/current_subscription.ts
+++ b/grafana-plugin/src/models/current_subscription.ts
@@ -1,5 +1,3 @@
-import { UserDTO as User } from './user';
-
export interface CurrentSubscriptionDTO {
uuid: string;
created_at: string;
diff --git a/grafana-plugin/src/models/escalation_chain/escalation_chain.ts b/grafana-plugin/src/models/escalation_chain/escalation_chain.ts
index c6e19968..817c010c 100644
--- a/grafana-plugin/src/models/escalation_chain/escalation_chain.ts
+++ b/grafana-plugin/src/models/escalation_chain/escalation_chain.ts
@@ -28,10 +28,10 @@ export class EscalationChainStore extends BaseStore {
this.items = {
...this.items,
- [id]: escalationChain
- }
+ [id]: escalationChain,
+ };
- return escalationChain
+ return escalationChain;
}
@action
diff --git a/grafana-plugin/src/models/escalation_policy/escalation_policy.types.ts b/grafana-plugin/src/models/escalation_policy/escalation_policy.types.ts
index bdefa8d3..d171cee6 100644
--- a/grafana-plugin/src/models/escalation_policy/escalation_policy.types.ts
+++ b/grafana-plugin/src/models/escalation_policy/escalation_policy.types.ts
@@ -1,6 +1,5 @@
import { ActionDTO } from 'models/action';
import { Channel } from 'models/channel';
-import { ChannelFilter } from 'models/channel_filter/channel_filter.types';
import { EscalationChain } from 'models/escalation_chain/escalation_chain.types';
import { Schedule } from 'models/schedule/schedule.types';
import { User } from 'models/user/user.types';
diff --git a/grafana-plugin/src/models/global_setting/global_setting.ts b/grafana-plugin/src/models/global_setting/global_setting.ts
index edcb2986..f1f6d3f6 100644
--- a/grafana-plugin/src/models/global_setting/global_setting.ts
+++ b/grafana-plugin/src/models/global_setting/global_setting.ts
@@ -1,7 +1,6 @@
import { action, observable } from 'mobx';
import BaseStore from 'models/base_store';
-import { makeRequest } from 'network';
import { RootStore } from 'state';
import { GlobalSetting } from './global_setting.types';
@@ -31,9 +30,6 @@ export class GlobalSettingStore extends BaseStore {
@action
async updateItems(query = '') {
- // const results = await makeRequest(`${this.path}`, {
- // params: { search: query },
- // });
const results = await this.getAll();
this.items = {
diff --git a/grafana-plugin/src/models/maintenance/helpers.ts b/grafana-plugin/src/models/maintenance/helpers.ts
index beb96893..517bccfa 100644
--- a/grafana-plugin/src/models/maintenance/helpers.ts
+++ b/grafana-plugin/src/models/maintenance/helpers.ts
@@ -1,4 +1,4 @@
-import moment from 'moment';
+import moment from 'moment-timezone';
import { Maintenance } from './maintenance.types';
diff --git a/grafana-plugin/src/models/resolution_note/resolution_note.ts b/grafana-plugin/src/models/resolution_note/resolution_note.ts
index 89f50db1..9dcaeb2a 100644
--- a/grafana-plugin/src/models/resolution_note/resolution_note.ts
+++ b/grafana-plugin/src/models/resolution_note/resolution_note.ts
@@ -1,8 +1,7 @@
-import { action, observable } from 'mobx';
+import { observable } from 'mobx';
import { Alert } from 'models/alertgroup/alertgroup.types';
import BaseStore from 'models/base_store';
-import { EscalationChain } from 'models/escalation_chain/escalation_chain.types';
import { makeRequest } from 'network';
import { RootStore } from 'state';
diff --git a/grafana-plugin/src/models/schedule/schedule.helpers.ts b/grafana-plugin/src/models/schedule/schedule.helpers.ts
index e0914840..3da07350 100644
--- a/grafana-plugin/src/models/schedule/schedule.helpers.ts
+++ b/grafana-plugin/src/models/schedule/schedule.helpers.ts
@@ -41,7 +41,7 @@ export const fillGaps = (events: Event[]) => {
export const splitToShiftsAndFillGaps = (events: Event[]) => {
const shifts: Array<{ shiftId: Shift['id']; priority: Shift['priority_level']; events: Event[] }> = [];
- for (const [i, event] of events.entries()) {
+ for (const [_i, event] of events.entries()) {
if (event.shift?.pk) {
let shift = shifts.find((shift) => shift.shiftId === event.shift?.pk);
if (!shift) {
@@ -62,7 +62,7 @@ export const splitToShiftsAndFillGaps = (events: Event[]) => {
export const getShiftsFromStore = (
store: RootStore,
scheduleId: Schedule['id'],
- startMoment: dayjs.Dayjs,
+ startMoment: dayjs.Dayjs
): ShiftEvents[] => {
return store.scheduleStore.finalPreview
? store.scheduleStore.finalPreview
@@ -78,11 +78,8 @@ export const getLayersFromStore = (store: RootStore, scheduleId: Schedule['id'],
export const getOverridesFromStore = (
store: RootStore,
scheduleId: Schedule['id'],
- startMoment: dayjs.Dayjs,
-):
- | Layer[]
- | ShiftEvents[] => {
-
+ startMoment: dayjs.Dayjs
+): Layer[] | ShiftEvents[] => {
return store.scheduleStore.overridePreview
? store.scheduleStore.overridePreview
: (store.scheduleStore.events[scheduleId]?.['override']?.[getFromString(startMoment)] as Layer[]);
diff --git a/grafana-plugin/src/models/schedule/schedule.ts b/grafana-plugin/src/models/schedule/schedule.ts
index 944a6064..cee1deaa 100644
--- a/grafana-plugin/src/models/schedule/schedule.ts
+++ b/grafana-plugin/src/models/schedule/schedule.ts
@@ -1,14 +1,8 @@
-import { SelectOptions } from '@grafana/ui';
import dayjs from 'dayjs';
-import { omit, reject } from 'lodash-es';
-import { action, observable, toJS } from 'mobx';
-import ReactCSSTransitionGroup from 'react-transition-group'; // ES6
+import { action, observable } from 'mobx';
import BaseStore from 'models/base_store';
import { EscalationChain } from 'models/escalation_chain/escalation_chain.types';
-import { SlackChannel } from 'models/slack_channel/slack_channel.types';
-import { Timezone } from 'models/timezone/timezone.types';
-import { User } from 'models/user/user.types';
import { makeRequest } from 'network';
import { RootStore } from 'state';
import { SelectOption } from 'state/types';
@@ -16,16 +10,11 @@ import { SelectOption } from 'state/types';
import {
enrichLayers,
enrichOverrides,
- fillGaps,
getFromString,
splitToLayers,
splitToShiftsAndFillGaps,
} from './schedule.helpers';
-import { Events, Rotation, RotationType, Schedule, ScheduleEvent, Shift, Event, Layer, ShiftEvents } from './schedule.types';
-
-const DEFAULT_FORMAT = 'YYYY-MM-DDTHH:mm:ss';
-
-let I = 0;
+import { Rotation, RotationType, Schedule, ScheduleEvent, Shift, Event, Layer, ShiftEvents } from './schedule.types';
export class ScheduleStore extends BaseStore {
@observable
@@ -230,7 +219,7 @@ export class ScheduleStore extends BaseStore {
this.rotationPreview = layers;
}
- this.finalPreview = splitToShiftsAndFillGaps(response.final); /*.filter((shift) => shift.shiftId !== shiftId);*/
+ this.finalPreview = splitToShiftsAndFillGaps(response.final);
}
@action
@@ -331,25 +320,7 @@ export class ScheduleStore extends BaseStore {
});
const fromString = getFromString(startMoment);
-
const shifts = splitToShiftsAndFillGaps(response.events);
-
- // merge users on frontend side, we don't need it now
- /*shifts.forEach((shift) => {
- for (let i = 0; i < shift.events.length; i++) {
- const iEvent = shift.events[i];
-
- for (let j = i + 1; j < shift.events.length; j++) {
- const jEvent = shift.events[j];
- if (iEvent.start === jEvent.start && iEvent.end === jEvent.end) {
- iEvent.users.push(...jEvent.users);
- jEvent.merged = true;
- }
- }
- shift.events = shift.events.filter((event) => !event.merged);
- }
- });*/
-
const layers = type === 'rotation' ? splitToLayers(shifts) : undefined;
this.events = {
@@ -362,8 +333,6 @@ export class ScheduleStore extends BaseStore {
},
},
};
-
- // console.log(toJS(this.events));
}
async updateFrequencyOptions() {
diff --git a/grafana-plugin/src/models/slack_channel/slack_channel.ts b/grafana-plugin/src/models/slack_channel/slack_channel.ts
index 02c90cd8..389b0924 100644
--- a/grafana-plugin/src/models/slack_channel/slack_channel.ts
+++ b/grafana-plugin/src/models/slack_channel/slack_channel.ts
@@ -1,4 +1,4 @@
-import { action, observable, toJS } from 'mobx';
+import { action, observable } from 'mobx';
import BaseStore from 'models/base_store';
import { makeRequest } from 'network';
diff --git a/grafana-plugin/src/models/team/team.ts b/grafana-plugin/src/models/team/team.ts
index 082b3188..1f01add5 100644
--- a/grafana-plugin/src/models/team/team.ts
+++ b/grafana-plugin/src/models/team/team.ts
@@ -5,7 +5,7 @@ import { makeRequest } from 'network';
import { Mixpanel } from 'services/mixpanel';
import { RootStore } from 'state';
import { openErrorNotification } from 'utils';
-import { getPathnameByTeamNameSlug, getTeamNameSlugFromUrl } from 'utils/url';
+import { getPathnameByTeamNameSlug } from 'utils/url';
import { Team } from './team.types';
@@ -118,8 +118,8 @@ export class TeamStore extends BaseStore {
}
@action
- async updateTeam(teamId: Team['pk']) {
- const response = await makeRequest(this.path, {
+ async updateTeam(_teamId: Team['pk']) {
+ await makeRequest(this.path, {
params: {},
withCredentials: true,
});
diff --git a/grafana-plugin/src/models/telegram_channel/telegram_channel.helpers.ts b/grafana-plugin/src/models/telegram_channel/telegram_channel.helpers.ts
deleted file mode 100644
index aa7a5a00..00000000
--- a/grafana-plugin/src/models/telegram_channel/telegram_channel.helpers.ts
+++ /dev/null
@@ -1 +0,0 @@
-import { TelegramChannel } from './telegram_channel.types';
diff --git a/grafana-plugin/src/models/telegram_channel/telegram_channel.ts b/grafana-plugin/src/models/telegram_channel/telegram_channel.ts
index 871cec3c..6b72151c 100644
--- a/grafana-plugin/src/models/telegram_channel/telegram_channel.ts
+++ b/grafana-plugin/src/models/telegram_channel/telegram_channel.ts
@@ -1,7 +1,6 @@
import { action, computed, observable } from 'mobx';
import BaseStore from 'models/base_store';
-import { Team } from 'models/team/team.types';
import { makeRequest } from 'network';
import { RootStore } from 'state';
diff --git a/grafana-plugin/src/models/timezone/timezone.types.ts b/grafana-plugin/src/models/timezone/timezone.types.ts
index 0e330ef9..6ed40261 100644
--- a/grafana-plugin/src/models/timezone/timezone.types.ts
+++ b/grafana-plugin/src/models/timezone/timezone.types.ts
@@ -1,5 +1,3 @@
-import { concat } from 'lodash-es';
-
const tzs = [
'Africa/Abidjan',
'Africa/Accra',
diff --git a/grafana-plugin/src/models/user/user.helpers.tsx b/grafana-plugin/src/models/user/user.helpers.tsx
index 7af6f17c..7d21b87d 100644
--- a/grafana-plugin/src/models/user/user.helpers.tsx
+++ b/grafana-plugin/src/models/user/user.helpers.tsx
@@ -1,11 +1,7 @@
import React from 'react';
-import { Tooltip } from '@grafana/ui';
-import dayjs from 'dayjs';
import { pick } from 'lodash-es';
-import { Timezone } from 'models/timezone/timezone.types';
-
import { User, UserRole } from './user.types';
export const getIconType = (role: UserRole) => {
diff --git a/grafana-plugin/src/models/user/user.ts b/grafana-plugin/src/models/user/user.ts
index 0079d795..60972d80 100644
--- a/grafana-plugin/src/models/user/user.ts
+++ b/grafana-plugin/src/models/user/user.ts
@@ -1,11 +1,9 @@
import dayjs from 'dayjs';
import { get } from 'lodash-es';
import { action, computed, observable } from 'mobx';
-import moment from 'moment-timezone';
import BaseStore from 'models/base_store';
import { NotificationPolicyType } from 'models/notification_policy';
-import { getRandomTimezone } from 'models/timezone/timezone.helpers';
import { makeRequest } from 'network';
import { Mixpanel } from 'services/mixpanel';
import { RootStore } from 'state';
@@ -68,8 +66,6 @@ export class UserStore extends BaseStore {
};
this.currentUserPk = response.pk;
-
- // this.rootStore.currentTimezone = timezone;
}
@action
diff --git a/grafana-plugin/src/models/webinar/webinar.ts b/grafana-plugin/src/models/webinar/webinar.ts
index fede777b..134d6a5d 100644
--- a/grafana-plugin/src/models/webinar/webinar.ts
+++ b/grafana-plugin/src/models/webinar/webinar.ts
@@ -1,5 +1,5 @@
import { action, observable } from 'mobx';
-import moment from 'moment';
+import moment from 'moment-timezone';
import BaseStore from 'models/base_store';
import { makeRequest } from 'network';
diff --git a/grafana-plugin/src/pages/chat-ops/ChatOps.tsx b/grafana-plugin/src/pages/chat-ops/ChatOps.tsx
index 6fb01b3e..5e7315fb 100644
--- a/grafana-plugin/src/pages/chat-ops/ChatOps.tsx
+++ b/grafana-plugin/src/pages/chat-ops/ChatOps.tsx
@@ -26,9 +26,7 @@ class ChatOpsPage extends React.Component
diff --git a/grafana-plugin/src/pages/cloud/CloudPage.tsx b/grafana-plugin/src/pages/cloud/CloudPage.tsx
index 15eabf90..2675f113 100644
--- a/grafana-plugin/src/pages/cloud/CloudPage.tsx
+++ b/grafana-plugin/src/pages/cloud/CloudPage.tsx
@@ -1,24 +1,12 @@
import React, { useCallback, useEffect, useState } from 'react';
-import { getLocationSrv, LocationUpdate } from '@grafana/runtime';
-import {
- Field,
- Input,
- Button,
- Modal,
- HorizontalGroup,
- Alert,
- Icon,
- VerticalGroup,
- Table,
- LoadingPlaceholder,
-} from '@grafana/ui';
+import { getLocationSrv } from '@grafana/runtime';
+import { Field, Input, Button, HorizontalGroup, Icon, VerticalGroup, LoadingPlaceholder } from '@grafana/ui';
import cn from 'classnames/bind';
import { observer } from 'mobx-react';
import Block from 'components/GBlock/Block';
import GTable from 'components/GTable/GTable';
-import PluginLink from 'components/PluginLink/PluginLink';
import Text from 'components/Text/Text';
import WithConfirm from 'components/WithConfirm/WithConfirm';
import { CrossCircleIcon, HeartIcon } from 'icons';
@@ -35,7 +23,7 @@ const cx = cn.bind(styles);
interface CloudPageProps extends WithStoreProps {}
const ITEMS_PER_PAGE = 50;
-const CloudPage = observer((props: CloudPageProps) => {
+const CloudPage = observer((_props: CloudPageProps) => {
const store = useStore();
const [page, setPage] = useState(1);
const [cloudApiKey, setCloudApiKey] = useState('');
@@ -44,7 +32,7 @@ const CloudPage = observer((props: CloudPageProps) => {
const [cloudNotificationsEnabled, setCloudNotificationsEnabled] = useState(false);
const [heartbeatLink, setheartbeatLink] = useState(null);
const [heartbeatEnabled, setheartbeatEnabled] = useState(false);
- const [showConfirmationModal, setShowConfirmationModal] = useState(false);
+ const [_showConfirmationModal, setShowConfirmationModal] = useState(false);
const [syncingUsers, setSyncingUsers] = useState(false);
useEffect(() => {
@@ -55,7 +43,7 @@ const CloudPage = observer((props: CloudPageProps) => {
setheartbeatLink(cloudStatus.cloud_heartbeat_link);
setCloudNotificationsEnabled(cloudStatus.cloud_notifications_enabled);
});
- }, [cloudIsConnected]);
+ }, [cloudIsConnected, page, store.cloudStore]);
const { matched_users_count, results } = store.cloudStore.getSearchResult();
diff --git a/grafana-plugin/src/pages/escalation-chains/EscalationChains.tsx b/grafana-plugin/src/pages/escalation-chains/EscalationChains.tsx
index 9b4109ed..691b620c 100644
--- a/grafana-plugin/src/pages/escalation-chains/EscalationChains.tsx
+++ b/grafana-plugin/src/pages/escalation-chains/EscalationChains.tsx
@@ -29,7 +29,6 @@ import { EscalationChain } from 'models/escalation_chain/escalation_chain.types'
import { WithStoreProps } from 'state/types';
import { UserAction } from 'state/userAction';
import { withMobXProviderContext } from 'state/withStore';
-import { openWarningNotification } from 'utils';
import styles from './EscalationChains.module.css';
@@ -242,7 +241,7 @@ class EscalationChainsPage extends React.Component {
const { store } = this.props;
- const { selectedEscalationChain, showCreateEscalationChainModal, escalationChainIdToCopy } = this.state;
+ const { selectedEscalationChain } = this.state;
const { escalationChainStore } = store;
@@ -305,14 +304,14 @@ class EscalationChainsPage extends React.Component
{escalationChainDetails.map((alertReceiveChannel) => (
-
+
{alertReceiveChannel.display_name}
{alertReceiveChannel.channel_filters.map((channelFilter) => (
-
+
{channelFilter.display_name}
diff --git a/grafana-plugin/src/pages/incident/Incident.helpers.tsx b/grafana-plugin/src/pages/incident/Incident.helpers.tsx
index 844477d6..6d421a20 100644
--- a/grafana-plugin/src/pages/incident/Incident.helpers.tsx
+++ b/grafana-plugin/src/pages/incident/Incident.helpers.tsx
@@ -1,4 +1,4 @@
-import React, { ReactElement } from 'react';
+import React from 'react';
import { Button, HorizontalGroup, Icon, Tooltip, VerticalGroup } from '@grafana/ui';
@@ -8,44 +8,12 @@ import Tag from 'components/Tag/Tag';
import Text from 'components/Text/Text';
import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl';
import { MaintenanceIntegration } from 'models/alert_receive_channel';
-import { Alert as AlertType, Alert, AlertAction, IncidentStatus } from 'models/alertgroup/alertgroup.types';
+import { Alert as AlertType, Alert, IncidentStatus } from 'models/alertgroup/alertgroup.types';
import { User } from 'models/user/user.types';
import SilenceDropdown from 'pages/incidents/parts/SilenceDropdown';
import { move } from 'state/helpers';
import { UserAction } from 'state/userAction';
-const TAG_COLORS = [
- '#D32D20',
- '#1E72B8',
- '#B240A2',
- '#705DA0',
- '#466803',
- '#497A3C',
- '#3D71AA',
- '#B15415',
- '#890F02',
- '#6E6E6E',
- '#0A437C',
- '#6D1F62',
- '#584477',
- '#4C7A3F',
- '#2F4F4F',
- '#BF1B00',
- '#7662B1',
- '#8A2EB8',
- '#517A00',
- '#000000',
- '#3F6833',
- '#2F575E',
- '#99440A',
- '#AE561A',
- '#0E4AB4',
- '#58140C',
- '#052B51',
- '#511749',
- '#3F2B5B',
-];
-
export function getIncidentStatusTag(alert: Alert) {
switch (alert.status) {
case IncidentStatus.New:
diff --git a/grafana-plugin/src/pages/incident/Incident.tsx b/grafana-plugin/src/pages/incident/Incident.tsx
index 634a9121..26617937 100644
--- a/grafana-plugin/src/pages/incident/Incident.tsx
+++ b/grafana-plugin/src/pages/incident/Incident.tsx
@@ -18,7 +18,7 @@ import {
} from '@grafana/ui';
import cn from 'classnames/bind';
import { observer } from 'mobx-react';
-import moment from 'moment';
+import moment from 'moment-timezone';
import CopyToClipboard from 'react-copy-to-clipboard';
import Emoji from 'react-emoji-render';
import reactStringReplace from 'react-string-replace';
@@ -126,11 +126,7 @@ class IncidentPage extends React.Component
}
return (
-
+
{() =>
errorData.isNotFoundError ? (
@@ -430,14 +426,7 @@ class IncidentPage extends React.Component
return (match: string) => {
switch (match) {
case 'author':
- const {
- store: { userStore },
- } = this.props;
-
- const user = userStore.items?.[entity?.author?.pk];
-
return (
- /* }>*/
{
getLocationSrv().update({ query: { page: 'users', id: entity?.author?.pk } });
@@ -446,7 +435,6 @@ class IncidentPage extends React.Component
>
{entity.author?.username}
- /* */
);
default:
console.warn('Unknown render_after_resolve_report_json enity placeholder');
@@ -552,7 +540,7 @@ function GroupedIncidentsList({
contentClassName={cx('incidents-content')}
>
{alerts.map((alert) => (
-
+
))}
);
@@ -659,7 +647,6 @@ function AttachedIncidentsList({
#{incident.inside_organization_number} {incident.render_for_web.title}
- {/* */}
getUnattachClickHandler(incident.pk)} variant="secondary">
Unattach
diff --git a/grafana-plugin/src/pages/incidents/Incidents.tsx b/grafana-plugin/src/pages/incidents/Incidents.tsx
index f2ce5ed8..ef7fb432 100644
--- a/grafana-plugin/src/pages/incidents/Incidents.tsx
+++ b/grafana-plugin/src/pages/incidents/Incidents.tsx
@@ -6,7 +6,7 @@ import { Button, Icon, Tooltip, VerticalGroup, LoadingPlaceholder, HorizontalGro
import cn from 'classnames/bind';
import { get } from 'lodash-es';
import { observer } from 'mobx-react';
-import moment from 'moment';
+import moment from 'moment-timezone';
import Emoji from 'react-emoji-render';
import CursorPagination from 'components/CursorPagination/CursorPagination';
@@ -39,13 +39,15 @@ interface Pagination {
}
function withSkeleton(fn: (alert: AlertType) => ReactElement | ReactElement[]) {
- return (alert: AlertType) => {
+ const WithSkeleton = (alert: AlertType) => {
if (alert.short) {
return ;
}
return fn(alert);
};
+
+ return WithSkeleton;
}
interface IncidentsPageProps extends WithStoreProps, AppRootProps {}
diff --git a/grafana-plugin/src/pages/integrations/Integrations.tsx b/grafana-plugin/src/pages/integrations/Integrations.tsx
index 799671fd..7bde29fd 100644
--- a/grafana-plugin/src/pages/integrations/Integrations.tsx
+++ b/grafana-plugin/src/pages/integrations/Integrations.tsx
@@ -28,7 +28,6 @@ import { AlertReceiveChannelOption } from 'models/alert_receive_channel/alert_re
import { WithStoreProps } from 'state/types';
import { UserAction } from 'state/userAction';
import { withMobXProviderContext } from 'state/withStore';
-import { openWarningNotification } from 'utils';
import styles from './Integrations.module.css';
@@ -189,9 +188,6 @@ class Integrations extends React.Component
integrationSettingsTab,
});
}}
- /*onEditAlertReceiveChannelTemplates={this.getShowAlertReceiveChannelSettingsClickHandler(
- store.selectedAlertReceiveChannel
- )}*/
/>
@@ -269,7 +265,6 @@ class Integrations extends React.Component
if (integration?.display_name === 'Grafana Alerting') {
this.alertReceiveChanneltoPoll = { ...this.alertReceiveChanneltoPoll, [alertReceiveChannel.id]: 200 };
if (!this.alertReceiveChannelTimerId) {
- let counter = 200;
this.alertReceiveChannelTimerId = setInterval(this.checkTimerTick, 3000);
}
}
diff --git a/grafana-plugin/src/pages/livesettings/LiveSettingsPage.tsx b/grafana-plugin/src/pages/livesettings/LiveSettingsPage.tsx
index 9542253f..7028e366 100644
--- a/grafana-plugin/src/pages/livesettings/LiveSettingsPage.tsx
+++ b/grafana-plugin/src/pages/livesettings/LiveSettingsPage.tsx
@@ -1,24 +1,10 @@
import React from 'react';
-import {
- Button,
- Checkbox,
- ConfirmModal,
- DatePickerWithInput,
- HorizontalGroup,
- Icon,
- LoadingPlaceholder,
- PENDING_COLOR,
- Tooltip,
- VerticalGroup,
-} from '@grafana/ui';
+import { Button, Checkbox, HorizontalGroup, Icon } from '@grafana/ui';
import cn from 'classnames/bind';
-import { omit } from 'lodash-es';
import { observe } from 'mobx';
import { observer } from 'mobx-react';
import { Lambda } from 'mobx/lib/internal';
-import { AlignType } from 'rc-table/lib/interface';
-import { Redirect } from 'react-router-dom';
import GTable from 'components/GTable/GTable';
import Text from 'components/Text/Text';
@@ -122,8 +108,6 @@ class LiveSettings extends React.Component
const data: any = globalSettingStore.getSearchResult();
- const loading = !data;
-
return (
Env Variables
- {/*Some information */}
@@ -246,20 +229,6 @@ class LiveSettings extends React.Component
}
return (
- // Are you sure to reset to default?>}
- // onConfirm={this.getResetGlobalSettingClickHandler(item)}
- // okText="Yes"
- // cancelText="Cancel"
- // >
- //
- // Reset
- //
- //
-
Reset to default
diff --git a/grafana-plugin/src/pages/maintenance/Maintenance.tsx b/grafana-plugin/src/pages/maintenance/Maintenance.tsx
index 64458c13..4b675ed5 100644
--- a/grafana-plugin/src/pages/maintenance/Maintenance.tsx
+++ b/grafana-plugin/src/pages/maintenance/Maintenance.tsx
@@ -4,23 +4,17 @@ import { AppRootProps } from '@grafana/data';
import { Button, HorizontalGroup } from '@grafana/ui';
import cn from 'classnames/bind';
import { observer } from 'mobx-react';
-import moment from 'moment';
+import moment from 'moment-timezone';
import Emoji from 'react-emoji-render';
import GTable from 'components/GTable/GTable';
-import PluginLink from 'components/PluginLink/PluginLink';
import Text from 'components/Text/Text';
import WithConfirm from 'components/WithConfirm/WithConfirm';
-import GSelect from 'containers/GSelect/GSelect';
import MaintenanceForm from 'containers/MaintenanceForm/MaintenanceForm';
-import OutgoingWebhookForm from 'containers/OutgoingWebhookForm/OutgoingWebhookForm';
import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl';
-import { ActionDTO } from 'models/action';
import { getAlertReceiveChannelDisplayName } from 'models/alert_receive_channel/alert_receive_channel.helpers';
import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types';
-import { getMaintenanceProgress } from 'models/maintenance/helpers';
import { Maintenance, MaintenanceMode, MaintenanceType } from 'models/maintenance/maintenance.types';
-import { PRIVATE_CHANNEL_NAME } from 'models/slack_channel/slack_channel.config';
import { WithStoreProps } from 'state/types';
import { UserAction } from 'state/userAction';
import { withMobXProviderContext } from 'state/withStore';
@@ -203,11 +197,7 @@ class MaintenancePage extends React.Component {
const started = moment(maintenance.started_at_timestamp * 1000);
const ended = moment(maintenance.maintenance_till_timestamp * 1000);
-
- const percent = getMaintenanceProgress(maintenance);
- const title = `${started.format('MMM DD, YYYY hh:mm A')} - ${ended.format('MMM DD, YYYY hh:mm A')}`;
-
- return title;
+ return `${started.format('MMM DD, YYYY hh:mm A')} - ${ended.format('MMM DD, YYYY hh:mm A')}`;
};
renderTimer = (maintenance: Maintenance) => {
diff --git a/grafana-plugin/src/pages/migration-tool/MigrationTool.tsx b/grafana-plugin/src/pages/migration-tool/MigrationTool.tsx
index 8ed547e2..4ed5a038 100644
--- a/grafana-plugin/src/pages/migration-tool/MigrationTool.tsx
+++ b/grafana-plugin/src/pages/migration-tool/MigrationTool.tsx
@@ -1,15 +1,11 @@
import React from 'react';
-import { Button, Icon, LoadingPlaceholder, Tag, TextArea } from '@grafana/ui';
-import { sentenceCase } from 'change-case';
+import { Button, LoadingPlaceholder, Tag, TextArea } from '@grafana/ui';
import cn from 'classnames/bind';
import { observer } from 'mobx-react';
import Emoji from 'react-emoji-render';
-import PluginLink from 'components/PluginLink/PluginLink';
import Text from 'components/Text/Text';
-import GSelect from 'containers/GSelect/GSelect';
-import { PRIVATE_CHANNEL_NAME } from 'models/slack_channel/slack_channel.config';
import { makeRequest } from 'network';
import { withMobXProviderContext } from 'state/withStore';
import { showApiError } from 'utils';
@@ -173,12 +169,12 @@ class MigrationToolPage extends React.Component
+
{key}:{' '}
{Array.isArray(item) && item.length ? (
{item.map((subItem) => (
-
+
))}
@@ -194,8 +190,8 @@ class MigrationToolPage extends React.Component
{' '}
- Migration will be applied to the "General" team. Once you perform the migration there won’t be
- possible to migrate data to the current Grafana OnCall workspace again. It’s a 1-time operation.
+ Migration will be applied to the "General" team. Once you perform the migration there won't be
+ possible to migrate data to the current Grafana OnCall workspace again. It's a 1-time operation.
@@ -208,7 +204,7 @@ class MigrationToolPage extends React.Component
{' '}
- Only “ical” schedules will be migrated. User names in your calendars should not be prefixed with
+ Only "ical" schedules will be migrated. User names in your calendars should not be prefixed with
'@', use bare usernames or emails.
@@ -267,7 +263,7 @@ class MigrationToolPage extends React.Component
{endpointsList.map((item) => (
-
+
{' '}
))}
diff --git a/grafana-plugin/src/pages/organization-logs/OrganizationLog.tsx b/grafana-plugin/src/pages/organization-logs/OrganizationLog.tsx
index 35f84dcb..66a7d5b5 100644
--- a/grafana-plugin/src/pages/organization-logs/OrganizationLog.tsx
+++ b/grafana-plugin/src/pages/organization-logs/OrganizationLog.tsx
@@ -1,10 +1,10 @@
-import React, { ChangeEvent, SyntheticEvent, ReactText } from 'react';
+import React from 'react';
-import { Button, colors, HorizontalGroup, Tag, Tooltip } from '@grafana/ui';
+import { Button, HorizontalGroup, Tag, Tooltip } from '@grafana/ui';
import cn from 'classnames/bind';
import { debounce } from 'lodash-es';
import { observer } from 'mobx-react';
-import moment, { Moment } from 'moment';
+import moment, { Moment } from 'moment-timezone';
import { RouteComponentProps } from 'react-router-dom';
import Avatar from 'components/Avatar/Avatar';
diff --git a/grafana-plugin/src/pages/outgoing_webhooks/OutgoingWebhooks.test.tsx b/grafana-plugin/src/pages/outgoing_webhooks/OutgoingWebhooks.test.tsx
new file mode 100644
index 00000000..309cd063
--- /dev/null
+++ b/grafana-plugin/src/pages/outgoing_webhooks/OutgoingWebhooks.test.tsx
@@ -0,0 +1,74 @@
+import 'jest/matchMedia.ts';
+import React from 'react';
+
+import { describe, expect, test } from '@jest/globals';
+import { render, screen, waitFor } from '@testing-library/react';
+import '@testing-library/jest-dom';
+import outgoingWebhooksStub from 'jest/outgoingWebhooksStub';
+
+import { OutgoingWebhook } from 'models/outgoing_webhook/outgoing_webhook.types';
+
+import { OutgoingWebhooks } from './OutgoingWebhooks';
+
+const outgoingWebhooks = outgoingWebhooksStub as OutgoingWebhook[];
+const outgoingWebhookStore = () => ({
+ loadItem: () => Promise.resolve(outgoingWebhooks[0]),
+ updateItems: () => Promise.resolve(),
+ getSearchResult: () => outgoingWebhooks,
+ items: outgoingWebhooks.reduce((prev, current) => {
+ prev[current.id] = current;
+ return prev;
+ }, {}),
+});
+
+jest.mock('state/useStore', () => ({
+ useStore: () => ({
+ outgoingWebhookStore: outgoingWebhookStore(),
+ isUserActionAllowed: jest.fn().mockReturnValue(true),
+ }),
+}));
+jest.mock('@grafana/runtime', () => ({
+ getLocationSrv: jest.fn(),
+}));
+
+describe('OutgoingWebhooks', () => {
+ const storeMock = {
+ isUserActionAllowed: jest.fn().mockReturnValue(true),
+ outgoingWebhookStore: outgoingWebhookStore(),
+ };
+
+ beforeAll(() => {
+ console.warn = () => {};
+ console.error = () => {};
+ });
+
+ test('It renders all retrieved webhooks', async () => {
+ render( );
+
+ const gTable = screen.queryByTestId('test__gTable');
+ const rows = gTable.querySelectorAll('tbody tr');
+
+ await waitFor(() => {
+ expect(() => queryEditForm()).toThrow(); // edit doesn't show for [id=undefined]
+ expect(rows.length).toBe(outgoingWebhooks.length);
+ });
+ });
+
+ test('It opens Edit View if [id] is supplied', async () => {
+ const id = outgoingWebhooks[0].id;
+ render( );
+
+ expect(() => queryEditForm()).toThrow(); // before updates kick in
+ await waitFor(() => {
+ expect(queryEditForm()).toBeDefined(); // edit shows for [id=?]
+ });
+ });
+
+ function getProps(id: OutgoingWebhook['id'] = undefined): any {
+ return { store: storeMock, query: { id } };
+ }
+
+ function queryEditForm(): HTMLElement {
+ return screen.getByTestId('test__outgoingWebhookEditForm');
+ }
+});
diff --git a/grafana-plugin/src/pages/outgoing_webhooks/OutgoingWebhooks.tsx b/grafana-plugin/src/pages/outgoing_webhooks/OutgoingWebhooks.tsx
index 51d80e98..c81fa697 100644
--- a/grafana-plugin/src/pages/outgoing_webhooks/OutgoingWebhooks.tsx
+++ b/grafana-plugin/src/pages/outgoing_webhooks/OutgoingWebhooks.tsx
@@ -50,7 +50,7 @@ class OutgoingWebhooks extends React.Component {
- this.setState((prevState) => ({
+ this.setState((_prevState) => ({
errorData: initErrorDataState(),
outgoingWebhookIdToEdit: undefined,
})); // reset state on query parse
@@ -60,7 +60,9 @@ class OutgoingWebhooks extends React.Component {
constructor(props: SchedulePageProps) {
@@ -111,26 +109,6 @@ class SchedulePage extends React.Component
{schedule?.name}
- {/*
- Grafana 1
-
- Grafana 2
-
- Grafana 3
- >
- }
- />
- */}
{users && (
@@ -139,11 +117,6 @@ class SchedulePage extends React.Component
)}
- {/*
*/}
- {/*
-
-
- */}
/>
- {/*
*/}
@@ -192,32 +164,6 @@ class SchedulePage extends React.Component
{startMoment.format('DD MMM')} - {startMoment.add(6, 'day').format('DD MMM')}
- {/*
-
-
- */}
- {(events || []).map((event) => (
-
+ {(events || []).map((event, idx) => (
+
))}
@@ -357,9 +359,9 @@ class SchedulesPage extends React.Component {
+ renderOncallNow = (item: Schedule, _index: number) => {
if (item.on_call_now?.length > 0) {
- return item.on_call_now.map((user, index) => {
+ return item.on_call_now.map((user, _index) => {
return (
@@ -386,7 +388,7 @@ class SchedulesPage extends React.Component
{item.warnings.map((warning: string) => (
- {warning}
+ {warning}
))}
);
diff --git a/grafana-plugin/src/pages/schedules_NEW/Schedules.tsx b/grafana-plugin/src/pages/schedules_NEW/Schedules.tsx
index 8c7ed34a..6ceedaad 100644
--- a/grafana-plugin/src/pages/schedules_NEW/Schedules.tsx
+++ b/grafana-plugin/src/pages/schedules_NEW/Schedules.tsx
@@ -21,12 +21,10 @@ import WithConfirm from 'components/WithConfirm/WithConfirm';
import ScheduleFinal from 'containers/Rotations/ScheduleFinal';
import ScheduleForm from 'containers/ScheduleForm/ScheduleForm';
import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl';
-import { getFromString } from 'models/schedule/schedule.helpers';
import { Schedule, ScheduleType } from 'models/schedule/schedule.types';
import { getSlackChannelName } from 'models/slack_channel/slack_channel.helpers';
import { Timezone } from 'models/timezone/timezone.types';
import { getStartOfWeek } from 'pages/schedule/Schedule.helpers';
-import { AppFeature } from 'state/features';
import { WithStoreProps } from 'state/types';
import { UserAction } from 'state/userAction';
import { withMobXProviderContext } from 'state/withStore';
@@ -73,7 +71,7 @@ class SchedulesPage extends React.Component (
-
+
{escalationChain.name}
))
@@ -311,12 +297,6 @@ class SchedulesPage extends React.Component
- {/* */}
);
};
@@ -325,11 +305,11 @@ class SchedulesPage extends React.Component{item.name} ;
};
- renderOncallNow = (item: Schedule, index: number) => {
+ renderOncallNow = (item: Schedule, _index: number) => {
if (item.on_call_now?.length > 0) {
return (
- {item.on_call_now.map((user, index) => {
+ {item.on_call_now.map((user, _index) => {
return (
@@ -353,22 +333,9 @@ class SchedulesPage extends React.Component {
- return item.chatOps;
- }; */
-
- /* renderQuality = (item: Schedule) => {
- const type = item.quality > 70 ? 'primary' : 'warning';
-
- return {item.quality || 70}% ;
- }; */
-
renderButtons = (item: Schedule) => {
return (
- {/*
-
- */}
@@ -405,16 +372,14 @@ class SchedulesPage extends React.Component {
- const { filters } = this.state;
- const { store } = this.props;
- const { scheduleStore } = store;
-
+ // const { filters } = this.state;
+ // const { scheduleStore } = this.props.store;
// scheduleStore.updateItems(filters.searchTerm);
};
debouncedUpdateSchedules = debounce(this.applyFilters, 1000);
- handlePageChange = (page: number) => {};
+ handlePageChange = (_page: number) => {};
update = () => {
const { store } = this.props;
diff --git a/grafana-plugin/src/pages/settings/SettingsPage.tsx b/grafana-plugin/src/pages/settings/SettingsPage.tsx
index 30951e1e..eff60e26 100644
--- a/grafana-plugin/src/pages/settings/SettingsPage.tsx
+++ b/grafana-plugin/src/pages/settings/SettingsPage.tsx
@@ -1,15 +1,12 @@
import React from 'react';
-import { DatePickerWithInput, Field, Input, Switch } from '@grafana/ui';
+import { Field, Input, Switch } from '@grafana/ui';
import cn from 'classnames/bind';
import { observer } from 'mobx-react';
-import moment from 'moment';
import Text from 'components/Text/Text';
import ApiTokenSettings from 'containers/ApiTokenSettings/ApiTokenSettings';
-import GSelect from 'containers/GSelect/GSelect';
import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl';
-import { PRIVATE_CHANNEL_NAME } from 'models/slack_channel/slack_channel.config';
import { WithStoreProps } from 'state/types';
import { UserAction } from 'state/userAction';
import { withMobXProviderContext } from 'state/withStore';
@@ -62,26 +59,6 @@ class SettingsPage extends React.Component
/>
- {/*
-
- {
- teamStore.saveCurrentTeam({ archive_alerts_from: moment(value).format('YYYY-MM-DD') });
- }}
- />
-
- */}
API URL
diff --git a/grafana-plugin/src/pages/users/Users.tsx b/grafana-plugin/src/pages/users/Users.tsx
index 3e75aacd..c84deaa1 100644
--- a/grafana-plugin/src/pages/users/Users.tsx
+++ b/grafana-plugin/src/pages/users/Users.tsx
@@ -83,7 +83,7 @@ class Users extends React.Component {
return await userStore.updateItems(getRealFilters(usersFilters), page);
};
- componentDidUpdate(prevProps: Readonly, prevState: Readonly, snapshot?: any) {
+ componentDidUpdate(prevProps: Readonly, _prevState: Readonly, _snapshot?: any) {
const { store } = this.props;
if (!this.initialUsersLoaded && store.isUserActionAllowed(UserAction.ViewOtherUsers)) {
diff --git a/grafana-plugin/src/plugin.json b/grafana-plugin/src/plugin.json
index b3a4705a..43462418 100644
--- a/grafana-plugin/src/plugin.json
+++ b/grafana-plugin/src/plugin.json
@@ -9,12 +9,7 @@
"name": "Grafana Labs",
"url": "https://grafana.com"
},
- "keywords": [
- "oncall",
- "irm",
- "incident",
- "response"
- ],
+ "keywords": ["oncall", "irm", "incident", "response"],
"logos": {
"small": "img/logo.svg",
"large": "img/logo.svg"
@@ -29,9 +24,7 @@
"url": "https://github.com/grafana/oncall/blob/main/LICENSE"
}
],
- "screenshots": [
- { "name": "Escalation chain", "path": "img/screenshot.png" }
- ],
+ "screenshots": [{ "name": "Escalation chain", "path": "img/screenshot.png" }],
"version": "%VERSION%",
"updated": "%TODAY%"
},
@@ -57,7 +50,8 @@
"path": "/a/grafana-oncall-app/?page=integrations",
"role": "Viewer",
"addToNav": true
- },{
+ },
+ {
"type": "page",
"name": "Escalation Chains",
"path": "/a/grafana-oncall-app/?page=escalations",
diff --git a/grafana-plugin/src/state/helpers.ts b/grafana-plugin/src/state/helpers.ts
index 6401f572..10e8976b 100644
--- a/grafana-plugin/src/state/helpers.ts
+++ b/grafana-plugin/src/state/helpers.ts
@@ -51,7 +51,7 @@ export function move(arr: any[], old_index: number, new_index: number) {
new_index += arr.length;
}
if (new_index >= arr.length) {
- var k = new_index - arr.length;
+ let k = new_index - arr.length;
while (k-- + 1) {
arr.push(undefined);
}
diff --git a/grafana-plugin/src/state/incidents.ts b/grafana-plugin/src/state/incidents.ts
deleted file mode 100644
index f97ce7b9..00000000
--- a/grafana-plugin/src/state/incidents.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export class IncidentsModel {
- private a = '1';
-}
diff --git a/grafana-plugin/src/state/plugin.ts b/grafana-plugin/src/state/plugin.ts
index 544eda02..80adbbd2 100644
--- a/grafana-plugin/src/state/plugin.ts
+++ b/grafana-plugin/src/state/plugin.ts
@@ -31,10 +31,9 @@ export async function startPluginSync() {
return await makeRequest('/plugin/sync', { method: 'POST' });
}
-
export const SYNC_STATUS_RETRY_LIMIT = 10;
-export const syncStatusDelay = retryCount => new Promise(resolve => setTimeout(resolve, 10 * 2 ** retryCount));
+export const syncStatusDelay = (retryCount) => new Promise((resolve) => setTimeout(resolve, 10 * 2 ** retryCount));
export async function getPluginSyncStatus() {
return await makeRequest(`/plugin/sync`, { method: 'GET' });
diff --git a/grafana-plugin/src/state/rootBaseStore.ts b/grafana-plugin/src/state/rootBaseStore.ts
index 4062749b..d300a8ac 100644
--- a/grafana-plugin/src/state/rootBaseStore.ts
+++ b/grafana-plugin/src/state/rootBaseStore.ts
@@ -32,13 +32,11 @@ import { makeRequest } from 'network';
import { AppFeature } from './features';
import {
- createGrafanaToken,
getPluginSyncStatus,
installPlugin,
startPluginSync,
SYNC_STATUS_RETRY_LIMIT,
syncStatusDelay,
- updateGrafanaToken,
} from './plugin';
import { UserAction } from './userAction';
@@ -131,8 +129,6 @@ export class RootBaseStore {
this.teamStore.loadCurrentTeam();
this.grafanaTeamStore.updateItems();
this.updateFeatures();
- // this.userStore.updateItems();
- // this.maintenanceStore.updateMaintenances();
this.userStore.updateNotificationPolicyOptions();
this.userStore.updateNotifyByOptions();
this.alertReceiveChannelStore.updateAlertReceiveChannelOptions();
@@ -165,7 +161,7 @@ export class RootBaseStore {
this.initializationError = e.response.status;
}
- async startSync(key?: string) {
+ async startSync() {
try {
return await startPluginSync();
} catch (e) {
diff --git a/grafana-plugin/src/state/withStore.tsx b/grafana-plugin/src/state/withStore.tsx
index 14946022..c83cf626 100644
--- a/grafana-plugin/src/state/withStore.tsx
+++ b/grafana-plugin/src/state/withStore.tsx
@@ -2,10 +2,12 @@ import React from 'react';
import { MobXProviderContext } from 'mobx-react';
-export const withMobXProviderContext = (BaseComponent: any) => (props: any) => {
- return (
+export const withMobXProviderContext = (BaseComponent: any) => {
+ const MobXProviderWrappedComponent = (props: any) => (
{(mobXProviderContext) => }
);
+
+ return MobXProviderWrappedComponent;
};
diff --git a/grafana-plugin/src/style/index.css b/grafana-plugin/src/style/index.css
index 0a948ad3..e248f1e8 100644
--- a/grafana-plugin/src/style/index.css
+++ b/grafana-plugin/src/style/index.css
@@ -19,7 +19,9 @@
}
@keyframes fadeIn {
- from { opacity: 0; }
+ from {
+ opacity: 0;
+ }
}
.disabled-row {
diff --git a/grafana-plugin/src/types.ts b/grafana-plugin/src/types.ts
index bd11b73d..8411077e 100644
--- a/grafana-plugin/src/types.ts
+++ b/grafana-plugin/src/types.ts
@@ -5,7 +5,7 @@ export interface OnCallAppSettings {
}
declare global {
- interface Window {
+ export interface Window {
grafanaBootData: any;
RECAPTCHA_SITE_KEY: string;
grecaptcha: any;
diff --git a/grafana-plugin/src/utils/DOM.ts b/grafana-plugin/src/utils/DOM.ts
index b1ebae8c..e971fbbe 100644
--- a/grafana-plugin/src/utils/DOM.ts
+++ b/grafana-plugin/src/utils/DOM.ts
@@ -4,7 +4,7 @@ export const waitForElement = (selector: string) => {
return resolve(document.querySelector(selector));
}
- const observer = new MutationObserver((mutations) => {
+ const observer = new MutationObserver((_mutations) => {
if (document.querySelector(selector)) {
resolve(document.querySelector(selector));
observer.disconnect();
@@ -20,19 +20,19 @@ export const waitForElement = (selector: string) => {
export const getCoords = (elem) => {
// crossbrowser version
- var box = elem.getBoundingClientRect();
+ const box = elem.getBoundingClientRect();
- var body = document.body;
- var docEl = document.documentElement;
+ const body = document.body;
+ const docEl = document.documentElement;
- var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
- var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
+ const scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
+ const scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
- var clientTop = docEl.clientTop || body.clientTop || 0;
- var clientLeft = docEl.clientLeft || body.clientLeft || 0;
+ const clientTop = docEl.clientTop || body.clientTop || 0;
+ const clientLeft = docEl.clientLeft || body.clientLeft || 0;
- var top = box.top + scrollTop - clientTop;
- var left = box.left + scrollLeft - clientLeft;
+ const top = box.top + scrollTop - clientTop;
+ const left = box.left + scrollLeft - clientLeft;
return { top: Math.round(top), left: Math.round(left) };
};
diff --git a/grafana-plugin/src/utils/index.ts b/grafana-plugin/src/utils/index.ts
index 98d1ef13..76259213 100644
--- a/grafana-plugin/src/utils/index.ts
+++ b/grafana-plugin/src/utils/index.ts
@@ -1,8 +1,9 @@
import { AppEvents } from '@grafana/data';
+import { AxiosError } from 'axios';
import { sentenceCase } from 'change-case';
// @ts-ignore
import appEvents from 'grafana/app/core/app_events';
-import { isArray, concat, isPlainObject, flatMap, map, keys, isNil } from 'lodash-es';
+import { isArray, concat, isPlainObject, flatMap, map, keys } from 'lodash-es';
import qs from 'query-string';
export const TZ_OFFSET = new Date().getTimezoneOffset();
@@ -26,8 +27,8 @@ export function showApiError(error: any) {
throw error;
}
-export function refreshPageError(error: any) {
- if (error.response.status == 502) {
+export function refreshPageError(error: AxiosError) {
+ if (error.response?.status === 502) {
const payload = error.response.data;
const text = `Try to refresh the page. ${payload}`;
openErrorNotification(text);
diff --git a/grafana-plugin/src/utils/loadCss.ts b/grafana-plugin/src/utils/loadCss.ts
index e5efcbee..5db0ddb2 100644
--- a/grafana-plugin/src/utils/loadCss.ts
+++ b/grafana-plugin/src/utils/loadCss.ts
@@ -1,5 +1,5 @@
export default function loadCss(url: string) {
- return new Promise((resolve, reject) => {
+ return new Promise((resolve, _reject) => {
let link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
diff --git a/grafana-plugin/tsconfig.json b/grafana-plugin/tsconfig.json
index add73ef9..56342bec 100644
--- a/grafana-plugin/tsconfig.json
+++ b/grafana-plugin/tsconfig.json
@@ -6,9 +6,10 @@
"rootDirs": ["src", "frontend_enterprise/src"],
"baseUrl": "src",
"typeRoots": ["./node_modules/@types"],
- "noUnusedLocals": false,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
"strict": false,
"resolveJsonModule": true,
- "noImplicitAny": false,
+ "noImplicitAny": false
}
}
diff --git a/grafana-plugin/webpack.config.js b/grafana-plugin/webpack.config.js
index d7c05774..9e6f58e9 100644
--- a/grafana-plugin/webpack.config.js
+++ b/grafana-plugin/webpack.config.js
@@ -1,5 +1,4 @@
const path = require('path');
-const fs = require('fs');
const CircularDependencyPlugin = require('circular-dependency-plugin');
@@ -133,8 +132,7 @@ module.exports.getWebpackConfig = (config, options) => {
allowAsyncCycles: false,
// set the current working directory for displaying module paths
cwd: process.cwd(),
- })
- // new BundleAnalyzerPlugin(),
+ }),
],
resolve: {
@@ -144,12 +142,5 @@ module.exports.getWebpackConfig = (config, options) => {
},
};
- /* fs.writeFile('webpack-conf.json', JSON.stringify(newConfig, null, 2), function (err) {
- if (err) {
- return console.log(err);
- }
- console.log('config > webpack-conf.json');
- }); */
-
return newConfig;
};
diff --git a/grafana-plugin/yarn.lock b/grafana-plugin/yarn.lock
index 3583dfd8..d2836932 100644
--- a/grafana-plugin/yarn.lock
+++ b/grafana-plugin/yarn.lock
@@ -2,9 +2,14 @@
# yarn lockfile v1
+"@adobe/css-tools@^4.0.1":
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.0.1.tgz#b38b444ad3aa5fedbb15f2f746dcd934226a12dd"
+ integrity sha512-+u76oB43nOHrF4DDWRLWDCtci7f3QJoEBigemIdIeTi1ODqjx6Tad9NCVnPRwewWlKkVab5PlK8DCtPTyX7S8g==
+
"@ampproject/remapping@^2.1.0":
version "2.2.0"
- resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz"
+ resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d"
integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==
dependencies:
"@jridgewell/gen-mapping" "^0.1.0"
@@ -17,76 +22,41 @@
dependencies:
"@babel/highlight" "^7.18.6"
-"@babel/compat-data@^7.17.10":
- version "7.18.5"
- resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.5.tgz"
- integrity sha512-BxhE40PVCBxVEJsSBhB6UWyAuqJRxGsAw8BdHMJ3AKGydcwuWW4kOO3HmqBQAdcq/OP+/DlTVxLvsCzRTnZuGg==
+"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8", "@babel/compat-data@^7.19.3":
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.3.tgz#707b939793f867f5a73b2666e6d9a3396eb03151"
+ integrity sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw==
-"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8":
- version "7.18.13"
- resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.13.tgz#6aff7b350a1e8c3e40b029e46cbe78e24a913483"
- integrity sha512-5yUzC5LqyTFp2HLmDoxGQelcdYgSpP9xsnMWBphAscOdFrHSAVbLNzWiy32sVNDqJRDiJK6klfDnAgu6PAGSHw==
-
-"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.18.9", "@babel/core@^7.7.2", "@babel/core@^7.8.0":
- version "7.18.13"
- resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.13.tgz#9be8c44512751b05094a4d3ab05fc53a47ce00ac"
- integrity sha512-ZisbOvRRusFktksHSG6pjj1CSvkPkcZq/KHD45LAkVP/oiHJkNBZWfpvlLmX8OtHDG8IuzsFlVRWo08w7Qxn0A==
+"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.17.9", "@babel/core@^7.18.9", "@babel/core@^7.7.2", "@babel/core@^7.8.0":
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.3.tgz#2519f62a51458f43b682d61583c3810e7dcee64c"
+ integrity sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==
dependencies:
"@ampproject/remapping" "^2.1.0"
"@babel/code-frame" "^7.18.6"
- "@babel/generator" "^7.18.13"
- "@babel/helper-compilation-targets" "^7.18.9"
- "@babel/helper-module-transforms" "^7.18.9"
- "@babel/helpers" "^7.18.9"
- "@babel/parser" "^7.18.13"
+ "@babel/generator" "^7.19.3"
+ "@babel/helper-compilation-targets" "^7.19.3"
+ "@babel/helper-module-transforms" "^7.19.0"
+ "@babel/helpers" "^7.19.0"
+ "@babel/parser" "^7.19.3"
"@babel/template" "^7.18.10"
- "@babel/traverse" "^7.18.13"
- "@babel/types" "^7.18.13"
+ "@babel/traverse" "^7.19.3"
+ "@babel/types" "^7.19.3"
convert-source-map "^1.7.0"
debug "^4.1.0"
gensync "^1.0.0-beta.2"
json5 "^2.2.1"
semver "^6.3.0"
-"@babel/core@^7.17.9":
- version "7.18.5"
- resolved "https://registry.npmjs.org/@babel/core/-/core-7.18.5.tgz"
- integrity sha512-MGY8vg3DxMnctw0LdvSEojOsumc70g0t18gNyUdAZqB1Rpd1Bqo/svHGvt+UJ6JcGX+DIekGFDxxIWofBxLCnQ==
+"@babel/generator@^7.19.3", "@babel/generator@^7.7.2":
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.3.tgz#d7f4d1300485b4547cb6f94b27d10d237b42bf59"
+ integrity sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==
dependencies:
- "@ampproject/remapping" "^2.1.0"
- "@babel/code-frame" "^7.16.7"
- "@babel/generator" "^7.18.2"
- "@babel/helper-compilation-targets" "^7.18.2"
- "@babel/helper-module-transforms" "^7.18.0"
- "@babel/helpers" "^7.18.2"
- "@babel/parser" "^7.18.5"
- "@babel/template" "^7.16.7"
- "@babel/traverse" "^7.18.5"
- "@babel/types" "^7.18.4"
- convert-source-map "^1.7.0"
- debug "^4.1.0"
- gensync "^1.0.0-beta.2"
- json5 "^2.2.1"
- semver "^6.3.0"
-
-"@babel/generator@^7.18.13", "@babel/generator@^7.7.2":
- version "7.18.13"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.13.tgz#59550cbb9ae79b8def15587bdfbaa388c4abf212"
- integrity sha512-CkPg8ySSPuHTYPJYo7IRALdqyjM9HCbt/3uOBEFbzyGVP6Mn8bwFPB0jX6982JVNBlYzM1nnPkfjuXSOPtQeEQ==
- dependencies:
- "@babel/types" "^7.18.13"
+ "@babel/types" "^7.19.3"
"@jridgewell/gen-mapping" "^0.3.2"
jsesc "^2.5.1"
-"@babel/generator@^7.18.2":
- version "7.18.2"
- resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz"
- integrity sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==
- dependencies:
- "@babel/types" "^7.18.2"
- "@jridgewell/gen-mapping" "^0.3.0"
- jsesc "^2.5.1"
-
"@babel/helper-annotate-as-pure@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb"
@@ -102,51 +72,41 @@
"@babel/helper-explode-assignable-expression" "^7.18.6"
"@babel/types" "^7.18.9"
-"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9":
- version "7.18.9"
- resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf"
- integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==
+"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.19.0", "@babel/helper-compilation-targets@^7.19.3":
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz#a10a04588125675d7c7ae299af86fa1b2ee038ca"
+ integrity sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==
dependencies:
- "@babel/compat-data" "^7.18.8"
+ "@babel/compat-data" "^7.19.3"
"@babel/helper-validator-option" "^7.18.6"
- browserslist "^4.20.2"
+ browserslist "^4.21.3"
semver "^6.3.0"
-"@babel/helper-compilation-targets@^7.18.2":
- version "7.18.2"
- resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.2.tgz"
- integrity sha512-s1jnPotJS9uQnzFtiZVBUxe67CuBa679oWFHpxYYnTpRL/1ffhyX44R9uYiXoa/pLXcY9H2moJta0iaanlk/rQ==
- dependencies:
- "@babel/compat-data" "^7.17.10"
- "@babel/helper-validator-option" "^7.16.7"
- browserslist "^4.20.2"
- semver "^6.3.0"
-
-"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.18.9":
- version "7.18.13"
- resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.13.tgz#63e771187bd06d234f95fdf8bd5f8b6429de6298"
- integrity sha512-hDvXp+QYxSRL+23mpAlSGxHMDyIGChm0/AwTfTAAK5Ufe40nCsyNdaYCGuK91phn/fVu9kqayImRDkvNAgdrsA==
+"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz#bfd6904620df4e46470bae4850d66be1054c404b"
+ integrity sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==
dependencies:
"@babel/helper-annotate-as-pure" "^7.18.6"
"@babel/helper-environment-visitor" "^7.18.9"
- "@babel/helper-function-name" "^7.18.9"
+ "@babel/helper-function-name" "^7.19.0"
"@babel/helper-member-expression-to-functions" "^7.18.9"
"@babel/helper-optimise-call-expression" "^7.18.6"
"@babel/helper-replace-supers" "^7.18.9"
"@babel/helper-split-export-declaration" "^7.18.6"
-"@babel/helper-create-regexp-features-plugin@^7.18.6":
- version "7.18.6"
- resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.18.6.tgz#3e35f4e04acbbf25f1b3534a657610a000543d3c"
- integrity sha512-7LcpH1wnQLGrI+4v+nPp+zUvIkF9x0ddv1Hkdue10tg3gmRnLy97DXh4STiOf1qeIInyD69Qv5kKSZzKD8B/7A==
+"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz#7976aca61c0984202baca73d84e2337a5424a41b"
+ integrity sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==
dependencies:
"@babel/helper-annotate-as-pure" "^7.18.6"
regexpu-core "^5.1.0"
-"@babel/helper-define-polyfill-provider@^0.3.1", "@babel/helper-define-polyfill-provider@^0.3.2":
- version "0.3.2"
- resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.2.tgz#bd10d0aca18e8ce012755395b05a79f45eca5073"
- integrity sha512-r9QJJ+uDWrd+94BSPcP6/de67ygLtvVy6cK4luE6MOuDsZIdoaPBnfSpbO/+LTifjPckbKXRuI9BB/Z2/y3iTg==
+"@babel/helper-define-polyfill-provider@^0.3.1", "@babel/helper-define-polyfill-provider@^0.3.2", "@babel/helper-define-polyfill-provider@^0.3.3":
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a"
+ integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==
dependencies:
"@babel/helper-compilation-targets" "^7.17.7"
"@babel/helper-plugin-utils" "^7.16.7"
@@ -155,16 +115,11 @@
resolve "^1.14.2"
semver "^6.1.2"
-"@babel/helper-environment-visitor@^7.16.7", "@babel/helper-environment-visitor@^7.18.9":
+"@babel/helper-environment-visitor@^7.18.9":
version "7.18.9"
resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be"
integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==
-"@babel/helper-environment-visitor@^7.18.2":
- version "7.18.2"
- resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz"
- integrity sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ==
-
"@babel/helper-explode-assignable-expression@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096"
@@ -172,23 +127,15 @@
dependencies:
"@babel/types" "^7.18.6"
-"@babel/helper-function-name@^7.17.9":
- version "7.17.9"
- resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz"
- integrity sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==
+"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c"
+ integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==
dependencies:
- "@babel/template" "^7.16.7"
- "@babel/types" "^7.17.0"
+ "@babel/template" "^7.18.10"
+ "@babel/types" "^7.19.0"
-"@babel/helper-function-name@^7.18.9":
- version "7.18.9"
- resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0"
- integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==
- dependencies:
- "@babel/template" "^7.18.6"
- "@babel/types" "^7.18.9"
-
-"@babel/helper-hoist-variables@^7.16.7", "@babel/helper-hoist-variables@^7.18.6":
+"@babel/helper-hoist-variables@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678"
integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==
@@ -209,33 +156,19 @@
dependencies:
"@babel/types" "^7.18.6"
-"@babel/helper-module-transforms@^7.18.0":
- version "7.18.0"
- resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz"
- integrity sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==
- dependencies:
- "@babel/helper-environment-visitor" "^7.16.7"
- "@babel/helper-module-imports" "^7.16.7"
- "@babel/helper-simple-access" "^7.17.7"
- "@babel/helper-split-export-declaration" "^7.16.7"
- "@babel/helper-validator-identifier" "^7.16.7"
- "@babel/template" "^7.16.7"
- "@babel/traverse" "^7.18.0"
- "@babel/types" "^7.18.0"
-
-"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.18.9":
- version "7.18.9"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712"
- integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==
+"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30"
+ integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==
dependencies:
"@babel/helper-environment-visitor" "^7.18.9"
"@babel/helper-module-imports" "^7.18.6"
"@babel/helper-simple-access" "^7.18.6"
"@babel/helper-split-export-declaration" "^7.18.6"
"@babel/helper-validator-identifier" "^7.18.6"
- "@babel/template" "^7.18.6"
- "@babel/traverse" "^7.18.9"
- "@babel/types" "^7.18.9"
+ "@babel/template" "^7.18.10"
+ "@babel/traverse" "^7.19.0"
+ "@babel/types" "^7.19.0"
"@babel/helper-optimise-call-expression@^7.18.6":
version "7.18.6"
@@ -244,10 +177,10 @@
dependencies:
"@babel/types" "^7.18.6"
-"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
- version "7.18.9"
- resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz#4b8aea3b069d8cb8a72cdfe28ddf5ceca695ef2f"
- integrity sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==
+"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz#4796bb14961521f0f8715990bee2fb6e51ce21bf"
+ integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==
"@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9":
version "7.18.9"
@@ -259,23 +192,16 @@
"@babel/helper-wrap-function" "^7.18.9"
"@babel/types" "^7.18.9"
-"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9":
- version "7.18.9"
- resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz#1092e002feca980fbbb0bd4d51b74a65c6a500e6"
- integrity sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ==
+"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9", "@babel/helper-replace-supers@^7.19.1":
+ version "7.19.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz#e1592a9b4b368aa6bdb8784a711e0bcbf0612b78"
+ integrity sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==
dependencies:
"@babel/helper-environment-visitor" "^7.18.9"
"@babel/helper-member-expression-to-functions" "^7.18.9"
"@babel/helper-optimise-call-expression" "^7.18.6"
- "@babel/traverse" "^7.18.9"
- "@babel/types" "^7.18.9"
-
-"@babel/helper-simple-access@^7.17.7":
- version "7.18.2"
- resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz"
- integrity sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ==
- dependencies:
- "@babel/types" "^7.18.2"
+ "@babel/traverse" "^7.19.1"
+ "@babel/types" "^7.19.0"
"@babel/helper-simple-access@^7.18.6":
version "7.18.6"
@@ -291,7 +217,7 @@
dependencies:
"@babel/types" "^7.18.9"
-"@babel/helper-split-export-declaration@^7.16.7", "@babel/helper-split-export-declaration@^7.18.6":
+"@babel/helper-split-export-declaration@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075"
integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==
@@ -303,43 +229,34 @@
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56"
integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==
-"@babel/helper-validator-identifier@^7.16.7", "@babel/helper-validator-identifier@^7.18.6":
- version "7.18.6"
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076"
- integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==
+"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1":
+ version "7.19.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2"
+ integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==
-"@babel/helper-validator-option@^7.16.7", "@babel/helper-validator-option@^7.18.6":
+"@babel/helper-validator-option@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8"
integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==
"@babel/helper-wrap-function@^7.18.9":
- version "7.18.11"
- resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.18.11.tgz#bff23ace436e3f6aefb61f85ffae2291c80ed1fb"
- integrity sha512-oBUlbv+rjZLh2Ks9SKi4aL7eKaAXBWleHzU89mP0G6BMUlRxSckk9tSIkgDGydhgFxHuGSlBQZfnaD47oBEB7w==
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz#89f18335cff1152373222f76a4b37799636ae8b1"
+ integrity sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==
dependencies:
- "@babel/helper-function-name" "^7.18.9"
+ "@babel/helper-function-name" "^7.19.0"
"@babel/template" "^7.18.10"
- "@babel/traverse" "^7.18.11"
- "@babel/types" "^7.18.10"
+ "@babel/traverse" "^7.19.0"
+ "@babel/types" "^7.19.0"
-"@babel/helpers@^7.18.2":
- version "7.18.2"
- resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.2.tgz"
- integrity sha512-j+d+u5xT5utcQSzrh9p+PaJX94h++KN+ng9b9WEJq7pkUPAd61FGqhjuUEdfknb3E/uDBb7ruwEeKkIxNJPIrg==
+"@babel/helpers@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.0.tgz#f30534657faf246ae96551d88dd31e9d1fa1fc18"
+ integrity sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==
dependencies:
- "@babel/template" "^7.16.7"
- "@babel/traverse" "^7.18.2"
- "@babel/types" "^7.18.2"
-
-"@babel/helpers@^7.18.9":
- version "7.18.9"
- resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9"
- integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==
- dependencies:
- "@babel/template" "^7.18.6"
- "@babel/traverse" "^7.18.9"
- "@babel/types" "^7.18.9"
+ "@babel/template" "^7.18.10"
+ "@babel/traverse" "^7.19.0"
+ "@babel/types" "^7.19.0"
"@babel/highlight@^7.18.6":
version "7.18.6"
@@ -350,15 +267,10 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
-"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.18.13":
- version "7.18.13"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.13.tgz#5b2dd21cae4a2c5145f1fbd8ca103f9313d3b7e4"
- integrity sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==
-
-"@babel/parser@^7.18.5":
- version "7.18.5"
- resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz"
- integrity sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==
+"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.19.3":
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.3.tgz#8dd36d17c53ff347f9e55c328710321b49479a9a"
+ integrity sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ==
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6":
version "7.18.6"
@@ -376,13 +288,13 @@
"@babel/helper-skip-transparent-expression-wrappers" "^7.18.9"
"@babel/plugin-proposal-optional-chaining" "^7.18.9"
-"@babel/plugin-proposal-async-generator-functions@^7.18.10":
- version "7.18.10"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.10.tgz#85ea478c98b0095c3e4102bff3b67d306ed24952"
- integrity sha512-1mFuY2TOsR1hxbjCo4QL+qlIjV07p4H4EUYw2J/WCqsvFV6V9X9z9YhXbWndc/4fw+hYGlDT7egYxliMp5O6Ew==
+"@babel/plugin-proposal-async-generator-functions@^7.19.1":
+ version "7.19.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz#34f6f5174b688529342288cd264f80c9ea9fb4a7"
+ integrity sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==
dependencies:
"@babel/helper-environment-visitor" "^7.18.9"
- "@babel/helper-plugin-utils" "^7.18.9"
+ "@babel/helper-plugin-utils" "^7.19.0"
"@babel/helper-remap-async-to-generator" "^7.18.9"
"@babel/plugin-syntax-async-generators" "^7.8.4"
@@ -404,15 +316,15 @@
"@babel/plugin-syntax-class-static-block" "^7.14.5"
"@babel/plugin-proposal-decorators@^7.18.10":
- version "7.18.10"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.18.10.tgz#788650d01e518a8a722eb8b3055dd9d73ecb7a35"
- integrity sha512-wdGTwWF5QtpTY/gbBtQLAiCnoxfD4qMbN87NYZle1dOZ9Os8Y6zXcKrIaOU8W+TIvFUWVGG9tUgNww3CjXRVVw==
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.19.3.tgz#c1977e4902a18cdf9051bf7bf08d97db2fd8b110"
+ integrity sha512-MbgXtNXqo7RTKYIXVchVJGPvaVufQH3pxvQyfbGvNw1DObIhph+PesYXJTcd8J4DdWibvf6Z2eanOyItX8WnJg==
dependencies:
- "@babel/helper-create-class-features-plugin" "^7.18.9"
- "@babel/helper-plugin-utils" "^7.18.9"
- "@babel/helper-replace-supers" "^7.18.9"
+ "@babel/helper-create-class-features-plugin" "^7.19.0"
+ "@babel/helper-plugin-utils" "^7.19.0"
+ "@babel/helper-replace-supers" "^7.19.1"
"@babel/helper-split-export-declaration" "^7.18.6"
- "@babel/plugin-syntax-decorators" "^7.18.6"
+ "@babel/plugin-syntax-decorators" "^7.19.0"
"@babel/plugin-proposal-dynamic-import@^7.18.6":
version "7.18.6"
@@ -544,12 +456,12 @@
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
-"@babel/plugin-syntax-decorators@^7.18.6":
- version "7.18.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.18.6.tgz#2e45af22835d0b0f8665da2bfd4463649ce5dbc1"
- integrity sha512-fqyLgjcxf/1yhyZ6A+yo1u9gJ7eleFQod2lkaUsF9DQ7sbbY3Ligym3L0+I2c0WmqNKDpoD9UTb1AKP3qRMOAQ==
+"@babel/plugin-syntax-decorators@^7.18.6", "@babel/plugin-syntax-decorators@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz#5f13d1d8fce96951bea01a10424463c9a5b3a599"
+ integrity sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==
dependencies:
- "@babel/helper-plugin-utils" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.19.0"
"@babel/plugin-syntax-dynamic-import@7.8.3", "@babel/plugin-syntax-dynamic-import@^7.8.3":
version "7.8.3"
@@ -686,16 +598,17 @@
dependencies:
"@babel/helper-plugin-utils" "^7.18.9"
-"@babel/plugin-transform-classes@^7.18.9":
- version "7.18.9"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.9.tgz#90818efc5b9746879b869d5ce83eb2aa48bbc3da"
- integrity sha512-EkRQxsxoytpTlKJmSPYrsOMjCILacAjtSVkd4gChEe2kXjFCun3yohhW5I7plXJhCemM0gKsaGMcO8tinvCA5g==
+"@babel/plugin-transform-classes@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz#0e61ec257fba409c41372175e7c1e606dc79bb20"
+ integrity sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==
dependencies:
"@babel/helper-annotate-as-pure" "^7.18.6"
+ "@babel/helper-compilation-targets" "^7.19.0"
"@babel/helper-environment-visitor" "^7.18.9"
- "@babel/helper-function-name" "^7.18.9"
+ "@babel/helper-function-name" "^7.19.0"
"@babel/helper-optimise-call-expression" "^7.18.6"
- "@babel/helper-plugin-utils" "^7.18.9"
+ "@babel/helper-plugin-utils" "^7.19.0"
"@babel/helper-replace-supers" "^7.18.9"
"@babel/helper-split-export-declaration" "^7.18.6"
globals "^11.1.0"
@@ -707,7 +620,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.18.9"
-"@babel/plugin-transform-destructuring@^7.18.9":
+"@babel/plugin-transform-destructuring@^7.18.13":
version "7.18.13"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz#9e03bc4a94475d62b7f4114938e6c5c33372cbf5"
integrity sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow==
@@ -786,14 +699,14 @@
"@babel/helper-simple-access" "^7.18.6"
babel-plugin-dynamic-import-node "^2.3.3"
-"@babel/plugin-transform-modules-systemjs@^7.18.9":
- version "7.18.9"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.9.tgz#545df284a7ac6a05125e3e405e536c5853099a06"
- integrity sha512-zY/VSIbbqtoRoJKo2cDTewL364jSlZGvn0LKOf9ntbfxOvjfmyrdtEEOAdswOswhZEb8UH3jDkCKHd1sPgsS0A==
+"@babel/plugin-transform-modules-systemjs@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz#5f20b471284430f02d9c5059d9b9a16d4b085a1f"
+ integrity sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==
dependencies:
"@babel/helper-hoist-variables" "^7.18.6"
- "@babel/helper-module-transforms" "^7.18.9"
- "@babel/helper-plugin-utils" "^7.18.9"
+ "@babel/helper-module-transforms" "^7.19.0"
+ "@babel/helper-plugin-utils" "^7.19.0"
"@babel/helper-validator-identifier" "^7.18.6"
babel-plugin-dynamic-import-node "^2.3.3"
@@ -805,13 +718,13 @@
"@babel/helper-module-transforms" "^7.18.6"
"@babel/helper-plugin-utils" "^7.18.6"
-"@babel/plugin-transform-named-capturing-groups-regex@^7.18.6":
- version "7.18.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.18.6.tgz#c89bfbc7cc6805d692f3a49bc5fc1b630007246d"
- integrity sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg==
+"@babel/plugin-transform-named-capturing-groups-regex@^7.19.1":
+ version "7.19.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz#ec7455bab6cd8fb05c525a94876f435a48128888"
+ integrity sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==
dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.18.6"
- "@babel/helper-plugin-utils" "^7.18.6"
+ "@babel/helper-create-regexp-features-plugin" "^7.19.0"
+ "@babel/helper-plugin-utils" "^7.19.0"
"@babel/plugin-transform-new-target@^7.18.6":
version "7.18.6"
@@ -871,15 +784,15 @@
"@babel/plugin-transform-react-jsx" "^7.18.6"
"@babel/plugin-transform-react-jsx@^7.18.6":
- version "7.18.10"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.18.10.tgz#ea47b2c4197102c196cbd10db9b3bb20daa820f1"
- integrity sha512-gCy7Iikrpu3IZjYZolFE4M1Sm+nrh1/6za2Ewj77Z+XirT4TsbJcvOFOyF+fRPwU6AKKK136CZxx6L8AbSFG6A==
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz#b3cbb7c3a00b92ec8ae1027910e331ba5c500eb9"
+ integrity sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==
dependencies:
"@babel/helper-annotate-as-pure" "^7.18.6"
"@babel/helper-module-imports" "^7.18.6"
- "@babel/helper-plugin-utils" "^7.18.9"
+ "@babel/helper-plugin-utils" "^7.19.0"
"@babel/plugin-syntax-jsx" "^7.18.6"
- "@babel/types" "^7.18.10"
+ "@babel/types" "^7.19.0"
"@babel/plugin-transform-react-pure-annotations@^7.18.6":
version "7.18.6"
@@ -923,12 +836,12 @@
dependencies:
"@babel/helper-plugin-utils" "^7.18.6"
-"@babel/plugin-transform-spread@^7.18.9":
- version "7.18.9"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.18.9.tgz#6ea7a6297740f381c540ac56caf75b05b74fb664"
- integrity sha512-39Q814wyoOPtIB/qGopNIL9xDChOE1pNU0ZY5dO0owhiVt/5kFm4li+/bBtwc7QotG0u5EPzqhZdjMtmqBqyQA==
+"@babel/plugin-transform-spread@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz#dd60b4620c2fec806d60cfaae364ec2188d593b6"
+ integrity sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==
dependencies:
- "@babel/helper-plugin-utils" "^7.18.9"
+ "@babel/helper-plugin-utils" "^7.19.0"
"@babel/helper-skip-transparent-expression-wrappers" "^7.18.9"
"@babel/plugin-transform-sticky-regex@^7.18.6":
@@ -962,12 +875,12 @@
"@babel/plugin-syntax-typescript" "^7.18.6"
"@babel/plugin-transform-typescript@^7.18.12", "@babel/plugin-transform-typescript@^7.18.6":
- version "7.18.12"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.12.tgz#712e9a71b9e00fde9f8c0238e0cceee86ab2f8fd"
- integrity sha512-2vjjam0cum0miPkenUbQswKowuxs/NjMwIKEq0zwegRxXk12C9YOF9STXnaUptITOtOJHKHpzvvWYOjbm6tc0w==
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.3.tgz#4f1db1e0fe278b42ddbc19ec2f6cd2f8262e35d6"
+ integrity sha512-z6fnuK9ve9u/0X0rRvI9MY0xg+DOUaABDYOe+/SQTxtlptaBB/V9JIUxJn6xp3lMBeb9qe8xSFmHU35oZDXD+w==
dependencies:
- "@babel/helper-create-class-features-plugin" "^7.18.9"
- "@babel/helper-plugin-utils" "^7.18.9"
+ "@babel/helper-create-class-features-plugin" "^7.19.0"
+ "@babel/helper-plugin-utils" "^7.19.0"
"@babel/plugin-syntax-typescript" "^7.18.6"
"@babel/plugin-transform-unicode-escapes@^7.18.10":
@@ -986,17 +899,17 @@
"@babel/helper-plugin-utils" "^7.18.6"
"@babel/preset-env@^7.18.10", "@babel/preset-env@^7.18.9":
- version "7.18.10"
- resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.18.10.tgz#83b8dfe70d7eea1aae5a10635ab0a5fe60dfc0f4"
- integrity sha512-wVxs1yjFdW3Z/XkNfXKoblxoHgbtUF7/l3PvvP4m02Qz9TZ6uZGxRVYjSQeR87oQmHco9zWitW5J82DJ7sCjvA==
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.19.3.tgz#52cd19abaecb3f176a4ff9cc5e15b7bf06bec754"
+ integrity sha512-ziye1OTc9dGFOAXSWKUqQblYHNlBOaDl8wzqf2iKXJAltYiR3hKHUKmkt+S9PppW7RQpq4fFCrwwpIDj/f5P4w==
dependencies:
- "@babel/compat-data" "^7.18.8"
- "@babel/helper-compilation-targets" "^7.18.9"
- "@babel/helper-plugin-utils" "^7.18.9"
+ "@babel/compat-data" "^7.19.3"
+ "@babel/helper-compilation-targets" "^7.19.3"
+ "@babel/helper-plugin-utils" "^7.19.0"
"@babel/helper-validator-option" "^7.18.6"
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6"
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9"
- "@babel/plugin-proposal-async-generator-functions" "^7.18.10"
+ "@babel/plugin-proposal-async-generator-functions" "^7.19.1"
"@babel/plugin-proposal-class-properties" "^7.18.6"
"@babel/plugin-proposal-class-static-block" "^7.18.6"
"@babel/plugin-proposal-dynamic-import" "^7.18.6"
@@ -1030,9 +943,9 @@
"@babel/plugin-transform-async-to-generator" "^7.18.6"
"@babel/plugin-transform-block-scoped-functions" "^7.18.6"
"@babel/plugin-transform-block-scoping" "^7.18.9"
- "@babel/plugin-transform-classes" "^7.18.9"
+ "@babel/plugin-transform-classes" "^7.19.0"
"@babel/plugin-transform-computed-properties" "^7.18.9"
- "@babel/plugin-transform-destructuring" "^7.18.9"
+ "@babel/plugin-transform-destructuring" "^7.18.13"
"@babel/plugin-transform-dotall-regex" "^7.18.6"
"@babel/plugin-transform-duplicate-keys" "^7.18.9"
"@babel/plugin-transform-exponentiation-operator" "^7.18.6"
@@ -1042,9 +955,9 @@
"@babel/plugin-transform-member-expression-literals" "^7.18.6"
"@babel/plugin-transform-modules-amd" "^7.18.6"
"@babel/plugin-transform-modules-commonjs" "^7.18.6"
- "@babel/plugin-transform-modules-systemjs" "^7.18.9"
+ "@babel/plugin-transform-modules-systemjs" "^7.19.0"
"@babel/plugin-transform-modules-umd" "^7.18.6"
- "@babel/plugin-transform-named-capturing-groups-regex" "^7.18.6"
+ "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.1"
"@babel/plugin-transform-new-target" "^7.18.6"
"@babel/plugin-transform-object-super" "^7.18.6"
"@babel/plugin-transform-parameters" "^7.18.8"
@@ -1052,18 +965,18 @@
"@babel/plugin-transform-regenerator" "^7.18.6"
"@babel/plugin-transform-reserved-words" "^7.18.6"
"@babel/plugin-transform-shorthand-properties" "^7.18.6"
- "@babel/plugin-transform-spread" "^7.18.9"
+ "@babel/plugin-transform-spread" "^7.19.0"
"@babel/plugin-transform-sticky-regex" "^7.18.6"
"@babel/plugin-transform-template-literals" "^7.18.9"
"@babel/plugin-transform-typeof-symbol" "^7.18.9"
"@babel/plugin-transform-unicode-escapes" "^7.18.10"
"@babel/plugin-transform-unicode-regex" "^7.18.6"
"@babel/preset-modules" "^0.1.5"
- "@babel/types" "^7.18.10"
- babel-plugin-polyfill-corejs2 "^0.3.2"
- babel-plugin-polyfill-corejs3 "^0.5.3"
- babel-plugin-polyfill-regenerator "^0.4.0"
- core-js-compat "^3.22.1"
+ "@babel/types" "^7.19.3"
+ babel-plugin-polyfill-corejs2 "^0.3.3"
+ babel-plugin-polyfill-corejs3 "^0.6.0"
+ babel-plugin-polyfill-regenerator "^0.4.1"
+ core-js-compat "^3.25.1"
semver "^6.3.0"
"@babel/preset-modules@^0.1.5":
@@ -1099,35 +1012,21 @@
"@babel/plugin-transform-typescript" "^7.18.6"
"@babel/runtime-corejs3@^7.9.2":
- version "7.14.7"
- resolved "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.7.tgz"
- integrity sha512-Wvzcw4mBYbTagyBVZpAJWI06auSIj033T/yNE0Zn1xcup83MieCddZA7ls3kme17L4NOGBrQ09Q+nKB41RLWBA==
+ version "7.19.1"
+ resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.19.1.tgz#f0cbbe7edda7c4109cd253bb1dee99aba4594ad9"
+ integrity sha512-j2vJGnkopRzH+ykJ8h68wrHnEUmtK//E723jjixiAl/PPf6FhqY/vYRcMVlNydRKQjQsTsYEjpx+DZMIvnGk/g==
dependencies:
- core-js-pure "^3.15.0"
+ core-js-pure "^3.25.1"
regenerator-runtime "^0.13.4"
-"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.15.4", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
- version "7.18.9"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a"
- integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==
+"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.15.4", "@babel/runtime@^7.18.3", "@babel/runtime@^7.2.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259"
+ integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==
dependencies:
regenerator-runtime "^0.13.4"
-"@babel/runtime@^7.1.2":
- version "7.14.0"
- resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz"
- integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==
- dependencies:
- regenerator-runtime "^0.13.4"
-
-"@babel/runtime@^7.2.0":
- version "7.14.5"
- resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.5.tgz"
- integrity sha512-121rumjddw9c3NCQ55KGkyE1h/nzWhU/owjhw0l4mQrkzz4x9SGS1X8gFLraHwX7td3Yo4QTL+qj0NcIzN87BA==
- dependencies:
- regenerator-runtime "^0.13.4"
-
-"@babel/template@^7.16.7", "@babel/template@^7.18.10", "@babel/template@^7.18.6", "@babel/template@^7.3.3":
+"@babel/template@^7.18.10", "@babel/template@^7.3.3":
version "7.18.10"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71"
integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==
@@ -1136,53 +1035,29 @@
"@babel/parser" "^7.18.10"
"@babel/types" "^7.18.10"
-"@babel/traverse@^7.18.0", "@babel/traverse@^7.18.2", "@babel/traverse@^7.18.5":
- version "7.18.5"
- resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.5.tgz"
- integrity sha512-aKXj1KT66sBj0vVzk6rEeAO6Z9aiiQ68wfDgge3nHhA/my6xMM/7HGQUNumKZaoa2qUPQ5whJG9aAifsxUKfLA==
- dependencies:
- "@babel/code-frame" "^7.16.7"
- "@babel/generator" "^7.18.2"
- "@babel/helper-environment-visitor" "^7.18.2"
- "@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.18.5"
- "@babel/types" "^7.18.4"
- debug "^4.1.0"
- globals "^11.1.0"
-
-"@babel/traverse@^7.18.11", "@babel/traverse@^7.18.13", "@babel/traverse@^7.18.9", "@babel/traverse@^7.7.2":
- version "7.18.13"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.13.tgz#5ab59ef51a997b3f10c4587d648b9696b6cb1a68"
- integrity sha512-N6kt9X1jRMLPxxxPYWi7tgvJRH/rtoU+dbKAPDM44RFHiMH8igdsaSBgFeskhSl/kLWLDUvIh1RXCrTmg0/zvA==
+"@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.19.3", "@babel/traverse@^7.7.2":
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.3.tgz#3a3c5348d4988ba60884e8494b0592b2f15a04b4"
+ integrity sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==
dependencies:
"@babel/code-frame" "^7.18.6"
- "@babel/generator" "^7.18.13"
+ "@babel/generator" "^7.19.3"
"@babel/helper-environment-visitor" "^7.18.9"
- "@babel/helper-function-name" "^7.18.9"
+ "@babel/helper-function-name" "^7.19.0"
"@babel/helper-hoist-variables" "^7.18.6"
"@babel/helper-split-export-declaration" "^7.18.6"
- "@babel/parser" "^7.18.13"
- "@babel/types" "^7.18.13"
+ "@babel/parser" "^7.19.3"
+ "@babel/types" "^7.19.3"
debug "^4.1.0"
globals "^11.1.0"
-"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.13", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
- version "7.18.13"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.13.tgz#30aeb9e514f4100f7c1cb6e5ba472b30e48f519a"
- integrity sha512-ePqfTihzW0W6XAU+aMw2ykilisStJfDnsejDCXRchCcMJ4O0+8DhPXf2YUbZ6wjBlsEmZwLK/sPweWtu8hcJYQ==
+"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.19.3", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.3.tgz#fc420e6bbe54880bce6779ffaf315f5e43ec9624"
+ integrity sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw==
dependencies:
"@babel/helper-string-parser" "^7.18.10"
- "@babel/helper-validator-identifier" "^7.18.6"
- to-fast-properties "^2.0.0"
-
-"@babel/types@^7.17.0", "@babel/types@^7.18.0", "@babel/types@^7.18.2", "@babel/types@^7.18.4":
- version "7.18.4"
- resolved "https://registry.npmjs.org/@babel/types/-/types-7.18.4.tgz"
- integrity sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==
- dependencies:
- "@babel/helper-validator-identifier" "^7.16.7"
+ "@babel/helper-validator-identifier" "^7.19.1"
to-fast-properties "^2.0.0"
"@bcoe/v8-coverage@^0.2.3":
@@ -1324,14 +1199,15 @@
hoist-non-react-statics "^3.3.1"
"@emotion/react@^11.8.1":
- version "11.10.0"
- resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.0.tgz#53c577f063f26493f68a05188fb87528d912ff2e"
- integrity sha512-K6z9zlHxxBXwN8TcpwBKcEsBsOw4JWCCmR+BeeOWgqp8GIU1yA2Odd41bwdAAr0ssbQrbJbVnndvv7oiv1bZeQ==
+ version "11.10.4"
+ resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.4.tgz#9dc6bccbda5d70ff68fdb204746c0e8b13a79199"
+ integrity sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==
dependencies:
"@babel/runtime" "^7.18.3"
"@emotion/babel-plugin" "^11.10.0"
"@emotion/cache" "^11.10.0"
"@emotion/serialize" "^1.1.0"
+ "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0"
"@emotion/utils" "^1.2.0"
"@emotion/weak-memoize" "^0.3.0"
hoist-non-react-statics "^3.3.1"
@@ -1357,6 +1233,11 @@
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.0.tgz#a4a36e9cbdc6903737cd20d38033241e1b8833db"
integrity sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==
+"@emotion/use-insertion-effect-with-fallbacks@^1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz#ffadaec35dbb7885bd54de3fa267ab2f860294df"
+ integrity sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==
+
"@emotion/utils@^1.0.0", "@emotion/utils@^1.1.0", "@emotion/utils@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.0.tgz#9716eaccbc6b5ded2ea5a90d65562609aab0f561"
@@ -1381,14 +1262,23 @@
esquery "^1.4.0"
jsdoc-type-pratt-parser "~2.2.5"
+"@es-joy/jsdoccomment@~0.33.0":
+ version "0.33.0"
+ resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.33.0.tgz#59416d08442d0fdbb316fc1cb491e750db80b9ad"
+ integrity sha512-bkxMGTlHPE4vfarXt1L1fOm81O18jTRFNgh3Fm4iPKctfWxcpJw4cpth5BhLkGZy4HFzGn/KfD/zGks/J+ZIIw==
+ dependencies:
+ comment-parser "1.3.1"
+ esquery "^1.4.0"
+ jsdoc-type-pratt-parser "~3.1.0"
+
"@eslint/eslintrc@^1.2.1", "@eslint/eslintrc@^1.3.0":
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f"
- integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.2.tgz#58b69582f3b7271d8fa67fe5251767a5b38ea356"
+ integrity sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==
dependencies:
ajv "^6.12.4"
debug "^4.3.2"
- espree "^9.3.2"
+ espree "^9.4.0"
globals "^13.15.0"
ignore "^5.2.0"
import-fresh "^3.2.1"
@@ -1396,12 +1286,27 @@
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
-"@formatjs/ecma402-abstract@1.11.10":
- version "1.11.10"
- resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.10.tgz#1b61909ce069d1fa62bafb163aaff59d524c094d"
- integrity sha512-v8nuQpx6pc0xzg4VMCXPWesFx8PxBysdF7q1CGEoet0X9nhbGPGNq0SC+D9g+Kh0pWWITidlEYsepLF7lb8Tqw==
+"@eslint/eslintrc@^1.3.3":
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95"
+ integrity sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==
dependencies:
- "@formatjs/intl-localematcher" "0.2.30"
+ ajv "^6.12.4"
+ debug "^4.3.2"
+ espree "^9.4.0"
+ globals "^13.15.0"
+ ignore "^5.2.0"
+ import-fresh "^3.2.1"
+ js-yaml "^4.1.0"
+ minimatch "^3.1.2"
+ strip-json-comments "^3.1.1"
+
+"@formatjs/ecma402-abstract@1.12.0":
+ version "1.12.0"
+ resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.12.0.tgz#2fb5e8983d5fae2fad9ec6c77aec1803c2b88d8e"
+ integrity sha512-0/wm9b7brUD40kx7KSE0S532T8EfH06Zc41rGlinoNyYXnuusR6ull2x63iFJgVXgwahm42hAW7dcYdZ+llZzA==
+ dependencies:
+ "@formatjs/intl-localematcher" "0.2.31"
tslib "2.4.0"
"@formatjs/fast-memoize@1.2.6":
@@ -1411,27 +1316,27 @@
dependencies:
tslib "2.4.0"
-"@formatjs/icu-messageformat-parser@2.1.6":
- version "2.1.6"
- resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.1.6.tgz#b5caf89a6211849c156bcebf95e836dc8758d50f"
- integrity sha512-f7jeuomhWzHIAMcH8hGyTdPrKml+yAKKtax5Tks56+5+nT7rdzCOyi/l/F5g0bN33PcnFB/eI9cW/CP0FNezig==
+"@formatjs/icu-messageformat-parser@2.1.8":
+ version "2.1.8"
+ resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.1.8.tgz#45cb678da4c760009b52fe6ca2c13aedbc200fee"
+ integrity sha512-T1R/UtPSCdznwjlfIJDl9XnjZdcFap+rPJrKC9uATr/sUdziVad3SfRQFf50JOuHptbk6knz+VdiYdApek4Sag==
dependencies:
- "@formatjs/ecma402-abstract" "1.11.10"
- "@formatjs/icu-skeleton-parser" "1.3.12"
+ "@formatjs/ecma402-abstract" "1.12.0"
+ "@formatjs/icu-skeleton-parser" "1.3.13"
tslib "2.4.0"
-"@formatjs/icu-skeleton-parser@1.3.12":
- version "1.3.12"
- resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.12.tgz#3c960424c982e852f6b62aed8f80b2f75f23acc9"
- integrity sha512-RHf5mi9dUaZIUteuWbK398FV1CkJOIezIubdiD+xEOPHb37ZvjXtwolCiCVVIWHDIeBBqxxAhnzdSFBS3CXfRg==
+"@formatjs/icu-skeleton-parser@1.3.13":
+ version "1.3.13"
+ resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.13.tgz#f7e186e72ed73c3272d22a3aacb646e77368b099"
+ integrity sha512-qb1kxnA4ep76rV+d9JICvZBThBpK5X+nh1dLmmIReX72QyglicsaOmKEcdcbp7/giCWfhVs6CXPVA2JJ5/ZvAw==
dependencies:
- "@formatjs/ecma402-abstract" "1.11.10"
+ "@formatjs/ecma402-abstract" "1.12.0"
tslib "2.4.0"
-"@formatjs/intl-localematcher@0.2.30":
- version "0.2.30"
- resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.2.30.tgz#1b8a5460768e87ee69ef3b12aceecbecb61f447c"
- integrity sha512-No+D8Q8rlzEMfoKkJ1tk81aphZuAk7ZwY+Vkzbb1TOvlP67TM/YPxdf4JoiUV/Q2GRqdGhaLfgulqIf9ATKHTA==
+"@formatjs/intl-localematcher@0.2.31":
+ version "0.2.31"
+ resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.2.31.tgz#aada2b1e58211460cedba56889e3c489117eb6eb"
+ integrity sha512-9QTjdSBpQ7wHShZgsNzNig5qT3rCPvmZogS/wXZzKotns5skbXgs0I7J8cuN0PPqXyynvNVuN+iOKhNS2eb+ZA==
dependencies:
tslib "2.4.0"
@@ -1454,13 +1359,13 @@
ua-parser-js "^1.0.2"
web-vitals "^2.1.4"
-"@grafana/data@9.1.1", "@grafana/data@^9.1.1":
- version "9.1.1"
- resolved "https://registry.yarnpkg.com/@grafana/data/-/data-9.1.1.tgz#342af5824359ae6f8b4f1bcc1ebb2ae3fb3e4d37"
- integrity sha512-DO2Ry97iGbpnJCwz1yA6yQgp34Diaan34t9zXJXGdEFNZ72hbKAtoDxo6X03QTynMtrB0AJcsDIYmSUAkeZQog==
+"@grafana/data@9.1.7", "@grafana/data@^9.1.1":
+ version "9.1.7"
+ resolved "https://registry.yarnpkg.com/@grafana/data/-/data-9.1.7.tgz#8d340b3dd74483e2de0d01b04b0b01f239117cad"
+ integrity sha512-Car35fxROtKJeZ09qYBE8Vy3qGDxuX8V/wilFmgiAqoELbR9WVxM//jOASuxp84xmTnpgmlWjhBLZztqIZ3l+A==
dependencies:
"@braintree/sanitize-url" "6.0.0"
- "@grafana/schema" "9.1.1"
+ "@grafana/schema" "9.1.7"
"@types/d3-interpolate" "^1.4.0"
d3-interpolate "1.4.0"
date-fns "2.29.1"
@@ -1479,10 +1384,10 @@
uplot "1.6.22"
xss "1.0.13"
-"@grafana/e2e-selectors@9.1.1":
- version "9.1.1"
- resolved "https://registry.yarnpkg.com/@grafana/e2e-selectors/-/e2e-selectors-9.1.1.tgz#acd53200f7c6f7f831266434cf9d61b2dc0580bd"
- integrity sha512-2y0Sb3sDYn/3iuYQmjI8Aae6vWY12vwDwZFMbgvWZW1/Bnn8YqEyYu0LyIV6QWdoLfAjre/7KPYzja2fjM8uZQ==
+"@grafana/e2e-selectors@9.1.7":
+ version "9.1.7"
+ resolved "https://registry.yarnpkg.com/@grafana/e2e-selectors/-/e2e-selectors-9.1.7.tgz#dc6834cae381e19b31317d9e5c101fd516845050"
+ integrity sha512-cDmH43v6D5hftxbRrfHobKVjulanXLl/wNn1i3tbWIAceIcqlv5xIUvZPmyGWa5va5pN471ue1owDfFR1uFyiA==
dependencies:
"@grafana/tsconfig" "^1.2.0-rc1"
tslib "2.4.0"
@@ -1502,15 +1407,29 @@
eslint-plugin-react-hooks "4.3.0"
typescript "4.6.4"
+"@grafana/eslint-config@^5.0.0":
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/@grafana/eslint-config/-/eslint-config-5.0.0.tgz#e08a89d378772340bc6cd1872ec4d15666269aba"
+ integrity sha512-8kJ95KYyeSBjucdu9R4qem8ik6s3LdCRxC2cfub9vSngzUyQIwPpXbLlWr9FrpZcmP5NiZBB15FhpW/FxjYbQQ==
+ dependencies:
+ "@typescript-eslint/eslint-plugin" "5.16.0"
+ "@typescript-eslint/parser" "5.16.0"
+ eslint "8.11.0"
+ eslint-config-prettier "8.5.0"
+ eslint-plugin-jsdoc "38.0.6"
+ eslint-plugin-react "7.29.4"
+ eslint-plugin-react-hooks "4.3.0"
+ typescript "4.6.4"
+
"@grafana/runtime@^9.1.1":
- version "9.1.1"
- resolved "https://registry.yarnpkg.com/@grafana/runtime/-/runtime-9.1.1.tgz#412ad5d087b72f1b7a21776c2e6fbcbc6483e61f"
- integrity sha512-vr+F3921J3XczGgCH0/TiQ/k8NHtFLIK+5rMXpEZZiX9tNGI55DeWhKcQ6c9pIF73vkglvSiUl8ixsnydi1S/Q==
+ version "9.1.7"
+ resolved "https://registry.yarnpkg.com/@grafana/runtime/-/runtime-9.1.7.tgz#b4081852e94e398defd0a16cfe74f77a47e00d35"
+ integrity sha512-OeJFNh4ZPkTdFL+64gUzzLKPRn0OjtTVOFV5MTv33Bl52mVyVrHWFwMGOtKmzY+qCALvEcv4G5s19eTkY2Picw==
dependencies:
"@grafana/agent-web" "^0.4.0"
- "@grafana/data" "9.1.1"
- "@grafana/e2e-selectors" "9.1.1"
- "@grafana/ui" "9.1.1"
+ "@grafana/data" "9.1.7"
+ "@grafana/e2e-selectors" "9.1.7"
+ "@grafana/ui" "9.1.7"
"@sentry/browser" "6.19.7"
history "4.10.1"
lodash "4.17.21"
@@ -1520,10 +1439,10 @@
systemjs "0.20.19"
tslib "2.4.0"
-"@grafana/schema@9.1.1":
- version "9.1.1"
- resolved "https://registry.yarnpkg.com/@grafana/schema/-/schema-9.1.1.tgz#ece11c4c0adad15b66fe63854ea76011e7e1202a"
- integrity sha512-gEsnoqemRvPVZkaHYWvZt3vfvhS4nxENQjpJlIkzCa04iWVJpHu/j0lylPVtFAg8YXY8AyIK1ECWqwnb2ANfCw==
+"@grafana/schema@9.1.7":
+ version "9.1.7"
+ resolved "https://registry.yarnpkg.com/@grafana/schema/-/schema-9.1.7.tgz#9d549efb722905db5b22057506c55e757a83398a"
+ integrity sha512-B40i+zYfnfF1sdfHn8sZ7uUxFKCXqljnV64DKvCtX3kXKshwkLjj71SI0qQGbsq8Ceq65yvGFVe0iYDFzRB4lA==
dependencies:
tslib "2.4.0"
@@ -1550,9 +1469,9 @@
tiny-warning "^0.0.3"
"@grafana/toolkit@^9.1.1":
- version "9.1.1"
- resolved "https://registry.yarnpkg.com/@grafana/toolkit/-/toolkit-9.1.1.tgz#0f75b8977a498e9f502ad3b5fd40c9d653b6b5f9"
- integrity sha512-i7Dr9VcLFdXO8j6QnoZdropW1d7nh0TiKVs9FCdTgcwsSmxTJ7g3h1vvTCilnL0zOjU3UsZsvRThGaIMQixcBw==
+ version "9.1.7"
+ resolved "https://registry.yarnpkg.com/@grafana/toolkit/-/toolkit-9.1.7.tgz#3f4da553de7fd23685294cf1d2e513cc73d018b9"
+ integrity sha512-vwCzjVouOBJ9UsdQrg82nCVN1iszXh+VcQoONR3uCVWwLc3vYniV9Dt88vI/xfUUxVLopLjBZhR9uddwnf3C0g==
dependencies:
"@babel/core" "^7.18.9"
"@babel/plugin-proposal-class-properties" "7.18.6"
@@ -1566,10 +1485,10 @@
"@babel/preset-env" "^7.18.9"
"@babel/preset-react" "^7.18.6"
"@babel/preset-typescript" "^7.18.6"
- "@grafana/data" "9.1.1"
+ "@grafana/data" "9.1.7"
"@grafana/eslint-config" "^4.0.0"
"@grafana/tsconfig" "^1.2.0-rc1"
- "@grafana/ui" "9.1.1"
+ "@grafana/ui" "9.1.7"
"@jest/core" "27.5.1"
"@types/command-exists" "^1.2.0"
"@types/eslint" "8.4.1"
@@ -1646,16 +1565,16 @@
resolved "https://registry.yarnpkg.com/@grafana/tsconfig/-/tsconfig-1.2.0-rc1.tgz#10973c978ec95b0ea637511254b5f478bce04de7"
integrity sha512-+SgQeBQ1pT6D/E3/dEdADqTrlgdIGuexUZ8EU+8KxQFKUeFeU7/3z/ayI2q/wpJ/Kr6WxBBNlrST6aOKia19Ag==
-"@grafana/ui@9.1.1", "@grafana/ui@^9.1.1":
- version "9.1.1"
- resolved "https://registry.yarnpkg.com/@grafana/ui/-/ui-9.1.1.tgz#b9778cb7db70ea4fe70836461f1e53873ae0e0b6"
- integrity sha512-jfZfke4THg35wPl8Y9vrssNwkv3q9a2gsJ2tVv0ZqFEnJl2RVnG2csw72hAtAyqTs/lykOyb8IM9kE6AlPxtKQ==
+"@grafana/ui@9.1.7", "@grafana/ui@^9.1.1":
+ version "9.1.7"
+ resolved "https://registry.yarnpkg.com/@grafana/ui/-/ui-9.1.7.tgz#b083a63f09638f2c7dabbbcb8a58b8040b889ca0"
+ integrity sha512-W9YsNbi9veZzxzD1kPLBXiSXTxbU70LgGpT30aTkXpSrh/9Ng/mg/ABJJ0sEOF/sfCFhl2R7eJ34REuueTcX7A==
dependencies:
"@emotion/css" "11.9.0"
"@emotion/react" "11.9.3"
- "@grafana/data" "9.1.1"
- "@grafana/e2e-selectors" "9.1.1"
- "@grafana/schema" "9.1.1"
+ "@grafana/data" "9.1.7"
+ "@grafana/e2e-selectors" "9.1.7"
+ "@grafana/schema" "9.1.7"
"@grafana/slate-react" "0.22.10-grafana"
"@monaco-editor/react" "4.3.1"
"@popperjs/core" "2.11.5"
@@ -1707,13 +1626,23 @@
react-use "17.4.0"
react-window "1.8.7"
rxjs "7.5.6"
- slate "0.47.8"
- slate-plain-serializer "0.7.10"
+ slate "0.47.9"
+ slate-plain-serializer "0.7.11"
+ slate-react "0.22.10"
tinycolor2 "1.4.2"
tslib "2.4.0"
uplot "1.6.22"
uuid "8.3.2"
+"@humanwhocodes/config-array@^0.10.5":
+ version "0.10.7"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.7.tgz#6d53769fd0c222767e6452e8ebda825c22e9f0dc"
+ integrity sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==
+ dependencies:
+ "@humanwhocodes/object-schema" "^1.2.1"
+ debug "^4.1.1"
+ minimatch "^3.0.4"
+
"@humanwhocodes/config-array@^0.9.2":
version "0.9.5"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7"
@@ -1723,6 +1652,11 @@
debug "^4.1.1"
minimatch "^3.0.4"
+"@humanwhocodes/module-importer@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
+ integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
+
"@humanwhocodes/object-schema@^1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
@@ -1829,6 +1763,13 @@
"@types/node" "*"
jest-mock "^27.5.1"
+"@jest/expect-utils@^29.1.2":
+ version "29.1.2"
+ resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.1.2.tgz#66dbb514d38f7d21456bc774419c9ae5cca3f88d"
+ integrity sha512-4a48bhKfGj/KAH39u0ppzNTABXQ8QPccWAFUFobWBaEMSMp+sB31Z2fK/l47c4a/Mu1po2ffmfAIPxXbVTXdtg==
+ dependencies:
+ jest-get-type "^29.0.0"
+
"@jest/fake-timers@^27.5.1":
version "27.5.1"
resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74"
@@ -1881,6 +1822,13 @@
terminal-link "^2.0.0"
v8-to-istanbul "^8.1.0"
+"@jest/schemas@^29.0.0":
+ version "29.0.0"
+ resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.0.0.tgz#5f47f5994dd4ef067fb7b4188ceac45f77fe952a"
+ integrity sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==
+ dependencies:
+ "@sinclair/typebox" "^0.24.1"
+
"@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"
@@ -1942,24 +1890,27 @@
"@types/yargs" "^16.0.0"
chalk "^4.0.0"
+"@jest/types@^29.1.2":
+ version "29.1.2"
+ resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.1.2.tgz#7442d32b16bcd7592d9614173078b8c334ec730a"
+ integrity sha512-DcXGtoTykQB5jiwCmVr8H4vdg2OJhQex3qPkG+ISyDO7xQXbt/4R6dowcRyPemRnkH7JoHvZuxPBdlq+9JxFCg==
+ dependencies:
+ "@jest/schemas" "^29.0.0"
+ "@types/istanbul-lib-coverage" "^2.0.0"
+ "@types/istanbul-reports" "^3.0.0"
+ "@types/node" "*"
+ "@types/yargs" "^17.0.8"
+ chalk "^4.0.0"
+
"@jridgewell/gen-mapping@^0.1.0":
version "0.1.1"
- resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz"
+ 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/gen-mapping@^0.3.0":
- version "0.3.1"
- resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz"
- integrity sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==
- dependencies:
- "@jridgewell/set-array" "^1.0.0"
- "@jridgewell/sourcemap-codec" "^1.4.10"
- "@jridgewell/trace-mapping" "^0.3.9"
-
-"@jridgewell/gen-mapping@^0.3.2":
+"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2":
version "0.3.2"
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9"
integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==
@@ -1969,16 +1920,11 @@
"@jridgewell/trace-mapping" "^0.3.9"
"@jridgewell/resolve-uri@^3.0.3":
- version "3.0.7"
- resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz"
- integrity sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
+ integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
-"@jridgewell/set-array@^1.0.0":
- version "1.1.1"
- resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz"
- integrity sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==
-
-"@jridgewell/set-array@^1.0.1":
+"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
@@ -1992,11 +1938,11 @@
"@jridgewell/trace-mapping" "^0.3.9"
"@jridgewell/sourcemap-codec@^1.4.10":
- version "1.4.13"
- resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz"
- integrity sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==
+ version "1.4.14"
+ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
+ integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
-"@jridgewell/trace-mapping@^0.3.14":
+"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.9":
version "0.3.15"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774"
integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==
@@ -2004,14 +1950,6 @@
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
-"@jridgewell/trace-mapping@^0.3.9":
- version "0.3.13"
- resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz"
- integrity sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==
- dependencies:
- "@jridgewell/resolve-uri" "^3.0.3"
- "@jridgewell/sourcemap-codec" "^1.4.10"
-
"@kwsites/file-exists@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@kwsites/file-exists/-/file-exists-1.1.1.tgz#ad1efcac13e1987d8dbaf235ef3be5b0d96faa99"
@@ -2097,9 +2035,9 @@
"@opentelemetry/api" "^1.0.0"
"@opentelemetry/api@^1.0.0", "@opentelemetry/api@^1.1.0":
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.1.0.tgz#563539048255bbe1a5f4f586a4a10a1bb737f44a"
- integrity sha512-hf+3bwuBwtXsugA2ULBc95qxrOqP2pOekLz34BJhcAKawt94vfeNyUKpYc0lZQ/3sCP6LqRa7UAdHA7i5UODzQ==
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686"
+ integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g==
"@opentelemetry/core@1.3.1":
version "1.3.1"
@@ -2156,10 +2094,10 @@
resolved "https://registry.yarnpkg.com/@petamoriken/float16/-/float16-3.6.6.tgz#641f73913a6be402b34e4bdfca98d6832ed55586"
integrity sha512-3MUulwMtsdCA9lw8a/Kc0XDBJJVCkYTQ5aGd+///TbfkOMXoOGAzzoiYKwPEsLYZv7He7fKJ/mCacqKOO7REyg==
-"@polka/url@^1.0.0-next.15":
- version "1.0.0-next.15"
- resolved "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.15.tgz"
- integrity sha512-15spi3V28QdevleWBNXE4pIls3nFZmBbUGrW9IVPwiQczuSb9n76TCB4bsk8TSel+I1OkHEdPhu5QKMfY6rQHA==
+"@polka/url@^1.0.0-next.20":
+ version "1.0.0-next.21"
+ resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1"
+ integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==
"@popperjs/core@2.11.5":
version "2.11.5"
@@ -2205,21 +2143,21 @@
"@react-types/shared" "^3.13.1"
clsx "^1.1.1"
-"@react-aria/focus@^3.6.1", "@react-aria/focus@^3.7.0":
- version "3.7.0"
- resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.7.0.tgz#6a90dc99da64bd145e3eeacf3097a29a0342f709"
- integrity sha512-LydZSLBLEUklakM0Ogdk17F3f/Uwaj5Nl1mfcK8HhrroGT8A8XH0KjA9D6gM6JGHgxZemx0ufOgxhQZeBGQMQw==
+"@react-aria/focus@^3.6.1", "@react-aria/focus@^3.9.0":
+ version "3.9.0"
+ resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.9.0.tgz#fa4478eebdc3c199a0529470f1d7b36608ef0d10"
+ integrity sha512-DwesjEjWjFfwAwzv9qeqkyKZNPAYmPa3UrygxzmXeKEg2JpaACGZPxRcmT2EFJFEDbX8daQDEeRGyLO49o5agg==
dependencies:
"@babel/runtime" "^7.6.2"
- "@react-aria/interactions" "^3.10.0"
- "@react-aria/utils" "^3.13.2"
- "@react-types/shared" "^3.14.0"
+ "@react-aria/interactions" "^3.12.0"
+ "@react-aria/utils" "^3.14.0"
+ "@react-types/shared" "^3.15.0"
clsx "^1.1.1"
-"@react-aria/i18n@^3.4.1", "@react-aria/i18n@^3.5.0":
- version "3.5.1"
- resolved "https://registry.yarnpkg.com/@react-aria/i18n/-/i18n-3.5.1.tgz#aba5e50266a3f15c195b8dc85682251af5c52211"
- integrity sha512-PtlQ/W1PXVKzCGK86MuGuCzYBwENDBjrQ2a4ux+BBQ2Dk8ZXEARSp9JaMFuOdiloXc/p4FoxCVoB+lhu4RCScg==
+"@react-aria/i18n@^3.4.1", "@react-aria/i18n@^3.6.1":
+ version "3.6.1"
+ resolved "https://registry.yarnpkg.com/@react-aria/i18n/-/i18n-3.6.1.tgz#b97e78e3ec040a5ca08d166033f2d358ef1af4c5"
+ integrity sha512-kAetWsj9HOqwaqLhmFU2udhZ+4QGGYkQOgGBJYdrB7GfLZQ1GPBlZjv3QFdkX4oSf/k9cFqgftxvVQQDYZLOew==
dependencies:
"@babel/runtime" "^7.6.2"
"@internationalized/date" "^3.0.1"
@@ -2227,17 +2165,17 @@
"@internationalized/number" "^3.1.1"
"@internationalized/string" "^3.0.0"
"@react-aria/ssr" "^3.3.0"
- "@react-aria/utils" "^3.13.2"
- "@react-types/shared" "^3.14.0"
+ "@react-aria/utils" "^3.14.0"
+ "@react-types/shared" "^3.15.0"
-"@react-aria/interactions@^3.10.0", "@react-aria/interactions@^3.9.1":
- version "3.10.0"
- resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.10.0.tgz#d60cc42c3904c1578f9c356fba4bab7003102dee"
- integrity sha512-Lp74VfF+EskT3IqK2MBMdJpJU48p60+YkMbgtoDF6LudNO8jw0nxcsvnimPriTSkZWINRpajG/9sIa0EIDcQKw==
+"@react-aria/interactions@^3.12.0", "@react-aria/interactions@^3.9.1":
+ version "3.12.0"
+ resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.12.0.tgz#b16a392c3dc23351c8fd33a16cef0ef93dc4682d"
+ integrity sha512-KcKurjPZwme9ggvGQjbjqZtZtuyXipTBVMHUah9a3+Dz7vXxhRg5vFaEdM79oQnNsrGFW5xS6SKBehl/JG6BMw==
dependencies:
"@babel/runtime" "^7.6.2"
- "@react-aria/utils" "^3.13.2"
- "@react-types/shared" "^3.14.0"
+ "@react-aria/utils" "^3.14.0"
+ "@react-types/shared" "^3.15.0"
"@react-aria/menu@3.5.1":
version "3.5.1"
@@ -2275,34 +2213,35 @@
react-transition-group "^4.4.2"
"@react-aria/overlays@^3.9.1":
- version "3.10.0"
- resolved "https://registry.yarnpkg.com/@react-aria/overlays/-/overlays-3.10.0.tgz#e702961d178992b9c25db808edd1646efa1d00ec"
- integrity sha512-A7aI59/o4tUAISjyyRfJz3833SLe4ZKPNoxOVUzgjfkfnCKq7YDSSEC5poxDqYD9bq/NBXK6stdgaGLXQSirNw==
+ version "3.11.0"
+ resolved "https://registry.yarnpkg.com/@react-aria/overlays/-/overlays-3.11.0.tgz#9ecab7fbaf88b7c315215d55a3eb1ae1aa5b78f2"
+ integrity sha512-NqLqxSiEW9AuUPcEHCIp2lHH1moNxlkP0CkuUMkT2/T5MCPm/Iq+uD53VSR+NyeCWU/aGH3ykj2kq9NSITJkOA==
dependencies:
"@babel/runtime" "^7.6.2"
- "@react-aria/i18n" "^3.5.0"
- "@react-aria/interactions" "^3.10.0"
+ "@react-aria/focus" "^3.9.0"
+ "@react-aria/i18n" "^3.6.1"
+ "@react-aria/interactions" "^3.12.0"
"@react-aria/ssr" "^3.3.0"
- "@react-aria/utils" "^3.13.2"
- "@react-aria/visually-hidden" "^3.4.0"
- "@react-stately/overlays" "^3.4.0"
- "@react-types/button" "^3.6.0"
- "@react-types/overlays" "^3.6.2"
- "@react-types/shared" "^3.14.0"
+ "@react-aria/utils" "^3.14.0"
+ "@react-aria/visually-hidden" "^3.5.0"
+ "@react-stately/overlays" "^3.4.2"
+ "@react-types/button" "^3.6.2"
+ "@react-types/overlays" "^3.6.4"
+ "@react-types/shared" "^3.15.0"
"@react-aria/selection@^3.9.1":
- version "3.10.0"
- resolved "https://registry.yarnpkg.com/@react-aria/selection/-/selection-3.10.0.tgz#c7c0441d9b496df6567af1c4462e4a80f97ea359"
- integrity sha512-VvFgNRrM0kK6aqyMTeTN+pguyvYN9Wu3viftnZyk89uo2+9hfmU7DLhz5kXkdJY9UNzn033jYGwJdWEuqRq65g==
+ version "3.11.0"
+ resolved "https://registry.yarnpkg.com/@react-aria/selection/-/selection-3.11.0.tgz#5d3457e9ea2a5aae4f8abf799da92c723d04172d"
+ integrity sha512-2Qcv0PxXqOrYYT1oL+TOaB+lE/jhIPzVEPHVmf8HYzEMP5WBYP8Q+R9no5s8x++b1W0DsbUVwmk9szY48O9Bmw==
dependencies:
"@babel/runtime" "^7.6.2"
- "@react-aria/focus" "^3.7.0"
- "@react-aria/i18n" "^3.5.0"
- "@react-aria/interactions" "^3.10.0"
- "@react-aria/utils" "^3.13.2"
- "@react-stately/collections" "^3.4.2"
- "@react-stately/selection" "^3.10.2"
- "@react-types/shared" "^3.14.0"
+ "@react-aria/focus" "^3.9.0"
+ "@react-aria/i18n" "^3.6.1"
+ "@react-aria/interactions" "^3.12.0"
+ "@react-aria/utils" "^3.14.0"
+ "@react-stately/collections" "^3.4.4"
+ "@react-stately/selection" "^3.11.0"
+ "@react-types/shared" "^3.15.0"
"@react-aria/ssr@^3.2.0", "@react-aria/ssr@^3.3.0":
version "3.3.0"
@@ -2322,35 +2261,35 @@
"@react-types/shared" "^3.13.1"
clsx "^1.1.1"
-"@react-aria/utils@^3.13.1", "@react-aria/utils@^3.13.2":
- version "3.13.2"
- resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.13.2.tgz#c28bc96e940a8a84c3e69a19f483c9f060584580"
- integrity sha512-VTI8tv9m/BxE/lPTNCZN1fcHuY540xm+HT1vg2ZQCryudUWvzQkHi+h0z32DhiGHhvRFIGdH/enf3psip7ZLTQ==
+"@react-aria/utils@^3.13.1", "@react-aria/utils@^3.14.0":
+ version "3.14.0"
+ resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.14.0.tgz#87877e89e959c8b6299da953ec3a7167de2192c3"
+ integrity sha512-DHgmwNBNEhnb6DEYYAfbt99wprBqJJOBBeIpQ2g3+pxwlw4BZ+v4Qr+rDD0ZibWV0mYzt8zOhZ9StpId7iTF0Q==
dependencies:
"@babel/runtime" "^7.6.2"
"@react-aria/ssr" "^3.3.0"
"@react-stately/utils" "^3.5.1"
- "@react-types/shared" "^3.14.0"
+ "@react-types/shared" "^3.15.0"
clsx "^1.1.1"
-"@react-aria/visually-hidden@^3.3.1", "@react-aria/visually-hidden@^3.4.0":
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/@react-aria/visually-hidden/-/visually-hidden-3.4.0.tgz#9422ba67296969b5eae3e8e8839ba50e8acc0990"
- integrity sha512-mRl4Vfg7F0ohf7N3RWdOQLUnXC4ApM3hsfBegsRQHDkbbrcq7MGPyCa154kIZg8Ff2cOtbgvrAlymzWmkOVZEQ==
+"@react-aria/visually-hidden@^3.3.1", "@react-aria/visually-hidden@^3.5.0":
+ version "3.5.0"
+ resolved "https://registry.yarnpkg.com/@react-aria/visually-hidden/-/visually-hidden-3.5.0.tgz#aa8669545464cdb6a4b2ba47c9695d1405864a06"
+ integrity sha512-tF/kCZCGv1yebwgH21cKbhjSV5CmB5/SAHOUM5YkO5V/lIFjaPtywcamIPI8F0JSfrwGF/Z9EqvqBxvIYGRlCA==
dependencies:
"@babel/runtime" "^7.6.2"
- "@react-aria/interactions" "^3.10.0"
- "@react-aria/utils" "^3.13.2"
- "@react-types/shared" "^3.14.0"
+ "@react-aria/interactions" "^3.12.0"
+ "@react-aria/utils" "^3.14.0"
+ "@react-types/shared" "^3.15.0"
clsx "^1.1.1"
-"@react-stately/collections@^3.4.1", "@react-stately/collections@^3.4.2":
- version "3.4.2"
- resolved "https://registry.yarnpkg.com/@react-stately/collections/-/collections-3.4.2.tgz#b8625192b8cd5abe6cc2d5371643a071dc492e44"
- integrity sha512-CmLVWtbX4r3QaTNdI6edtrRKIZRKPuxyD7TmVIaoZBdaOXStTP4wOgyPN1ELww9bvW0MoOaQBbUn5WAPrfifFw==
+"@react-stately/collections@^3.4.1", "@react-stately/collections@^3.4.4":
+ version "3.4.4"
+ resolved "https://registry.yarnpkg.com/@react-stately/collections/-/collections-3.4.4.tgz#9df0b690bac0d3a95bc01352937ec74160c6bd29"
+ integrity sha512-gryUYCe6uzqE0ea5frTwOxOPpx/6Z42PRk7KetOh3ddN3Ts0j8XQP08jP1IB/7BC1QidrkHWvDCqGHxRiEjiIg==
dependencies:
"@babel/runtime" "^7.6.2"
- "@react-types/shared" "^3.14.0"
+ "@react-types/shared" "^3.15.0"
"@react-stately/menu@3.3.1":
version "3.3.1"
@@ -2364,55 +2303,55 @@
"@react-types/shared" "^3.13.1"
"@react-stately/menu@^3.3.1":
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/@react-stately/menu/-/menu-3.4.0.tgz#ee535287229ab4b0561dfdca570d82180f8cc4ea"
- integrity sha512-xdNS3K0PmSjpNhH/Xnskfexxyo909Jkkfux4zhP5Ivk4Vkp0eThb6v9AIomUAo163PuOnHQFen1ZmwFEs92xMw==
+ version "3.4.2"
+ resolved "https://registry.yarnpkg.com/@react-stately/menu/-/menu-3.4.2.tgz#5bb6847c9bf4a6140d561114b5f8709a4df12a51"
+ integrity sha512-vFC8EloVEcqf6sgiP6ABIkC41ytjoJiGtj7Ws5OS7PvZNyxxDgJr4V0O3Pxd1T0AjlHCloBbojnvoTRwZiSr/A==
dependencies:
"@babel/runtime" "^7.6.2"
- "@react-stately/overlays" "^3.4.0"
+ "@react-stately/overlays" "^3.4.2"
"@react-stately/utils" "^3.5.1"
- "@react-types/menu" "^3.7.0"
- "@react-types/shared" "^3.14.0"
+ "@react-types/menu" "^3.7.2"
+ "@react-types/shared" "^3.15.0"
-"@react-stately/overlays@^3.3.1", "@react-stately/overlays@^3.4.0":
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/@react-stately/overlays/-/overlays-3.4.0.tgz#4023d0c7cd48363fe046e5b6084d703ac461c907"
- integrity sha512-jXVm1V91lWOKh73cFvE9W9JtAE8idSWEUtFlVrlBI/jh0ZOt148UlRVWgHrm7FhaUpyvOFNUyfidRmKMuB+hgw==
+"@react-stately/overlays@^3.3.1", "@react-stately/overlays@^3.4.2":
+ version "3.4.2"
+ resolved "https://registry.yarnpkg.com/@react-stately/overlays/-/overlays-3.4.2.tgz#c6df94a65551137075263eeef70beba8b90b52a0"
+ integrity sha512-UTCnn0aT+JL4ZhYPQYUWHwhmuR2T3vKTFUEZeZN9sTuDCctg08VfGoASJx8qofqkLwYJXeb8D5PMhhTDPiUQPw==
dependencies:
"@babel/runtime" "^7.6.2"
"@react-stately/utils" "^3.5.1"
- "@react-types/overlays" "^3.6.2"
+ "@react-types/overlays" "^3.6.4"
-"@react-stately/selection@^3.10.2":
- version "3.10.2"
- resolved "https://registry.yarnpkg.com/@react-stately/selection/-/selection-3.10.2.tgz#0871e4d7bfc5a1dc1df6ff8d6800b499b2042732"
- integrity sha512-3/iw0BpShWt5ie+YpOzi4Mpa3yKOtlKQZXEc0fZt3v3m3N3fMoCr7Ovkfuz5Svy47HIIN1Pk1WkRJC+CQ4hfDw==
+"@react-stately/selection@^3.11.0":
+ version "3.11.0"
+ resolved "https://registry.yarnpkg.com/@react-stately/selection/-/selection-3.11.0.tgz#50945d87dadd0d08505b37f1bb319d0c783d2037"
+ integrity sha512-cBgDzH+AY+bMEROJbcZFdhbMk0vgiwyqBB8ZKLtCL7EOHs2xeynTAohRM+/t27U/tF91o4qHPFo67Tkxrd16Bg==
dependencies:
"@babel/runtime" "^7.6.2"
- "@react-stately/collections" "^3.4.2"
+ "@react-stately/collections" "^3.4.4"
"@react-stately/utils" "^3.5.1"
- "@react-types/shared" "^3.14.0"
+ "@react-types/shared" "^3.15.0"
"@react-stately/toggle@^3.3.1":
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/@react-stately/toggle/-/toggle-3.4.0.tgz#42bb0dc226f90eb70f9e87dcbe08df9e45324255"
- integrity sha512-7kPxR2+Aze7NmpWWOQanRsQvmz7R+Sdlu+2xi0Wh5LPFg+lkXSiGY63uM2amxZcbFb0Mhy5ExlRpF53ReZjEOA==
+ version "3.4.2"
+ resolved "https://registry.yarnpkg.com/@react-stately/toggle/-/toggle-3.4.2.tgz#8c70922ad559d9ef32ecf3cc3d122a66eb858f0d"
+ integrity sha512-+pO13Ap/tj4optu6VjQrEAaAoZvJAEwarMUaZvrkc0kdvMTNPdiT/2vhN32yvsSW0ssuFqToa3jMrTylCbpo8w==
dependencies:
"@babel/runtime" "^7.6.2"
"@react-stately/utils" "^3.5.1"
- "@react-types/checkbox" "^3.3.2"
- "@react-types/shared" "^3.14.0"
+ "@react-types/checkbox" "^3.4.0"
+ "@react-types/shared" "^3.15.0"
"@react-stately/tree@^3.3.1":
- version "3.3.2"
- resolved "https://registry.yarnpkg.com/@react-stately/tree/-/tree-3.3.2.tgz#db1e98fa074c89cfd63b4d260de025fef285e520"
- integrity sha512-goviIXFYZvWJ2FOBQdKHfLwCaFUlhyGCsbX9GB7ziZhm0Ez8iWCzEy1IWoeuPaprBlHIPv6/3XtDi4ZQ52A59g==
+ version "3.3.4"
+ resolved "https://registry.yarnpkg.com/@react-stately/tree/-/tree-3.3.4.tgz#2b71436dd7ed3bd42983f4fd29a9417f947876f9"
+ integrity sha512-CBgXvwa9qYBsJuxrAiVgGnm48eSxLe/6OjPMwH1pWf4s383Mx73MbbN4fS0oWDeXBVgdqz5/Xg/p8nvPIvl3WQ==
dependencies:
"@babel/runtime" "^7.6.2"
- "@react-stately/collections" "^3.4.2"
- "@react-stately/selection" "^3.10.2"
+ "@react-stately/collections" "^3.4.4"
+ "@react-stately/selection" "^3.11.0"
"@react-stately/utils" "^3.5.1"
- "@react-types/shared" "^3.14.0"
+ "@react-types/shared" "^3.15.0"
"@react-stately/utils@^3.5.0", "@react-stately/utils@^3.5.1":
version "3.5.1"
@@ -2421,47 +2360,47 @@
dependencies:
"@babel/runtime" "^7.6.2"
-"@react-types/button@^3.5.1", "@react-types/button@^3.6.0":
- version "3.6.0"
- resolved "https://registry.yarnpkg.com/@react-types/button/-/button-3.6.0.tgz#cda33c4ed3a5e9da07c52961c17a0028607f5606"
- integrity sha512-ijCi07TkLmwU3Qtn8IzKJi1nugZj8Ln0+w2OZPRJS/tRFv48qgNsOXum54W5i9W0yg/I7VQiPjm+YsQS51g7gA==
+"@react-types/button@^3.5.1", "@react-types/button@^3.6.2":
+ version "3.6.2"
+ resolved "https://registry.yarnpkg.com/@react-types/button/-/button-3.6.2.tgz#72d617deb0f76bd01a570ef28306ac1482c58a67"
+ integrity sha512-qgrYT6yiGVuZSPbzeDT6kTREQVxzJ9p5chV+JX7G5Rpjl2vyUDkEhZ5V/AHLKguBALgFaWJvjtwejHQ7FtycTw==
dependencies:
- "@react-types/shared" "^3.14.0"
+ "@react-types/shared" "^3.15.0"
-"@react-types/checkbox@^3.3.2":
- version "3.3.2"
- resolved "https://registry.yarnpkg.com/@react-types/checkbox/-/checkbox-3.3.2.tgz#513442cb2e73a4d8c8ad14021c424612e98e7cd7"
- integrity sha512-s1bgqL4qfEMEasePayukZ6pzpIzfAG1OuVmpARz0kVdVaN7e+B4+dRJ0nDtiQf/TjNLg45ZlG3NTXJ1hsZPelQ==
+"@react-types/checkbox@^3.4.0":
+ version "3.4.0"
+ resolved "https://registry.yarnpkg.com/@react-types/checkbox/-/checkbox-3.4.0.tgz#f2d6acabdf953cf2f7b8b874dab9ac8ae1c020fa"
+ integrity sha512-ZDqbtAYWWSGPjL4ydinaWHrD65Qft9yEGA6BCKQTxdJCgxiXxgGkA3pI7Sxwk+OulR+O0CYJ1JROExM9cSJyyQ==
dependencies:
- "@react-types/shared" "^3.14.0"
+ "@react-types/shared" "^3.15.0"
"@react-types/dialog@^3.4.1":
- version "3.4.2"
- resolved "https://registry.yarnpkg.com/@react-types/dialog/-/dialog-3.4.2.tgz#509ac6998b6d7bedd2b8150306054389fee7ce61"
- integrity sha512-ub5KrXuN0VELqIKDKuj+ySalcliIneuVnwnX83XbW+xSs9/zFo5WwALU0YxP77rzwIyuu6ziQ8CUZ7rHhLa0hQ==
+ version "3.4.4"
+ resolved "https://registry.yarnpkg.com/@react-types/dialog/-/dialog-3.4.4.tgz#48863c58e18d41de8a7e35cf2463a1ed44bd0135"
+ integrity sha512-mBaoQn+2nd14j0WSTfqGMb8dfG6Nak4+S9HqbJeP6UjKfwnmF8aXQ/Z3EYPNcwwDB+fNYStPagxRdBeqJ1GK4g==
dependencies:
- "@react-types/overlays" "^3.6.2"
- "@react-types/shared" "^3.14.0"
+ "@react-types/overlays" "^3.6.4"
+ "@react-types/shared" "^3.15.0"
-"@react-types/menu@^3.6.1", "@react-types/menu@^3.7.0":
- version "3.7.0"
- resolved "https://registry.yarnpkg.com/@react-types/menu/-/menu-3.7.0.tgz#632422d6024a36ab7920c1fceb064900d9f5a762"
- integrity sha512-1kEyyb0tERlPdZ67lsC2fMZ2TTh0OdS1hcb01PrSkGna/S+H/Q9M65Xc+q9eu7QoC4+DN4Flh/7vNRT82kVlHg==
+"@react-types/menu@^3.6.1", "@react-types/menu@^3.7.2":
+ version "3.7.2"
+ resolved "https://registry.yarnpkg.com/@react-types/menu/-/menu-3.7.2.tgz#04a0447f791a7ffa0a6c8dc160cbff3bbeeedefd"
+ integrity sha512-BXMWrT3VCP6NTf0y7v1YYqRJNXkUKLzGXI+n7Qv9+aiZZfd3NNMyk20byHczhFoT2yuCcU5xhyOXzkxSo6ew3A==
dependencies:
- "@react-types/overlays" "^3.6.2"
- "@react-types/shared" "^3.14.0"
+ "@react-types/overlays" "^3.6.4"
+ "@react-types/shared" "^3.15.0"
-"@react-types/overlays@^3.6.1", "@react-types/overlays@^3.6.2":
- version "3.6.2"
- resolved "https://registry.yarnpkg.com/@react-types/overlays/-/overlays-3.6.2.tgz#f11f8abe5073ca7a80d3beada018b715af25859c"
- integrity sha512-ag9UCIlcNCvMHBORRksdLnQK3ef+CEbrt+TydOxBAxAf+87fXJ/0H6hP/4QTebEA2ixA0qz8CFga81S8ZGnOsQ==
+"@react-types/overlays@^3.6.1", "@react-types/overlays@^3.6.4":
+ version "3.6.4"
+ resolved "https://registry.yarnpkg.com/@react-types/overlays/-/overlays-3.6.4.tgz#4ae4d7b3b38c45d122b0ca2dc88a57f08e89fd0e"
+ integrity sha512-REC4IyDUHS5WhwxMxcvTo+LdrvlSYpJKjyYkPFtJoDBpM3gmXfakTY3KW6K5eZkFv3TnmXjDF9Q2yboEk2u6WQ==
dependencies:
- "@react-types/shared" "^3.14.0"
+ "@react-types/shared" "^3.15.0"
-"@react-types/shared@^3.13.1", "@react-types/shared@^3.14.0":
- version "3.14.0"
- resolved "https://registry.yarnpkg.com/@react-types/shared/-/shared-3.14.0.tgz#240991d6672f32ecd2a172111e163be0fe0778f2"
- integrity sha512-K069Bh/P0qV3zUG8kqabeO8beAUlFdyVPvpcNVPjRl+0Q9NDS9mfdQbmUa0LqdVo5e6jRPdos77Ylflkrz8wcw==
+"@react-types/shared@^3.13.1", "@react-types/shared@^3.15.0":
+ version "3.15.0"
+ resolved "https://registry.yarnpkg.com/@react-types/shared/-/shared-3.15.0.tgz#a4a78f36bc8daaefe6e9a9df1f453271639c2233"
+ integrity sha512-hwuE4BmgswqP+HRDSLMj7DcnYOCCK+ZRuKnc9AVhXS4LBrwRSkdUkNvXhgvqF5tav7IqTpG9pBYMR9wedehuhA==
"@sentry/browser@6.19.7":
version "6.19.7"
@@ -2515,6 +2454,11 @@
"@sentry/types" "6.19.7"
tslib "^1.9.3"
+"@sinclair/typebox@^0.24.1":
+ version "0.24.44"
+ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.44.tgz#0a0aa3bf4a155a678418527342a3ee84bd8caa5c"
+ integrity sha512-ka0W0KN5i6LfrSocduwliMMpqVgohtPFidKdMEOUjoOFCHcOOYkKsPRxfs5f15oPNHTm6ERAm0GV/+/LTKeiWg==
+
"@sinonjs/commons@^1.7.0":
version "1.8.3"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d"
@@ -2531,23 +2475,23 @@
"@stylelint/postcss-css-in-js@^0.37.2":
version "0.37.3"
- resolved "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.3.tgz"
+ resolved "https://registry.yarnpkg.com/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.3.tgz#d149a385e07ae365b0107314c084cb6c11adbf49"
integrity sha512-scLk3cSH1H9KggSniseb2KNAU5D9FWc3H7BxCSAIdtU9OWIyw0zkEZ9qEKHryRM+SExYXRKNb7tOOVNAsQ3iwg==
dependencies:
"@babel/core" "^7.17.9"
"@stylelint/postcss-markdown@^0.36.2":
version "0.36.2"
- resolved "https://registry.npmjs.org/@stylelint/postcss-markdown/-/postcss-markdown-0.36.2.tgz"
+ resolved "https://registry.yarnpkg.com/@stylelint/postcss-markdown/-/postcss-markdown-0.36.2.tgz#0a540c4692f8dcdfc13c8e352c17e7bfee2bb391"
integrity sha512-2kGbqUVJUGE8dM+bMzXG/PYUWKkjLIkRLWNh39OaADkiabDRdw8ATFCgbMz5xdIcvwspPAluSL7uY+ZiTWdWmQ==
dependencies:
remark "^13.0.0"
unist-util-find-all-after "^3.0.2"
-"@testing-library/dom@>=7":
- version "8.17.1"
- resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.17.1.tgz#2d7af4ff6dad8d837630fecd08835aee08320ad7"
- integrity sha512-KnH2MnJUzmFNPW6RIKfd+zf2Wue8mEKX0M3cpX6aKl5ZXrJM1/c/Pc8c2xDNYQCnJO48Sm5ITbMXgqTr3h4jxQ==
+"@testing-library/dom@>=7", "@testing-library/dom@^8.0.0":
+ version "8.18.1"
+ resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.18.1.tgz#80f91be02bc171fe5a3a7003f88207be31ac2cf3"
+ integrity sha512-oEvsm2B/WtcHKE+IcEeeCqNU/ltFGaVyGbpcm4g/2ytuT49jrlH9x5qRKL/H3A6yfM4YAbSbC0ceT5+9CEXnLg==
dependencies:
"@babel/code-frame" "^7.10.4"
"@babel/runtime" "^7.12.5"
@@ -2558,6 +2502,30 @@
lz-string "^1.4.4"
pretty-format "^27.0.2"
+"@testing-library/jest-dom@^5.16.5":
+ version "5.16.5"
+ resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz#3912846af19a29b2dbf32a6ae9c31ef52580074e"
+ integrity sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA==
+ dependencies:
+ "@adobe/css-tools" "^4.0.1"
+ "@babel/runtime" "^7.9.2"
+ "@types/testing-library__jest-dom" "^5.9.1"
+ aria-query "^5.0.0"
+ chalk "^3.0.0"
+ css.escape "^1.5.1"
+ dom-accessibility-api "^0.5.6"
+ lodash "^4.17.15"
+ redent "^3.0.0"
+
+"@testing-library/react@12":
+ version "12.1.5"
+ resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-12.1.5.tgz#bb248f72f02a5ac9d949dea07279095fa577963b"
+ integrity sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg==
+ dependencies:
+ "@babel/runtime" "^7.12.5"
+ "@testing-library/dom" "^8.0.0"
+ "@types/react-dom" "<18.0.0"
+
"@tootallnate/once@1":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
@@ -2600,9 +2568,9 @@
"@babel/types" "^7.0.0"
"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6":
- version "7.18.0"
- resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.0.tgz#8134fd78cb39567465be65b9fdc16d378095f41f"
- integrity sha512-v4Vwdko+pgymgS+A2UIaJru93zQd85vIGWObM5ekZNdXCKtDYqATlEYnWgfo86Q6I1Lh0oXnksDnMU1cwmlPDw==
+ version "7.18.2"
+ resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.2.tgz#235bf339d17185bdec25e024ca19cce257cc7309"
+ integrity sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==
dependencies:
"@babel/types" "^7.3.0"
@@ -2615,9 +2583,9 @@
"@types/node" "*"
"@types/clean-css@*":
- version "4.2.5"
- resolved "https://registry.yarnpkg.com/@types/clean-css/-/clean-css-4.2.5.tgz#69ce62cc13557c90ca40460133f672dc52ceaf89"
- integrity sha512-NEzjkGGpbs9S9fgC4abuBvTpVwE3i+Acu9BBod3PUyjDVZcNsGx61b8r2PphR61QGPnn0JHVs5ey6/I4eTrkxw==
+ version "4.2.6"
+ resolved "https://registry.yarnpkg.com/@types/clean-css/-/clean-css-4.2.6.tgz#48b427285b2b654751a9bbc6f7d35e6173dec8d2"
+ integrity sha512-Ze1tf+LnGPmG6hBFMi0B4TEB0mhF7EiMM5oyjLDNPE9hxrPU0W+5+bHvO+eFPA+bt0iC1zkQMoU/iGdRVjcRbw==
dependencies:
"@types/node" "*"
source-map "^0.6.0"
@@ -2696,18 +2664,18 @@
integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==
"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18":
- version "4.17.30"
- resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.30.tgz#0f2f99617fa8f9696170c46152ccf7500b34ac04"
- integrity sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ==
+ version "4.17.31"
+ resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz#a1139efeab4e7323834bb0226e62ac019f474b2f"
+ integrity sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==
dependencies:
"@types/node" "*"
"@types/qs" "*"
"@types/range-parser" "*"
"@types/express@*":
- version "4.17.13"
- resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034"
- integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==
+ version "4.17.14"
+ resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.14.tgz#143ea0557249bc1b3b54f15db4c81c3d4eb3569c"
+ integrity sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==
dependencies:
"@types/body-parser" "*"
"@types/express-serve-static-core" "^4.17.18"
@@ -2715,9 +2683,9 @@
"@types/serve-static" "*"
"@types/fined@*":
- version "1.1.2"
- resolved "https://registry.npmjs.org/@types/fined/-/fined-1.1.2.tgz"
- integrity sha512-hzzTS+X9EqDhx4vwdch/DOZci/bfh5J6Nyz8lqvyfBg2ROx2fPafX+LpDfpVgSvQKj0EYkwTYpBO3z2etwbkOw==
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/@types/fined/-/fined-1.1.3.tgz#83f03e8f0a8d3673dfcafb18fce3571f6250e1bc"
+ integrity sha512-CWYnSRnun3CGbt6taXeVo2lCbuaj4mchVJ4UF/BdU5TSuIn3AmS13pGMwCsBUoehGbhZrBrpNJZSZI5EVilXww==
"@types/fs-extra@^9.0.13":
version "9.0.13"
@@ -2726,7 +2694,15 @@
dependencies:
"@types/node" "*"
-"@types/glob@*", "@types/glob@^7.1.1":
+"@types/glob@*":
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/@types/glob/-/glob-8.0.0.tgz#321607e9cbaec54f687a0792b2d1d370739455d2"
+ integrity sha512-l6NQsDDyQUVeoTynNpC9uRvCUint/gSUXQA2euwmTuWGvPY5LSDUu6tkCtJB2SvGQlJQzLaKqcGZP4//7EDveA==
+ dependencies:
+ "@types/minimatch" "*"
+ "@types/node" "*"
+
+"@types/glob@^7.1.1":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb"
integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==
@@ -2741,11 +2717,6 @@
dependencies:
"@types/node" "*"
-"@types/history@*":
- version "4.7.8"
- resolved "https://registry.npmjs.org/@types/history/-/history-4.7.8.tgz"
- integrity sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==
-
"@types/history@^4.7.11":
version "4.7.11"
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64"
@@ -2791,22 +2762,22 @@
"@types/inquirer@^6.5.0":
version "6.5.0"
- resolved "https://registry.npmjs.org/@types/inquirer/-/inquirer-6.5.0.tgz"
+ resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-6.5.0.tgz#b83b0bf30b88b8be7246d40e51d32fe9d10e09be"
integrity sha512-rjaYQ9b9y/VFGOpqBEXRavc3jh0a+e6evAbI31tMda8VlPaSy0AZJfXsvmIe3wklc7W6C3zCSfleuMXR7NOyXw==
dependencies:
"@types/through" "*"
rxjs "^6.4.0"
"@types/inquirer@^8.2.1":
- version "8.2.3"
- resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-8.2.3.tgz#985515d04879a0d0c1f5f49ec375767410ba9dab"
- integrity sha512-ZlBqD+8WIVNy3KIVkl+Qne6bGLW2erwN0GJXY9Ri/9EMbyupee3xw3H0Mmv5kJoLyNpfd/oHlwKxO0DUDH7yWA==
+ version "8.2.4"
+ resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-8.2.4.tgz#f7f0c76c65870c7bbc80a112c9c77ffcf7f158c1"
+ integrity sha512-Pxxx3i3AyK7vKAj3LRM/vF7ETcHKiLJ/u5CnNgbz/eYj/vB3xGAYtRxI5IKtq0hpe5iFHD22BKV3n6WHUu0k4Q==
dependencies:
"@types/through" "*"
"@types/interpret@*":
version "1.1.1"
- resolved "https://registry.npmjs.org/@types/interpret/-/interpret-1.1.1.tgz"
+ resolved "https://registry.yarnpkg.com/@types/interpret/-/interpret-1.1.1.tgz#b1bf85b0420e2414b989ce237658ad20dc03719b"
integrity sha512-HZ4d0m2Ebl8DmrOdYZHgYyipj/8Ftq1/ssB/oQR7fqfUrwtTP7IW3BDi2V445nhPBLzZjEkApaPVp83moSCXlA==
dependencies:
"@types/node" "*"
@@ -2830,6 +2801,14 @@
dependencies:
"@types/istanbul-lib-report" "*"
+"@types/jest@*":
+ version "29.1.2"
+ resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.1.2.tgz#7ad8077043ab5f6c108c8111bcc1d224e5600a87"
+ integrity sha512-y+nlX0h87U0R+wsGn6EBuoRWYyv3KFtwRNP3QWp9+k2tJ2/bqcGS3UxD7jgT+tiwJWWq3UsyV4Y+T6rsMT4XMg==
+ dependencies:
+ expect "^29.0.0"
+ pretty-format "^29.0.0"
+
"@types/jest@27.4.1":
version "27.4.1"
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.4.1.tgz#185cbe2926eaaf9662d340cc02e548ce9e11ab6d"
@@ -2838,6 +2817,14 @@
jest-matcher-utils "^27.0.0"
pretty-format "^27.0.0"
+"@types/jest@^27.5.1":
+ version "27.5.2"
+ resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.5.2.tgz#ec49d29d926500ffb9fd22b84262e862049c026c"
+ integrity sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==
+ dependencies:
+ jest-matcher-utils "^27.0.0"
+ pretty-format "^27.0.0"
+
"@types/js-cookie@^2.2.6":
version "2.2.7"
resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.2.7.tgz#226a9e31680835a6188e887f3988e60c04d3f6a3"
@@ -2850,13 +2837,13 @@
"@types/json5@^0.0.29":
version "0.0.29"
- resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz"
- integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
+ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
+ integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
-"@types/liftoff@^2.5.0":
- version "2.5.0"
- resolved "https://registry.npmjs.org/@types/liftoff/-/liftoff-2.5.0.tgz"
- integrity sha512-1jsThE//wKDK+hYM+NJqswI+K9lfR0YNMctteOxAzk/aemI0rQsVDk6Dia0zkPfBWFTh+hiDmrGQXqP1tyM+eg==
+"@types/liftoff@^2.5.1":
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/@types/liftoff/-/liftoff-2.5.1.tgz#2eb4c1f86e9d5ee85571e56db0084b26af129ced"
+ integrity sha512-nB3R6Q9CZcM07JgiTK6ibxqrG1reiHE+UX7em/W1DKwVBxDlfKWOefQjk4jubY5xX+GDxVsWR2KD1SenPby8ow==
dependencies:
"@types/fined" "*"
"@types/interpret" "*"
@@ -2870,9 +2857,9 @@
"@types/lodash" "*"
"@types/lodash@*":
- version "4.14.170"
- resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.170.tgz"
- integrity sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q==
+ version "4.14.186"
+ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.186.tgz#862e5514dd7bd66ada6c70ee5fce844b06c8ee97"
+ integrity sha512-eHcVlLXP0c2FlMPm56ITode2AgLMSa6aJ05JTTbYbI+7EMkCEE5qk2E41d5g2lCVTqRe0GnnRFurmlCsDODrPw==
"@types/lodash@4.14.181":
version "4.14.181"
@@ -2881,7 +2868,7 @@
"@types/mdast@^3.0.0":
version "3.0.10"
- resolved "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz"
+ resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af"
integrity sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==
dependencies:
"@types/unist" "*"
@@ -2892,19 +2879,19 @@
integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==
"@types/minimatch@*":
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.0.tgz#c3018161691376002f8a22ebb87f341e0dba3219"
- integrity sha512-0RJHq5FqDWo17kdHe+SMDJLfxmLaqHbWnqZ6gNKzDvStUlrmx/eKIY17+ifLS1yybo7X86aUshQMlittDOVNnw==
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca"
+ integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==
"@types/minimist@^1.2.0":
version "1.2.2"
- resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz"
+ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c"
integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==
"@types/node@*":
- version "18.7.13"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.13.tgz#23e6c5168333480d454243378b69e861ab5c011a"
- integrity sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==
+ version "18.8.3"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.8.3.tgz#ce750ab4017effa51aed6a7230651778d54e327c"
+ integrity sha512-0os9vz6BpGwxGe9LOhgP/ncvYN5Tx1fNcd2TM3rD/aCGBkysb+ZWpXEocG24h6ZzOi13+VB8HndAQFezsSOw1w==
"@types/node@16.11.26":
version "16.11.26"
@@ -2927,9 +2914,9 @@
integrity sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==
"@types/prettier@^2.1.5":
- version "2.7.0"
- resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.0.tgz#ea03e9f0376a4446f44797ca19d9c46c36e352dc"
- integrity sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==
+ version "2.7.1"
+ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.1.tgz#dfd20e2dc35f027cdd6c1908e80a5ddc7499670e"
+ integrity sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==
"@types/prop-types@*":
version "15.7.5"
@@ -2943,7 +2930,7 @@
"@types/query-string@^6.3.0":
version "6.3.0"
- resolved "https://registry.npmjs.org/@types/query-string/-/query-string-6.3.0.tgz"
+ resolved "https://registry.yarnpkg.com/@types/query-string/-/query-string-6.3.0.tgz#b6fa172a01405abcaedac681118e78429d62ea39"
integrity sha512-yuIv/WRffRzL7cBW+sla4HwBZrEXRNf1MKQ5SklPEadth+BKbDxiVG8A3iISN5B3yC4EeSCzMZP8llHTcUhOzQ==
dependencies:
query-string "*"
@@ -2971,6 +2958,13 @@
"@types/webpack" "^4"
"@types/webpack-dev-server" "3"
+"@types/react-dom@<18.0.0":
+ version "17.0.17"
+ resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.17.tgz#2e3743277a793a96a99f1bf87614598289da68a1"
+ integrity sha512-VjnqEmqGnasQKV0CWLevqMTXBYG9GbwuE6x3VetERLh0cq2LTptFE73MrQi2S7GkKXCf2GgwItB/melLnxfnsg==
+ dependencies:
+ "@types/react" "^17"
+
"@types/react-dom@^18.0.6":
version "18.0.6"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.6.tgz#36652900024842b74607a17786b6662dd1e103a1"
@@ -3005,13 +2999,20 @@
"@types/react-router" "*"
"@types/react-router@*":
- version "5.1.15"
- resolved "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.15.tgz"
- integrity sha512-z3UlMG/x91SFEVmmvykk9FLTliDvfdIUky4k2rCfXWQ0NKbrP8o9BTCaCTPuYsB8gDkUnUmkcA2vYlm2DR+HAA==
+ version "5.1.19"
+ resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.19.tgz#9b404246fba7f91474d7008a3d48c17b6e075ad6"
+ integrity sha512-Fv/5kb2STAEMT3wHzdKQK2z8xKq38EDIGVrutYLmQVVLe+4orDFquU52hQrULnEHinMKv9FSA6lf9+uNT1ITtA==
dependencies:
- "@types/history" "*"
+ "@types/history" "^4.7.11"
"@types/react" "*"
+"@types/react-test-renderer@^17.0.2":
+ version "17.0.2"
+ resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-17.0.2.tgz#5f800a39b12ac8d2a2149e7e1885215bcf4edbbf"
+ integrity sha512-+F1KONQTBHDBBhbHuT2GNydeMpPuviduXIVJRB7Y4nma4NR5DrTJfMMZ+jbhEHbpwL+Uqhs1WXh4KHiyrtYTPg==
+ dependencies:
+ "@types/react" "^17"
+
"@types/react-transition-group@^4.4.0", "@types/react-transition-group@^4.4.5":
version "4.4.5"
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.5.tgz#aae20dcf773c5aa275d5b9f7cdbca638abc5e416"
@@ -3020,9 +3021,18 @@
"@types/react" "*"
"@types/react@*":
- version "18.0.17"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.17.tgz#4583d9c322d67efe4b39a935d223edcc7050ccf4"
- integrity sha512-38ETy4tL+rn4uQQi7mB81G7V1g0u2ryquNmsVIOKUAEIDK+3CUjZ6rSRpdvS99dNBnkLFL83qfmtLacGOTIhwQ==
+ version "18.0.21"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.21.tgz#b8209e9626bb00a34c76f55482697edd2b43cc67"
+ integrity sha512-7QUCOxvFgnD5Jk8ZKlUAhVcRj7GuJRjnjjiY/IUBWKgOlnvDvTMLD4RTF7NPyVmbRhNrbomZiOepg7M/2Kj1mA==
+ dependencies:
+ "@types/prop-types" "*"
+ "@types/scheduler" "*"
+ csstype "^3.0.2"
+
+"@types/react@^17":
+ version "17.0.50"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.50.tgz#39abb4f7098f546cfcd6b51207c90c4295ee81fc"
+ integrity sha512-ZCBHzpDb5skMnc1zFXAXnL3l1FAdi+xZvwxK+PkglMmBrwjpp9nKaWuEvrGnSifCJmBFGxZOOFuwC6KH/s0NuA==
dependencies:
"@types/prop-types" "*"
"@types/scheduler" "*"
@@ -3051,6 +3061,11 @@
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc"
integrity sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==
+"@types/semver@^7.3.12":
+ version "7.3.12"
+ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.12.tgz#920447fdd78d76b19de0438b7f60df3c4a80bf1c"
+ integrity sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==
+
"@types/serve-static@*":
version "1.15.0"
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155"
@@ -3074,6 +3089,13 @@
resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.8.tgz#b94a4391c85666c7b73299fd3ad79d4faa435310"
integrity sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==
+"@types/testing-library__jest-dom@^5.9.1":
+ version "5.14.5"
+ resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.5.tgz#d113709c90b3c75fdb127ec338dad7d5f86c974f"
+ integrity sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ==
+ dependencies:
+ "@types/jest" "*"
+
"@types/throttle-debounce@^5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@types/throttle-debounce/-/throttle-debounce-5.0.0.tgz#8208087f0af85107bcc681c50fa837fc9505483e"
@@ -3092,9 +3114,9 @@
integrity sha512-dDZH/tXzwjutnuk4UacGgFRwV+JSLaXL1ikvidfJprkb7L9Nx1njcRHHmi3Dsvt7pgqqTEeucQuOrWHPFgzVHA==
"@types/trusted-types@*":
- version "2.0.0"
- resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.0.tgz"
- integrity sha512-I8MnZqNXsOLHsU111oHbn3khtvKMi5Bn4qVFsIWSJcCP1KKDiXX5AEw8UPk0nSopeC+Hvxt6yAy1/a5PailFqg==
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756"
+ integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==
"@types/uglify-js@*":
version "3.17.0"
@@ -3105,7 +3127,7 @@
"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2":
version "2.0.6"
- resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz"
+ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
"@types/webpack-dev-server@3":
@@ -3152,6 +3174,13 @@
dependencies:
"@types/yargs-parser" "*"
+"@types/yargs@^17.0.8":
+ version "17.0.13"
+ resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.13.tgz#34cced675ca1b1d51fcf4d34c3c6f0fa142a5c76"
+ integrity sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==
+ dependencies:
+ "@types/yargs-parser" "*"
+
"@typescript-eslint/eslint-plugin@5.16.0":
version "5.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.16.0.tgz#78f246dd8d1b528fc5bfca99a8a64d4023a3d86d"
@@ -3167,6 +3196,20 @@
semver "^7.3.5"
tsutils "^3.21.0"
+"@typescript-eslint/eslint-plugin@^5.40.1":
+ version "5.40.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.40.1.tgz#3203a6ff396b1194083faaa6e5110c401201d7d5"
+ integrity sha512-FsWboKkWdytGiXT5O1/R9j37YgcjO8MKHSUmWnIEjVaz0krHkplPnYi7mwdb+5+cs0toFNQb0HIrN7zONdIEWg==
+ dependencies:
+ "@typescript-eslint/scope-manager" "5.40.1"
+ "@typescript-eslint/type-utils" "5.40.1"
+ "@typescript-eslint/utils" "5.40.1"
+ debug "^4.3.4"
+ ignore "^5.2.0"
+ regexpp "^3.2.0"
+ semver "^7.3.7"
+ tsutils "^3.21.0"
+
"@typescript-eslint/parser@5.16.0":
version "5.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.16.0.tgz#e4de1bde4b4dad5b6124d3da227347616ed55508"
@@ -3185,6 +3228,14 @@
"@typescript-eslint/types" "5.16.0"
"@typescript-eslint/visitor-keys" "5.16.0"
+"@typescript-eslint/scope-manager@5.40.1":
+ version "5.40.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.40.1.tgz#a7a5197dfd234622a2421ea590ee0ccc02e18dfe"
+ integrity sha512-jkn4xsJiUQucI16OLCXrLRXDZ3afKhOIqXs4R3O+M00hdQLKR58WuyXPZZjhKLFCEP2g+TXdBRtLQ33UfAdRUg==
+ dependencies:
+ "@typescript-eslint/types" "5.40.1"
+ "@typescript-eslint/visitor-keys" "5.40.1"
+
"@typescript-eslint/type-utils@5.16.0":
version "5.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.16.0.tgz#b482bdde1d7d7c0c7080f7f2f67ea9580b9e0692"
@@ -3194,11 +3245,26 @@
debug "^4.3.2"
tsutils "^3.21.0"
+"@typescript-eslint/type-utils@5.40.1":
+ version "5.40.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.40.1.tgz#091e4ce3bebbdb68f4980bae9dee2e4e1725f601"
+ integrity sha512-DLAs+AHQOe6n5LRraXiv27IYPhleF0ldEmx6yBqBgBLaNRKTkffhV1RPsjoJBhVup2zHxfaRtan8/YRBgYhU9Q==
+ dependencies:
+ "@typescript-eslint/typescript-estree" "5.40.1"
+ "@typescript-eslint/utils" "5.40.1"
+ debug "^4.3.4"
+ tsutils "^3.21.0"
+
"@typescript-eslint/types@5.16.0":
version "5.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.16.0.tgz#5827b011982950ed350f075eaecb7f47d3c643ee"
integrity sha512-oUorOwLj/3/3p/HFwrp6m/J2VfbLC8gjW5X3awpQJ/bSG+YRGFS4dpsvtQ8T2VNveV+LflQHjlLvB6v0R87z4g==
+"@typescript-eslint/types@5.40.1":
+ version "5.40.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.40.1.tgz#de37f4f64de731ee454bb2085d71030aa832f749"
+ integrity sha512-Icg9kiuVJSwdzSQvtdGspOlWNjVDnF3qVIKXdJ103o36yRprdl3Ge5cABQx+csx960nuMF21v8qvO31v9t3OHw==
+
"@typescript-eslint/typescript-estree@5.16.0":
version "5.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.16.0.tgz#32259459ec62f5feddca66adc695342f30101f61"
@@ -3212,6 +3278,19 @@
semver "^7.3.5"
tsutils "^3.21.0"
+"@typescript-eslint/typescript-estree@5.40.1":
+ version "5.40.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.40.1.tgz#9a7d25492f02c69882ce5e0cd1857b0c55645d72"
+ integrity sha512-5QTP/nW5+60jBcEPfXy/EZL01qrl9GZtbgDZtDPlfW5zj/zjNrdI2B5zMUHmOsfvOr2cWqwVdWjobCiHcedmQA==
+ dependencies:
+ "@typescript-eslint/types" "5.40.1"
+ "@typescript-eslint/visitor-keys" "5.40.1"
+ debug "^4.3.4"
+ globby "^11.1.0"
+ is-glob "^4.0.3"
+ semver "^7.3.7"
+ tsutils "^3.21.0"
+
"@typescript-eslint/utils@5.16.0":
version "5.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.16.0.tgz#42218b459d6d66418a4eb199a382bdc261650679"
@@ -3224,6 +3303,20 @@
eslint-scope "^5.1.1"
eslint-utils "^3.0.0"
+"@typescript-eslint/utils@5.40.1":
+ version "5.40.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.40.1.tgz#3204fb73a559d3b7bab7dc9d3c44487c2734a9ca"
+ integrity sha512-a2TAVScoX9fjryNrW6BZRnreDUszxqm9eQ9Esv8n5nXApMW0zeANUYlwh/DED04SC/ifuBvXgZpIK5xeJHQ3aw==
+ dependencies:
+ "@types/json-schema" "^7.0.9"
+ "@types/semver" "^7.3.12"
+ "@typescript-eslint/scope-manager" "5.40.1"
+ "@typescript-eslint/types" "5.40.1"
+ "@typescript-eslint/typescript-estree" "5.40.1"
+ eslint-scope "^5.1.1"
+ eslint-utils "^3.0.0"
+ semver "^7.3.7"
+
"@typescript-eslint/visitor-keys@5.16.0":
version "5.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.16.0.tgz#f27dc3b943e6317264c7492e390c6844cd4efbbb"
@@ -3232,6 +3325,14 @@
"@typescript-eslint/types" "5.16.0"
eslint-visitor-keys "^3.0.0"
+"@typescript-eslint/visitor-keys@5.40.1":
+ version "5.40.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.40.1.tgz#f3d2bf5af192f4432b84cec6fdcb387193518754"
+ integrity sha512-A2DGmeZ+FMja0geX5rww+DpvILpwo1OsiQs0M+joPWJYsiEFBLsH0y1oFymPNul6Z5okSmHpP4ivkc2N0Cgfkw==
+ dependencies:
+ "@typescript-eslint/types" "5.40.1"
+ eslint-visitor-keys "^3.3.0"
+
"@webassemblyjs/ast@1.11.1":
version "1.11.1"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7"
@@ -3402,21 +3503,16 @@ acorn-walk@^7.1.1:
integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
acorn-walk@^8.0.0:
- version "8.1.0"
- resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.0.tgz"
- integrity sha512-mjmzmv12YIG/G8JQdQuz2MUDShEJ6teYpT5bmWA4q7iwoGen8xtt3twF3OvzIUl+Q06aWIjvnwQUKvQ6TtMRjg==
+ version "8.2.0"
+ resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
+ integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
acorn@^7.1.1:
version "7.4.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
-acorn@^8.0.4:
- version "8.4.0"
- resolved "https://registry.npmjs.org/acorn/-/acorn-8.4.0.tgz"
- integrity sha512-ULr0LDaEqQrMFGyQ3bhJkLsbtrQ8QibAseGZeaSUiT/6zb9IvIkomWHJIvgvwad+hinRAgsI51JcWk2yvwyL+w==
-
-acorn@^8.2.4, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0:
+acorn@^8.0.4, acorn@^8.2.4, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0:
version "8.8.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8"
integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==
@@ -3434,9 +3530,9 @@ add-px-to-style@1.0.0:
integrity sha512-YMyxSlXpPjD8uWekCQGuN40lV4bnZagUwqa2m/uFv1z/tNImSk9fnXVMUI5qwME/zzI3MMQRvjZ+69zyfSSyew==
address@^1.0.1, address@^1.1.2:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/address/-/address-1.2.0.tgz#d352a62c92fee90f89a693eccd2a8b2139ab02d9"
- integrity sha512-tNEZYz5G/zYunxFm7sfhAxkXEuLj3K6BKwv6ZURlsF6yiUQ65z0Q2wZW9L5cPUl9ocofGvXOdFYbFHp0+6MOig==
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/address/-/address-1.2.1.tgz#25bb61095b7522d65b357baa11bc05492d4c8acd"
+ integrity sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==
agent-base@6:
version "6.0.2"
@@ -3499,7 +3595,7 @@ ansi-colors@^4.1.1:
ansi-escapes@^4.2.1, ansi-escapes@^4.3.0:
version "4.3.2"
- resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz"
+ resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==
dependencies:
type-fest "^0.21.3"
@@ -3516,7 +3612,7 @@ ansi-regex@^4.1.0:
ansi-regex@^5.0.1:
version "5.0.1"
- resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
ansi-styles@^2.2.1:
@@ -3574,9 +3670,9 @@ argparse@^2.0.1:
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
aria-query@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.0.0.tgz#210c21aaf469613ee8c9a62c7f86525e058db52c"
- integrity sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.0.2.tgz#0b8a744295271861e1d933f8feca13f9b70cfdc1"
+ integrity sha512-eigU3vhqSO+Z8BKDnVLN/ompjhf3pYzecKXz8+whRy+9gZu8n1TCGfwzQUUPnqdHl9ax1Hr9031orZ+UOEYr7Q==
arr-diff@^4.0.0:
version "4.0.0"
@@ -3595,21 +3691,10 @@ arr-union@^3.1.0:
array-each@^1.0.1:
version "1.0.1"
- resolved "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz"
- integrity sha1-p5SvDAWrF1KEbudTofIRoFugxE8=
+ resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f"
+ integrity sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==
-array-includes@^3.1.4:
- version "3.1.4"
- resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz"
- integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.19.1"
- get-intrinsic "^1.1.1"
- is-string "^1.0.7"
-
-array-includes@^3.1.5:
+array-includes@^3.1.4, array-includes@^3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb"
integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==
@@ -3627,7 +3712,7 @@ array-move@^4.0.0:
array-slice@^1.0.0:
version "1.1.0"
- resolved "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz"
+ resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4"
integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==
array-tree-filter@^2.1.0:
@@ -3646,15 +3731,16 @@ array-unique@^0.3.2:
integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==
array.prototype.flat@^1.2.5:
- version "1.2.5"
- resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz"
- integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b"
+ integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
- es-abstract "^1.19.0"
+ es-abstract "^1.19.2"
+ es-shim-unscopables "^1.0.0"
-array.prototype.flatmap@^1.2.5:
+array.prototype.flatmap@^1.2.5, array.prototype.flatmap@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz#a7e8ed4225f4788a70cd910abcf0791e76a5534f"
integrity sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==
@@ -3700,12 +3786,12 @@ attr-accept@^2.2.2:
integrity sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==
autoprefixer@^10.4.4:
- version "10.4.8"
- resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.8.tgz#92c7a0199e1cfb2ad5d9427bd585a3d75895b9e5"
- integrity sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==
+ version "10.4.12"
+ resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.12.tgz#183f30bf0b0722af54ee5ef257f7d4320bb33129"
+ integrity sha512-WrCGV9/b97Pa+jtwf5UGaRjgQIg7OK3D06GnoYoZNcG1Xb8Gt3EfuKjlhh9i/VtT16g6PYjZ69jdJ2g8FxSC4Q==
dependencies:
- browserslist "^4.21.3"
- caniuse-lite "^1.0.30001373"
+ browserslist "^4.21.4"
+ caniuse-lite "^1.0.30001407"
fraction.js "^4.2.0"
normalize-range "^0.1.2"
picocolors "^1.0.0"
@@ -3713,7 +3799,7 @@ autoprefixer@^10.4.4:
autoprefixer@^9.8.6:
version "9.8.8"
- resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz"
+ resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.8.tgz#fd4bd4595385fa6f06599de749a4d5f7a474957a"
integrity sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==
dependencies:
browserslist "^4.12.0"
@@ -3801,16 +3887,16 @@ babel-plugin-macros@^3.1.0:
cosmiconfig "^7.0.0"
resolve "^1.19.0"
-babel-plugin-polyfill-corejs2@^0.3.1, babel-plugin-polyfill-corejs2@^0.3.2:
- version "0.3.2"
- resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.2.tgz#e4c31d4c89b56f3cf85b92558954c66b54bd972d"
- integrity sha512-LPnodUl3lS0/4wN3Rb+m+UK8s7lj2jcLRrjho4gLw+OJs+I4bvGXshINesY5xx/apM+biTnQ9reDI8yj+0M5+Q==
+babel-plugin-polyfill-corejs2@^0.3.1, babel-plugin-polyfill-corejs2@^0.3.3:
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122"
+ integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==
dependencies:
"@babel/compat-data" "^7.17.7"
- "@babel/helper-define-polyfill-provider" "^0.3.2"
+ "@babel/helper-define-polyfill-provider" "^0.3.3"
semver "^6.1.1"
-babel-plugin-polyfill-corejs3@^0.5.2, babel-plugin-polyfill-corejs3@^0.5.3:
+babel-plugin-polyfill-corejs3@^0.5.2:
version "0.5.3"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz#d7e09c9a899079d71a8b670c6181af56ec19c5c7"
integrity sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw==
@@ -3818,6 +3904,14 @@ babel-plugin-polyfill-corejs3@^0.5.2, babel-plugin-polyfill-corejs3@^0.5.3:
"@babel/helper-define-polyfill-provider" "^0.3.2"
core-js-compat "^3.21.0"
+babel-plugin-polyfill-corejs3@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz#56ad88237137eade485a71b52f72dbed57c6230a"
+ integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==
+ dependencies:
+ "@babel/helper-define-polyfill-provider" "^0.3.3"
+ core-js-compat "^3.25.1"
+
babel-plugin-polyfill-regenerator@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990"
@@ -3825,12 +3919,12 @@ babel-plugin-polyfill-regenerator@^0.3.1:
dependencies:
"@babel/helper-define-polyfill-provider" "^0.3.1"
-babel-plugin-polyfill-regenerator@^0.4.0:
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.0.tgz#8f51809b6d5883e07e71548d75966ff7635527fe"
- integrity sha512-RW1cnryiADFeHmfLS+WW/G431p1PsW5qdRdz0SDRi7TKcUgc7Oh/uXkT7MZ/+tGsT1BkczEAmD5XjUyJ5SWDTw==
+babel-plugin-polyfill-regenerator@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz#390f91c38d90473592ed43351e801a9d3e0fd747"
+ integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==
dependencies:
- "@babel/helper-define-polyfill-provider" "^0.3.2"
+ "@babel/helper-define-polyfill-provider" "^0.3.3"
babel-preset-current-node-syntax@^1.0.0:
version "1.0.1"
@@ -3868,7 +3962,7 @@ babel-runtime@6.x, babel-runtime@^6.26.0:
bail@^1.0.0:
version "1.0.5"
- resolved "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz"
+ resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776"
integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==
balanced-match@^1.0.0:
@@ -3878,7 +3972,7 @@ balanced-match@^1.0.0:
balanced-match@^2.0.0:
version "2.0.0"
- resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-2.0.0.tgz#dc70f920d78db8b858535795867bf48f820633d9"
integrity sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==
base64-js@^1.3.1:
@@ -3959,26 +4053,15 @@ browser-process-hrtime@^1.0.0:
resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626"
integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==
-browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.18.1, browserslist@^4.20.3, browserslist@^4.21.3:
- version "4.21.3"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a"
- integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==
+browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.18.1, browserslist@^4.20.2, browserslist@^4.20.3, browserslist@^4.21.3, browserslist@^4.21.4:
+ version "4.21.4"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987"
+ integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==
dependencies:
- caniuse-lite "^1.0.30001370"
- electron-to-chromium "^1.4.202"
+ caniuse-lite "^1.0.30001400"
+ electron-to-chromium "^1.4.251"
node-releases "^2.0.6"
- update-browserslist-db "^1.0.5"
-
-browserslist@^4.20.2:
- version "4.20.4"
- resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.20.4.tgz"
- integrity sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==
- dependencies:
- caniuse-lite "^1.0.30001349"
- electron-to-chromium "^1.4.147"
- escalade "^3.1.1"
- node-releases "^2.0.5"
- picocolors "^1.0.0"
+ update-browserslist-db "^1.0.9"
bs-logger@0.x:
version "0.2.6"
@@ -4042,15 +4125,15 @@ callsites@^3.0.0:
camel-case@^3.0.0:
version "3.0.0"
- resolved "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz"
- integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=
+ resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73"
+ integrity sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==
dependencies:
no-case "^2.2.0"
upper-case "^1.1.1"
camel-case@^4.1.2:
version "4.1.2"
- resolved "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz"
+ resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a"
integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==
dependencies:
pascal-case "^3.1.2"
@@ -4058,7 +4141,7 @@ camel-case@^4.1.2:
camelcase-keys@^6.2.2:
version "6.2.2"
- resolved "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz"
+ resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0"
integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==
dependencies:
camelcase "^5.3.1"
@@ -4085,19 +4168,14 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"
-caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001370, caniuse-lite@^1.0.30001373:
- version "1.0.30001382"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001382.tgz#4d37f0d0b6fffb826c8e5e1c0f4bf8ce592db949"
- integrity sha512-2rtJwDmSZ716Pxm1wCtbPvHtbDWAreTPxXbkc5RkKglow3Ig/4GNGazDI9/BVnXbG/wnv6r3B5FEbkfg9OcTGg==
-
-caniuse-lite@^1.0.30001349:
- version "1.0.30001352"
- resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001352.tgz"
- integrity sha512-GUgH8w6YergqPQDGWhJGt8GDRnY0L/iJVQcU3eJ46GYf52R8tk0Wxp0PymuFVZboJYXGiCqwozAYZNRjVj6IcA==
+caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001407:
+ version "1.0.30001418"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz#5f459215192a024c99e3e3a53aac310fc7cf24e6"
+ integrity sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==
capital-case@^1.0.4:
version "1.0.4"
- resolved "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/capital-case/-/capital-case-1.0.4.tgz#9d130292353c9249f6b00fa5852bee38a717e669"
integrity sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==
dependencies:
no-case "^3.0.4"
@@ -4124,25 +4202,25 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.2:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
-chalk@^4.0.0, chalk@^4.1.1, chalk@^4.1.2:
- version "4.1.2"
- resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
- integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
+chalk@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
+ integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
-chalk@^4.1.0:
- version "4.1.1"
- resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz"
- integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==
+chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
+ integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
change-case@^3.1.0:
version "3.1.0"
- resolved "https://registry.npmjs.org/change-case/-/change-case-3.1.0.tgz"
+ resolved "https://registry.yarnpkg.com/change-case/-/change-case-3.1.0.tgz#0e611b7edc9952df2e8513b27b42de72647dd17e"
integrity sha512-2AZp7uJZbYEzRPsFoa+ijKdvp9zsrnnt6+yFokfwEpeJm0xuJDVoxiRCAaTzyJND8GJkofo2IcKWaUZ/OECVzw==
dependencies:
camel-case "^3.0.0"
@@ -4166,7 +4244,7 @@ change-case@^3.1.0:
change-case@^4.1.1:
version "4.1.2"
- resolved "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz"
+ resolved "https://registry.yarnpkg.com/change-case/-/change-case-4.1.2.tgz#fedfc5f136045e2398c0410ee441f95704641e12"
integrity sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==
dependencies:
camel-case "^4.1.2"
@@ -4189,17 +4267,17 @@ char-regex@^1.0.2:
character-entities-legacy@^1.0.0:
version "1.1.4"
- resolved "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz"
+ resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1"
integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==
character-entities@^1.0.0:
version "1.2.4"
- resolved "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz"
+ resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b"
integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==
character-reference-invalid@^1.0.0:
version "1.1.4"
- resolved "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz"
+ resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560"
integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==
chardet@^0.7.0:
@@ -4228,13 +4306,13 @@ chrome-trace-event@^1.0.2:
integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==
ci-info@^3.2.0:
- version "3.3.2"
- resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.2.tgz#6d2967ffa407466481c6c90b6e16b3098f080128"
- integrity sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==
+ version "3.4.0"
+ resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.4.0.tgz#b28484fd436cbc267900364f096c9dc185efb251"
+ integrity sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==
circular-dependency-plugin@^5.2.2:
version "5.2.2"
- resolved "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz"
+ resolved "https://registry.yarnpkg.com/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz#39e836079db1d3cf2f988dc48c5188a44058b600"
integrity sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ==
cjs-module-lexer@^1.0.0:
@@ -4252,11 +4330,16 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
-classnames@2.3.1, classnames@2.x, classnames@^2.2.1, classnames@^2.2.5, classnames@^2.2.6, classnames@^2.3.1:
+classnames@2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
+classnames@2.x, classnames@^2.2.1, classnames@^2.2.5, classnames@^2.2.6, classnames@^2.3.1:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924"
+ integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==
+
clean-css@^5.2.2:
version "5.3.1"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.1.tgz#d0610b0b90d125196a2894d35366f734e5d7aa32"
@@ -4283,19 +4366,14 @@ cli-cursor@^3.1.0:
dependencies:
restore-cursor "^3.1.0"
-cli-spinners@^2.0.0:
- version "2.6.0"
- resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz"
- integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==
-
-cli-spinners@^2.5.0:
+cli-spinners@^2.0.0, cli-spinners@^2.5.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.7.0.tgz#f815fd30b5f9eaac02db604c7a231ed7cb2f797a"
integrity sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==
cli-truncate@^2.1.0:
version "2.1.0"
- resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz"
+ resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7"
integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==
dependencies:
slice-ansi "^3.0.0"
@@ -4303,7 +4381,7 @@ cli-truncate@^2.1.0:
cli-width@^3.0.0:
version "3.0.0"
- resolved "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6"
integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==
cliui@^7.0.2:
@@ -4317,7 +4395,7 @@ cliui@^7.0.2:
clone-regexp@^2.1.0:
version "2.2.0"
- resolved "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz"
+ resolved "https://registry.yarnpkg.com/clone-regexp/-/clone-regexp-2.2.0.tgz#7d65e00885cd8796405c35a737e7a86b7429e36f"
integrity sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==
dependencies:
is-regexp "^2.0.0"
@@ -4379,10 +4457,10 @@ colord@^2.9.1:
resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43"
integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==
-colorette@^1.2.2:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40"
- integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==
+colorette@^2.0.16:
+ version "2.0.19"
+ resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798"
+ integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==
combined-stream@^1.0.8:
version "1.0.8"
@@ -4403,7 +4481,7 @@ commander@2, commander@^2.20.0, commander@^2.20.3:
commander@^6.2.0:
version "6.2.1"
- resolved "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
commander@^7.2.0:
@@ -4417,9 +4495,9 @@ commander@^8.3.0:
integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
commander@^9.2.0:
- version "9.4.0"
- resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.0.tgz#bc4a40918fefe52e22450c111ecd6b7acce6f11c"
- integrity sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==
+ version "9.4.1"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd"
+ integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==
comment-parser@1.3.1:
version "1.3.1"
@@ -4455,15 +4533,15 @@ concat-map@0.0.1:
constant-case@^2.0.0:
version "2.0.0"
- resolved "https://registry.npmjs.org/constant-case/-/constant-case-2.0.0.tgz"
- integrity sha1-QXV2TTidP6nI7NKRhu1gBSQ7akY=
+ resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-2.0.0.tgz#4175764d389d3fa9c8ecd29186ed6005243b6a46"
+ integrity sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ==
dependencies:
snake-case "^2.1.0"
upper-case "^1.1.1"
constant-case@^3.0.4:
version "3.0.4"
- resolved "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-3.0.4.tgz#3b84a9aeaf4cf31ec45e6bf5de91bdfb0589faf1"
integrity sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==
dependencies:
no-case "^3.0.4"
@@ -4489,13 +4567,6 @@ copy-descriptor@^0.1.0:
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==
-copy-to-clipboard@^3:
- version "3.3.1"
- resolved "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz"
- integrity sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==
- dependencies:
- toggle-selection "^1.0.6"
-
copy-to-clipboard@^3.3.1:
version "3.3.2"
resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.2.tgz#5b263ec2366224b100181dded7ce0579b340c107"
@@ -4527,18 +4598,17 @@ copy-webpack-plugin@^9.0.1:
schema-utils "^3.1.1"
serialize-javascript "^6.0.0"
-core-js-compat@^3.21.0, core-js-compat@^3.22.1:
- version "3.24.1"
- resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.24.1.tgz#d1af84a17e18dfdd401ee39da9996f9a7ba887de"
- integrity sha512-XhdNAGeRnTpp8xbD+sR/HFDK9CbeeeqXT6TuofXh3urqEevzkWmLRgrVoykodsw8okqo2pu1BOmuCKrHx63zdw==
+core-js-compat@^3.21.0, core-js-compat@^3.25.1:
+ version "3.25.5"
+ resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.25.5.tgz#0016e8158c904f7b059486639e6e82116eafa7d9"
+ integrity sha512-ovcyhs2DEBUIE0MGEKHP4olCUW/XYte3Vroyxuh38rD1wAO4dHohsovUC4eAOuzFxE6b+RXvBU3UZ9o0YhUTkA==
dependencies:
- browserslist "^4.21.3"
- semver "7.0.0"
+ browserslist "^4.21.4"
-core-js-pure@^3.15.0:
- version "3.15.1"
- resolved "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.15.1.tgz"
- integrity sha512-OZuWHDlYcIda8sJLY4Ec6nWq2hRjlyCqCZ+jCflyleMkVt3tPedDVErvHslyS2nbO+SlBFMSBJYvtLMwxnrzjA==
+core-js-pure@^3.25.1:
+ version "3.25.5"
+ resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.25.5.tgz#79716ba54240c6aa9ceba6eee08cf79471ba184d"
+ integrity sha512-oml3M22pHM+igfWHDfdLVq2ShWmjM2V4L+dQEBs0DWVIqEm9WHCwGAlZ6BmyBQGy5sFrJmcx+856D9lVKyGWYg==
core-js@3.24.0:
version "3.24.0"
@@ -4561,18 +4631,7 @@ cosmiconfig@^6.0.0:
path-type "^4.0.0"
yaml "^1.7.2"
-cosmiconfig@^7.0.0:
- version "7.0.0"
- resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz"
- integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==
- dependencies:
- "@types/parse-json" "^4.0.0"
- import-fresh "^3.2.1"
- parse-json "^5.0.0"
- path-type "^4.0.0"
- yaml "^1.10.0"
-
-cosmiconfig@^7.0.1:
+cosmiconfig@^7.0.0, cosmiconfig@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d"
integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==
@@ -4620,9 +4679,9 @@ css-box-model@^1.2.0:
tiny-invariant "^1.0.6"
css-declaration-sorter@^6.3.0:
- version "6.3.0"
- resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.3.0.tgz#72ebd995c8f4532ff0036631f7365cce9759df14"
- integrity sha512-OGT677UGHJTAVMRhPO+HJ4oKln3wkBTwtDFH0ojbqm+MJm6xuDMHp2nkhh/ThaBqq20IbraBQSWKfSLNHQO9Og==
+ version "6.3.1"
+ resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz#be5e1d71b7a992433fb1c542c7a1b835e45682ec"
+ integrity sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==
css-has-pseudo@^3.0.4:
version "3.0.4"
@@ -4655,8 +4714,8 @@ css-loader@^6.7.1:
css-mediaquery@^0.1.2:
version "0.1.2"
- resolved "https://registry.npmjs.org/css-mediaquery/-/css-mediaquery-0.1.2.tgz"
- integrity sha1-aiw3NEkoYYYxxUvTPO3TAdoYvqA=
+ resolved "https://registry.yarnpkg.com/css-mediaquery/-/css-mediaquery-0.1.2.tgz#6a2c37344928618631c54bd33cedd301da18bea0"
+ integrity sha512-COtn4EROW5dBGlE/4PiKnh6rZpAPxDeFLaEEwt4i10jpDMFt2EhQGS79QmmrO+iKCHv0PU/HrOWEhijFd1x99Q==
css-minimizer-webpack-plugin@^3.4.1:
version "3.4.1"
@@ -4699,6 +4758,11 @@ css-what@^6.0.1:
resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
+css.escape@^1.5.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb"
+ integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==
+
csscolorparser@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/csscolorparser/-/csscolorparser-1.0.3.tgz#b34f391eea4da8f3e98231e2ccd8df9c041f171b"
@@ -4798,9 +4862,9 @@ cssstyle@^2.3.0:
cssom "~0.3.6"
csstype@^3.0.2, csstype@^3.0.6:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2"
- integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9"
+ integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==
d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0:
version "1.2.4"
@@ -5069,7 +5133,7 @@ dayjs@^1.11.5:
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.5.tgz#00e8cc627f231f9499c19b38af49f56dc0ac5e93"
integrity sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA==
-debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
+debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -5085,35 +5149,28 @@ debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9:
debug@^3.1.0, debug@^3.2.6, debug@^3.2.7:
version "3.2.7"
- resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
dependencies:
ms "^2.1.1"
-debug@^4.2.0:
- version "4.3.2"
- resolved "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz"
- integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
- dependencies:
- ms "2.1.2"
-
decamelize-keys@^1.1.0:
version "1.1.0"
- resolved "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz"
- integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=
+ resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9"
+ integrity sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==
dependencies:
decamelize "^1.1.0"
map-obj "^1.0.0"
decamelize@^1.1.0, decamelize@^1.2.0:
version "1.2.0"
- resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz"
- integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
+ resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
+ integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
decimal.js@^10.2.1:
- version "10.4.0"
- resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.0.tgz#97a7448873b01e92e5ff9117d89a7bca8e63e0fe"
- integrity sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==
+ version "10.4.1"
+ resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.1.tgz#be75eeac4a2281aace80c1a8753587c27ef053e7"
+ integrity sha512-F29o+vci4DodHYT9UrR5IEbfBw9pE5eSapIJdTqXK5+6hq+t8VRxwQyKlW2i+KDKFkkJQRvFyI/QXD83h8LyQw==
decode-uri-component@^0.2.0:
version "0.2.0"
@@ -5122,8 +5179,8 @@ decode-uri-component@^0.2.0:
dedent@^0.7.0:
version "0.7.0"
- resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz"
- integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=
+ resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
+ integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==
deep-is@^0.1.3, deep-is@~0.1.3:
version "0.1.4"
@@ -5179,7 +5236,7 @@ define-property@^2.0.2:
del@^5.1.0:
version "5.1.0"
- resolved "https://registry.npmjs.org/del/-/del-5.1.0.tgz"
+ resolved "https://registry.yarnpkg.com/del/-/del-5.1.0.tgz#d9487c94e367410e6eff2925ee58c0c84a75b3a7"
integrity sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==
dependencies:
globby "^10.0.1"
@@ -5198,8 +5255,8 @@ delayed-stream@~1.0.0:
detect-file@^1.0.0:
version "1.0.0"
- resolved "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz"
- integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=
+ resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"
+ integrity sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==
detect-newline@^3.0.0:
version "3.1.0"
@@ -5219,6 +5276,11 @@ diff-sequences@^27.5.1:
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327"
integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==
+diff-sequences@^29.0.0:
+ version "29.0.0"
+ resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.0.0.tgz#bae49972ef3933556bcb0800b72e8579d19d9e4f"
+ integrity sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==
+
diff@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
@@ -5250,7 +5312,7 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
-dom-accessibility-api@^0.5.9:
+dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9:
version "0.5.14"
resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz#56082f71b1dc7aac69d83c4285eef39c15d93f56"
integrity sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg==
@@ -5303,7 +5365,7 @@ dom-serializer@^1.0.1:
domelementtype@1, domelementtype@^1.3.1:
version "1.3.1"
- resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
domelementtype@^2.0.1, domelementtype@^2.2.0:
@@ -5320,7 +5382,7 @@ domexception@^2.0.1:
domhandler@^2.3.0:
version "2.4.2"
- resolved "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803"
integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==
dependencies:
domelementtype "1"
@@ -5333,13 +5395,13 @@ domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1:
domelementtype "^2.2.0"
dompurify@^2.3.12:
- version "2.3.12"
- resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.12.tgz#0c8a5cabc5d7a7cf2635645cfd5061deab73f3d2"
- integrity sha512-KkCEdpWPXBkF9IP9afmYPDB24nRZRUsThsjuWKM8Cpp9+WXKJmC6FZxSyPIiiQezkYa3+Mm1oo6dh60NxBXkyw==
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.0.tgz#c9c88390f024c2823332615c9e20a453cf3825dd"
+ integrity sha512-Be9tbQMZds4a3C6xTmz68NlMfeONA//4dOavl/1rNw50E+/QO0KVpbcU0PcaW0nsQxurXls9ZocqFxk8R2mWEA==
domutils@^1.5.1:
version "1.7.0"
- resolved "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==
dependencies:
dom-serializer "0"
@@ -5356,14 +5418,14 @@ domutils@^2.5.2, domutils@^2.8.0:
dot-case@^2.1.0:
version "2.1.1"
- resolved "https://registry.npmjs.org/dot-case/-/dot-case-2.1.1.tgz"
- integrity sha1-NNzzf1Co6TwrO8qLt/uRVcfaO+4=
+ resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-2.1.1.tgz#34dcf37f50a8e93c2b3bca8bb7fb9155c7da3bee"
+ integrity sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug==
dependencies:
no-case "^2.2.0"
dot-case@^3.0.4:
version "3.0.4"
- resolved "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751"
integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==
dependencies:
no-case "^3.0.4"
@@ -5371,18 +5433,13 @@ dot-case@^3.0.4:
duplexer@^0.1.2:
version "0.1.2"
- resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz"
+ resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==
-electron-to-chromium@^1.4.147:
- version "1.4.152"
- resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.152.tgz"
- integrity sha512-jk4Ju5SGZAQQJ1iI4Rgru7dDlvkQPLpNPWH9gIZmwCD4YteA5Bbk1xPcPDUf5jUYs3e1e80RXdi8XgKQZaigeg==
-
-electron-to-chromium@^1.4.202:
- version "1.4.228"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.228.tgz#3baff13cf54198c2045f9bdd8b64db93aafd7f33"
- integrity sha512-XfDHCvou7CsDMlFwb0WZ1tWmW48e7Sn7VBRyPfZsZZila9esRsJl1trO+OqDNV97GggFSt0ISbWslKXfQkG//g==
+electron-to-chromium@^1.4.251:
+ version "1.4.275"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.275.tgz#db25c8e39c9cc910a996d1ec9b73eee834cb0ac1"
+ integrity sha512-aJeQQ+Hl9Jyyzv4chBqYJwmVRY46N5i2BEX5Cuyk/5gFCUZ5F3i7Hnba6snZftWla7Gglwc5pIgcd+E7cW+rPg==
emittery@^0.8.1:
version "0.8.1"
@@ -5391,7 +5448,7 @@ emittery@^0.8.1:
emoji-regex@^6.4.1:
version "6.5.1"
- resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.5.1.tgz#9baea929b155565c11ea41c6626eaa65cef992c2"
integrity sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==
emoji-regex@^8.0.0:
@@ -5421,14 +5478,14 @@ enhanced-resolve@^5.0.0, enhanced-resolve@^5.10.0:
enquirer@^2.3.6:
version "2.3.6"
- resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz"
+ resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d"
integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==
dependencies:
ansi-colors "^4.1.1"
entities@^1.1.1:
version "1.1.2"
- resolved "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
entities@^2.0.0:
@@ -5457,57 +5514,32 @@ error-stack-parser@^2.0.6:
dependencies:
stackframe "^1.3.4"
-es-abstract@^1.19.0:
- version "1.19.1"
- resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz"
- integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==
- dependencies:
- call-bind "^1.0.2"
- es-to-primitive "^1.2.1"
- function-bind "^1.1.1"
- get-intrinsic "^1.1.1"
- get-symbol-description "^1.0.0"
- has "^1.0.3"
- has-symbols "^1.0.2"
- internal-slot "^1.0.3"
- is-callable "^1.2.4"
- is-negative-zero "^2.0.1"
- is-regex "^1.1.4"
- is-shared-array-buffer "^1.0.1"
- is-string "^1.0.7"
- is-weakref "^1.0.1"
- object-inspect "^1.11.0"
- object-keys "^1.1.1"
- object.assign "^4.1.2"
- string.prototype.trimend "^1.0.4"
- string.prototype.trimstart "^1.0.4"
- unbox-primitive "^1.0.1"
-
-es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5:
- version "1.20.1"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814"
- integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==
+es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5:
+ version "1.20.4"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.4.tgz#1d103f9f8d78d4cf0713edcd6d0ed1a46eed5861"
+ integrity sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==
dependencies:
call-bind "^1.0.2"
es-to-primitive "^1.2.1"
function-bind "^1.1.1"
function.prototype.name "^1.1.5"
- get-intrinsic "^1.1.1"
+ get-intrinsic "^1.1.3"
get-symbol-description "^1.0.0"
has "^1.0.3"
has-property-descriptors "^1.0.0"
has-symbols "^1.0.3"
internal-slot "^1.0.3"
- is-callable "^1.2.4"
+ is-callable "^1.2.7"
is-negative-zero "^2.0.2"
is-regex "^1.1.4"
is-shared-array-buffer "^1.0.2"
is-string "^1.0.7"
is-weakref "^1.0.2"
- object-inspect "^1.12.0"
+ object-inspect "^1.12.2"
object-keys "^1.1.1"
- object.assign "^4.1.2"
+ object.assign "^4.1.4"
regexp.prototype.flags "^1.4.3"
+ safe-regex-test "^1.0.0"
string.prototype.trimend "^1.0.5"
string.prototype.trimstart "^1.0.5"
unbox-primitive "^1.0.2"
@@ -5572,38 +5604,37 @@ eslint-config-prettier@8.5.0:
eslint-import-resolver-node@^0.3.6:
version "0.3.6"
- resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz"
+ resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd"
integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==
dependencies:
debug "^3.2.7"
resolve "^1.20.0"
-eslint-module-utils@^2.7.2:
- version "2.7.3"
- resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz"
- integrity sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==
+eslint-module-utils@^2.7.3:
+ version "2.7.4"
+ resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974"
+ integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==
dependencies:
debug "^3.2.7"
- find-up "^2.1.0"
eslint-plugin-import@^2.25.4:
- version "2.25.4"
- resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz"
- integrity sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==
+ version "2.26.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b"
+ integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==
dependencies:
array-includes "^3.1.4"
array.prototype.flat "^1.2.5"
debug "^2.6.9"
doctrine "^2.1.0"
eslint-import-resolver-node "^0.3.6"
- eslint-module-utils "^2.7.2"
+ eslint-module-utils "^2.7.3"
has "^1.0.3"
- is-core-module "^2.8.0"
+ is-core-module "^2.8.1"
is-glob "^4.0.3"
- minimatch "^3.0.4"
+ minimatch "^3.1.2"
object.values "^1.1.5"
- resolve "^1.20.0"
- tsconfig-paths "^3.12.0"
+ resolve "^1.22.0"
+ tsconfig-paths "^3.14.1"
eslint-plugin-jsdoc@38.0.6:
version "38.0.6"
@@ -5619,12 +5650,25 @@ eslint-plugin-jsdoc@38.0.6:
semver "^7.3.5"
spdx-expression-parse "^3.0.1"
+eslint-plugin-jsdoc@^39.3.14:
+ version "39.3.14"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.3.14.tgz#2591bf48907a7527a6e689fd721634364d08fe4e"
+ integrity sha512-kle7ot5xvzXwWzg7ElzTPM/y1IWUo0kfa5X+ZwOC/7Jw81OJaqIaNEk+2ZH+HcKkbwRUQ3RTdK9qsm4p5vbXAQ==
+ dependencies:
+ "@es-joy/jsdoccomment" "~0.33.0"
+ comment-parser "1.3.1"
+ debug "^4.3.4"
+ escape-string-regexp "^4.0.0"
+ esquery "^1.4.0"
+ semver "^7.3.8"
+ spdx-expression-parse "^3.0.1"
+
eslint-plugin-react-hooks@4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172"
integrity sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==
-eslint-plugin-react-hooks@4.6.0:
+eslint-plugin-react-hooks@4.6.0, eslint-plugin-react-hooks@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3"
integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==
@@ -5649,9 +5693,29 @@ eslint-plugin-react@7.29.4:
semver "^6.3.0"
string.prototype.matchall "^4.0.6"
+eslint-plugin-react@^7.31.10:
+ version "7.31.10"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.31.10.tgz#6782c2c7fe91c09e715d536067644bbb9491419a"
+ integrity sha512-e4N/nc6AAlg4UKW/mXeYWd3R++qUano5/o+t+wnWxIf+bLsOaH3a4q74kX3nDjYym3VBN4HyO9nEn1GcAqgQOA==
+ dependencies:
+ array-includes "^3.1.5"
+ array.prototype.flatmap "^1.3.0"
+ doctrine "^2.1.0"
+ estraverse "^5.3.0"
+ jsx-ast-utils "^2.4.1 || ^3.0.0"
+ minimatch "^3.1.2"
+ object.entries "^1.1.5"
+ object.fromentries "^2.0.5"
+ object.hasown "^1.1.1"
+ object.values "^1.1.5"
+ prop-types "^15.8.1"
+ resolve "^2.0.0-next.3"
+ semver "^6.3.0"
+ string.prototype.matchall "^4.0.7"
+
eslint-plugin-rulesdir@^0.2.1:
version "0.2.1"
- resolved "https://registry.npmjs.org/eslint-plugin-rulesdir/-/eslint-plugin-rulesdir-0.2.1.tgz"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-rulesdir/-/eslint-plugin-rulesdir-0.2.1.tgz#e246bb9657e68eb0a30680c60775f40aa829ec0b"
integrity sha512-t7rQvEyfE4JZJu6dPl4/uVr6Fr0fxopBhzVbtq3isfOHMKdlIe9xW/5CtIaWZI0E1U+wzAk0lEnZC8laCD5YLA==
eslint-scope@5.1.1, eslint-scope@^5.1.1:
@@ -5769,6 +5833,50 @@ eslint@8.20.0:
text-table "^0.2.0"
v8-compile-cache "^2.0.3"
+eslint@^8.25.0:
+ version "8.25.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.25.0.tgz#00eb962f50962165d0c4ee3327708315eaa8058b"
+ integrity sha512-DVlJOZ4Pn50zcKW5bYH7GQK/9MsoQG2d5eDH0ebEkE8PbgzTTmtt/VTH9GGJ4BfeZCpBLqFfvsjX35UacUL83A==
+ dependencies:
+ "@eslint/eslintrc" "^1.3.3"
+ "@humanwhocodes/config-array" "^0.10.5"
+ "@humanwhocodes/module-importer" "^1.0.1"
+ ajv "^6.10.0"
+ chalk "^4.0.0"
+ cross-spawn "^7.0.2"
+ debug "^4.3.2"
+ doctrine "^3.0.0"
+ escape-string-regexp "^4.0.0"
+ eslint-scope "^7.1.1"
+ eslint-utils "^3.0.0"
+ eslint-visitor-keys "^3.3.0"
+ espree "^9.4.0"
+ esquery "^1.4.0"
+ esutils "^2.0.2"
+ fast-deep-equal "^3.1.3"
+ file-entry-cache "^6.0.1"
+ find-up "^5.0.0"
+ glob-parent "^6.0.1"
+ globals "^13.15.0"
+ globby "^11.1.0"
+ grapheme-splitter "^1.0.4"
+ ignore "^5.2.0"
+ import-fresh "^3.0.0"
+ imurmurhash "^0.1.4"
+ is-glob "^4.0.0"
+ js-sdsl "^4.1.4"
+ js-yaml "^4.1.0"
+ json-stable-stringify-without-jsonify "^1.0.1"
+ levn "^0.4.1"
+ lodash.merge "^4.6.2"
+ minimatch "^3.1.2"
+ natural-compare "^1.4.0"
+ optionator "^0.9.1"
+ regexpp "^3.2.0"
+ strip-ansi "^6.0.1"
+ strip-json-comments "^3.1.0"
+ text-table "^0.2.0"
+
espree@^9.3.1, espree@^9.3.2:
version "9.3.3"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.3.tgz#2dd37c4162bb05f433ad3c1a52ddf8a49dc08e9d"
@@ -5778,6 +5886,15 @@ espree@^9.3.1, espree@^9.3.2:
acorn-jsx "^5.3.2"
eslint-visitor-keys "^3.3.0"
+espree@^9.4.0:
+ version "9.4.0"
+ resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a"
+ integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==
+ dependencies:
+ acorn "^8.8.0"
+ acorn-jsx "^5.3.2"
+ eslint-visitor-keys "^3.3.0"
+
esprima@^4.0.0, esprima@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
@@ -5829,7 +5946,7 @@ events@^3.2.0:
execa@^4.1.0:
version "4.1.0"
- resolved "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz"
+ resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a"
integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==
dependencies:
cross-spawn "^7.0.0"
@@ -5859,7 +5976,7 @@ execa@^5.0.0, execa@^5.1.1:
execall@^2.0.0:
version "2.0.0"
- resolved "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/execall/-/execall-2.0.0.tgz#16a06b5fe5099df7d00be5d9c06eecded1663b45"
integrity sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==
dependencies:
clone-regexp "^2.1.0"
@@ -5889,8 +6006,8 @@ expand-brackets@^2.1.4:
expand-tilde@^2.0.0, expand-tilde@^2.0.2:
version "2.0.2"
- resolved "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz"
- integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=
+ resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502"
+ integrity sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==
dependencies:
homedir-polyfill "^1.0.1"
@@ -5904,6 +6021,17 @@ expect@^27.5.1:
jest-matcher-utils "^27.5.1"
jest-message-util "^27.5.1"
+expect@^29.0.0:
+ version "29.1.2"
+ resolved "https://registry.yarnpkg.com/expect/-/expect-29.1.2.tgz#82f8f28d7d408c7c68da3a386a490ee683e1eced"
+ integrity sha512-AuAGn1uxva5YBbBlXb+2JPxJRuemZsmlGcapPXWNSBNsQtAULfjioREGBWuI0EOvYUKjDnrCy8PW5Zlr1md5mw==
+ dependencies:
+ "@jest/expect-utils" "^29.1.2"
+ jest-get-type "^29.0.0"
+ jest-matcher-utils "^29.1.2"
+ jest-message-util "^29.1.2"
+ jest-util "^29.1.2"
+
extend-shallow@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
@@ -5921,7 +6049,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
extend@^3.0.0:
version "3.0.2"
- resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz"
+ resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
external-editor@^3.0.3:
@@ -5952,10 +6080,15 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
+fast-diff@^1.1.2:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03"
+ integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==
+
fast-glob@^3.0.3, fast-glob@^3.2.11, fast-glob@^3.2.5, fast-glob@^3.2.7, fast-glob@^3.2.9:
- version "3.2.11"
- resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz"
- integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==
+ version "3.2.12"
+ resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80"
+ integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==
dependencies:
"@nodelib/fs.stat" "^2.0.2"
"@nodelib/fs.walk" "^1.2.3"
@@ -5979,9 +6112,9 @@ fast-shallow-equal@^1.0.0:
integrity sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==
fastest-levenshtein@^1.0.12:
- version "1.0.12"
- resolved "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz"
- integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==
+ version "1.0.16"
+ resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5"
+ integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==
fastest-stable-stringify@^2.0.2:
version "2.0.2"
@@ -5996,9 +6129,9 @@ fastq@^1.6.0:
reusify "^1.0.4"
fb-watchman@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85"
- integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c"
+ integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==
dependencies:
bser "2.1.1"
@@ -6055,8 +6188,8 @@ fill-range@^7.0.1:
filter-obj@^1.1.0:
version "1.1.0"
- resolved "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz"
- integrity sha1-mzERErxsYSehbgFsbF1/GeCAXFs=
+ resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b"
+ integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==
find-cache-dir@^3.3.1:
version "3.3.2"
@@ -6072,13 +6205,6 @@ find-root@^1.1.0:
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
-find-up@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz"
- integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c=
- dependencies:
- locate-path "^2.0.0"
-
find-up@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
@@ -6104,8 +6230,8 @@ find-up@^5.0.0:
findup-sync@^2.0.0:
version "2.0.0"
- resolved "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz"
- integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=
+ resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc"
+ integrity sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g==
dependencies:
detect-file "^1.0.0"
is-glob "^3.1.0"
@@ -6114,7 +6240,7 @@ findup-sync@^2.0.0:
fined@^1.0.1:
version "1.2.0"
- resolved "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz"
+ resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b"
integrity sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==
dependencies:
expand-tilde "^2.0.2"
@@ -6125,7 +6251,7 @@ fined@^1.0.1:
flagged-respawn@^1.0.0:
version "1.0.1"
- resolved "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz"
+ resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41"
integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==
flat-cache@^3.0.4:
@@ -6142,19 +6268,19 @@ flatted@^3.1.0:
integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
follow-redirects@^1.0.0, follow-redirects@^1.14.8:
- version "1.15.1"
- resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5"
- integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==
+ version "1.15.2"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
+ integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
for-in@^1.0.1, for-in@^1.0.2:
version "1.0.2"
- resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz"
- integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=
+ resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
+ integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==
for-own@^1.0.0:
version "1.0.0"
- resolved "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz"
- integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=
+ resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b"
+ integrity sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==
dependencies:
for-in "^1.0.1"
@@ -6303,10 +6429,10 @@ get-document@1:
resolved "https://registry.yarnpkg.com/get-document/-/get-document-1.0.0.tgz#4821bce66f1c24cb0331602be6cb6b12c4f01c4b"
integrity sha512-8E7H2Xxibav+/rQTTtm6gFlSQwDoAQg667yheA+vWQr/amxEuswChzGo4MIbOJJoR0SMpDyhbUqWp3FpIfwD9A==
-get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598"
- integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==
+get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385"
+ integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==
dependencies:
function-bind "^1.1.1"
has "^1.0.3"
@@ -6314,7 +6440,7 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
get-own-enumerable-property-symbols@^3.0.0:
version "3.0.2"
- resolved "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz"
+ resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==
get-package-type@^0.1.0:
@@ -6324,7 +6450,7 @@ get-package-type@^0.1.0:
get-stdin@^8.0.0:
version "8.0.0"
- resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53"
integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==
get-stream@^5.0.0:
@@ -6399,7 +6525,7 @@ glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
global-modules@^1.0.0:
version "1.0.0"
- resolved "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea"
integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==
dependencies:
global-prefix "^1.0.1"
@@ -6408,15 +6534,15 @@ global-modules@^1.0.0:
global-modules@^2.0.0:
version "2.0.0"
- resolved "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780"
integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==
dependencies:
global-prefix "^3.0.0"
global-prefix@^1.0.1:
version "1.0.2"
- resolved "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz"
- integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=
+ resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe"
+ integrity sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==
dependencies:
expand-tilde "^2.0.2"
homedir-polyfill "^1.0.1"
@@ -6459,9 +6585,9 @@ globby@^10.0.1:
merge2 "^1.2.3"
slash "^3.0.0"
-globby@^11.0.3, globby@^11.0.4:
+globby@^11.0.3, globby@^11.0.4, globby@^11.1.0:
version "11.1.0"
- resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b"
integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==
dependencies:
array-union "^2.1.0"
@@ -6484,12 +6610,12 @@ globby@^13.1.1:
globjoin@^0.1.4:
version "0.1.4"
- resolved "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz"
- integrity sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=
+ resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43"
+ integrity sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==
gonzales-pe@^4.3.0:
version "4.3.0"
- resolved "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz"
+ resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.3.0.tgz#fe9dec5f3c557eead09ff868c65826be54d067b3"
integrity sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==
dependencies:
minimist "^1.2.5"
@@ -6499,16 +6625,21 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2,
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
+grapheme-splitter@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e"
+ integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
+
gzip-size@^6.0.0:
version "6.0.0"
- resolved "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462"
integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==
dependencies:
duplexer "^0.1.2"
handlebars@^4.4.3:
version "4.7.7"
- resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz"
+ resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1"
integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==
dependencies:
minimist "^1.2.5"
@@ -6520,7 +6651,7 @@ handlebars@^4.4.3:
hard-rejection@^2.1.0:
version "2.1.0"
- resolved "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz"
+ resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883"
integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==
has-ansi@^2.0.0:
@@ -6609,15 +6740,15 @@ he@^1.2.0:
header-case@^1.0.0:
version "1.0.1"
- resolved "https://registry.npmjs.org/header-case/-/header-case-1.0.1.tgz"
- integrity sha1-lTWXMZfBRLCWE81l0xfvGZY70C0=
+ resolved "https://registry.yarnpkg.com/header-case/-/header-case-1.0.1.tgz#9535973197c144b09613cd65d317ef19963bd02d"
+ integrity sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==
dependencies:
no-case "^2.2.0"
upper-case "^1.1.3"
header-case@^2.0.4:
version "2.0.4"
- resolved "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/header-case/-/header-case-2.0.4.tgz#5a42e63b55177349cf405beb8d775acabb92c063"
integrity sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==
dependencies:
capital-case "^1.0.4"
@@ -6630,7 +6761,7 @@ highlight-words-core@^1.2.0:
history@4.10.1, history@^4.9.0:
version "4.10.1"
- resolved "https://registry.npmjs.org/history/-/history-4.10.1.tgz"
+ resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3"
integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==
dependencies:
"@babel/runtime" "^7.1.2"
@@ -6642,14 +6773,14 @@ history@4.10.1, history@^4.9.0:
hoist-non-react-statics@3.3.2, hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2:
version "3.3.2"
- resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz"
+ resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
dependencies:
react-is "^16.7.0"
homedir-polyfill@^1.0.1:
version "1.0.3"
- resolved "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz"
+ resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8"
integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==
dependencies:
parse-passwd "^1.0.0"
@@ -6660,9 +6791,9 @@ hosted-git-info@^2.1.4:
integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
hosted-git-info@^4.0.1:
- version "4.0.2"
- resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz"
- integrity sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224"
+ integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==
dependencies:
lru-cache "^6.0.0"
@@ -6701,7 +6832,7 @@ html-minifier-terser@^6.0.2:
html-tags@^3.1.0:
version "3.2.0"
- resolved "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz"
+ resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.2.0.tgz#dbb3518d20b726524e4dd43de397eb0a95726961"
integrity sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==
html-webpack-plugin@^5.5.0:
@@ -6717,7 +6848,7 @@ html-webpack-plugin@^5.5.0:
htmlparser2@^3.10.0:
version "3.10.1"
- resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==
dependencies:
domelementtype "^1.3.1"
@@ -6786,7 +6917,7 @@ human-signals@^2.1.0:
hyphenate-style-name@^1.0.0, hyphenate-style-name@^1.0.2:
version "1.0.4"
- resolved "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d"
integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==
iconv-lite@0.4, iconv-lite@0.4.24, iconv-lite@^0.4.24:
@@ -6815,7 +6946,7 @@ ieee754@^1.1.12, ieee754@^1.1.13:
ignore@^5.1.1, ignore@^5.1.8, ignore@^5.2.0:
version "5.2.0"
- resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
image-size@~0.5.0:
@@ -6843,7 +6974,7 @@ import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1:
import-lazy@^4.0.0:
version "4.0.0"
- resolved "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153"
integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==
import-local@^3.0.2:
@@ -6891,7 +7022,7 @@ inline-style-prefixer@^6.0.0:
inquirer@^7.1.0:
version "7.3.3"
- resolved "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz"
+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003"
integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==
dependencies:
ansi-escapes "^4.2.1"
@@ -6940,29 +7071,29 @@ internal-slot@^1.0.3:
interpret@^1.2.0:
version "1.4.0"
- resolved "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz"
+ resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
intl-messageformat@^10.1.0:
- version "10.1.3"
- resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.1.3.tgz#7252cc978b7f3a7e539589c58f37800a718477fb"
- integrity sha512-olvdXBZITgfA/9ShzrjcsNidTXd/uGw3H8oWcjysw2lF8txF4MtO9nSWR3exPR6PhTtrrWl+BriucmsITI8Mmw==
+ version "10.1.5"
+ resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.1.5.tgz#ec053e0367ee5e4d40a9448ddbb9fff143266a9d"
+ integrity sha512-bDQz81oQ6TkQp1pSnlBK36ahGL5/tLb0+3hSiG/1/SnVbz5NWPQTqaPx2cT7nmGujDrPn9pQ0ik8RWE8v1lzEw==
dependencies:
- "@formatjs/ecma402-abstract" "1.11.10"
+ "@formatjs/ecma402-abstract" "1.12.0"
"@formatjs/fast-memoize" "1.2.6"
- "@formatjs/icu-messageformat-parser" "2.1.6"
+ "@formatjs/icu-messageformat-parser" "2.1.8"
tslib "2.4.0"
invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.4:
version "2.2.4"
- resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz"
+ resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
dependencies:
loose-envify "^1.0.0"
is-absolute@^1.0.0:
version "1.0.0"
- resolved "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576"
integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==
dependencies:
is-relative "^1.0.0"
@@ -6984,12 +7115,12 @@ is-accessor-descriptor@^1.0.0:
is-alphabetical@^1.0.0:
version "1.0.4"
- resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d"
integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==
is-alphanumerical@^1.0.0:
version "1.0.4"
- resolved "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf"
integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==
dependencies:
is-alphabetical "^1.0.0"
@@ -7029,15 +7160,15 @@ is-buffer@^1.1.5:
is-buffer@^2.0.0:
version "2.0.5"
- resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz"
+ resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191"
integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
-is-callable@^1.1.4, is-callable@^1.2.4:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945"
- integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==
+is-callable@^1.1.4, is-callable@^1.2.7:
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
+ integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
-is-core-module@^2.2.0, is-core-module@^2.8.0, is-core-module@^2.9.0:
+is-core-module@^2.5.0, is-core-module@^2.8.1, is-core-module@^2.9.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed"
integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==
@@ -7067,7 +7198,7 @@ is-date-object@^1.0.1:
is-decimal@^1.0.0:
version "1.0.4"
- resolved "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5"
integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==
is-descriptor@^0.1.0:
@@ -7129,14 +7260,14 @@ is-glob@^3.1.0:
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
version "4.0.3"
- resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz"
+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
dependencies:
is-extglob "^2.1.1"
is-hexadecimal@^1.0.0:
version "1.0.4"
- resolved "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7"
integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==
is-hotkey@0.1.4:
@@ -7161,12 +7292,12 @@ is-interactive@^1.0.0:
is-lower-case@^1.1.0:
version "1.1.3"
- resolved "https://registry.npmjs.org/is-lower-case/-/is-lower-case-1.1.3.tgz"
- integrity sha1-fhR75HaNxGbbO/shzGCzHmrWk5M=
+ resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-1.1.3.tgz#7e147be4768dc466db3bfb21cc60b31e6ad69393"
+ integrity sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==
dependencies:
lower-case "^1.1.0"
-is-negative-zero@^2.0.1, is-negative-zero@^2.0.2:
+is-negative-zero@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150"
integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==
@@ -7192,27 +7323,27 @@ is-number@^7.0.0:
is-obj@^1.0.1:
version "1.0.1"
- resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz"
- integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8=
+ resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
+ integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==
is-path-cwd@^2.2.0:
version "2.2.0"
- resolved "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz"
+ resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb"
integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==
is-path-inside@^3.0.1:
version "3.0.3"
- resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz"
+ resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
is-plain-obj@^1.1.0:
version "1.1.0"
- resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz"
- integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4=
+ resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
+ integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==
is-plain-obj@^2.0.0:
version "2.1.0"
- resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz"
+ resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
is-plain-obj@^3.0.0:
@@ -7242,17 +7373,17 @@ is-regex@^1.1.4:
is-regexp@^1.0.0:
version "1.0.0"
- resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz"
- integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk=
+ resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
+ integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==
is-regexp@^2.0.0:
version "2.1.0"
- resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz"
+ resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-2.1.0.tgz#cd734a56864e23b956bf4e7c66c396a4c0b22c2d"
integrity sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==
is-relative@^1.0.0:
version "1.0.0"
- resolved "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d"
integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==
dependencies:
is-unc-path "^1.0.0"
@@ -7262,7 +7393,7 @@ is-root@^2.1.0:
resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c"
integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==
-is-shared-array-buffer@^1.0.1, is-shared-array-buffer@^1.0.2:
+is-shared-array-buffer@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79"
integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==
@@ -7295,24 +7426,24 @@ is-typedarray@^1.0.0:
is-unc-path@^1.0.0:
version "1.0.0"
- resolved "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d"
integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==
dependencies:
unc-path-regex "^0.1.2"
is-unicode-supported@^0.1.0:
version "0.1.0"
- resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz"
+ resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
is-upper-case@^1.1.0:
version "1.1.2"
- resolved "https://registry.npmjs.org/is-upper-case/-/is-upper-case-1.1.2.tgz"
- integrity sha1-jQsfp+eTOh5YSDYA7H2WYcuvdW8=
+ resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-1.1.2.tgz#8d0b1fa7e7933a1e58483600ec7d9661cbaf756f"
+ integrity sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==
dependencies:
upper-case "^1.1.0"
-is-weakref@^1.0.1, is-weakref@^1.0.2:
+is-weakref@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2"
integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==
@@ -7331,7 +7462,7 @@ is-window@^1.0.2:
is-windows@^1.0.1, is-windows@^1.0.2:
version "1.0.2"
- resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz"
+ resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==
is-wsl@^2.2.0:
@@ -7343,8 +7474,8 @@ is-wsl@^2.2.0:
isarray@0.0.1:
version "0.0.1"
- resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
- integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
+ integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==
isarray@1.0.0:
version "1.0.0"
@@ -7352,9 +7483,9 @@ isarray@1.0.0:
integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
isbinaryfile@^4.0.2:
- version "4.0.8"
- resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz"
- integrity sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w==
+ version "4.0.10"
+ resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3"
+ integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==
isexe@^2.0.0:
version "2.0.0"
@@ -7384,9 +7515,9 @@ istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0:
integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==
istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f"
- integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d"
+ integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==
dependencies:
"@babel/core" "^7.12.3"
"@babel/parser" "^7.14.7"
@@ -7520,6 +7651,16 @@ jest-diff@^27.5.1:
jest-get-type "^27.5.1"
pretty-format "^27.5.1"
+jest-diff@^29.1.2:
+ version "29.1.2"
+ resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.1.2.tgz#bb7aaf5353227d6f4f96c5e7e8713ce576a607dc"
+ integrity sha512-4GQts0aUopVvecIT4IwD/7xsBaMhKTYoM4/njE/aVw9wpw+pIUVp8Vab/KnSzSilr84GnLBkaP3JLDnQYCKqVQ==
+ dependencies:
+ chalk "^4.0.0"
+ diff-sequences "^29.0.0"
+ jest-get-type "^29.0.0"
+ pretty-format "^29.1.2"
+
jest-docblock@^27.5.1:
version "27.5.1"
resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0"
@@ -7568,6 +7709,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@^29.0.0:
+ version "29.0.0"
+ resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.0.0.tgz#843f6c50a1b778f7325df1129a0fd7aa713aef80"
+ integrity sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw==
+
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"
@@ -7639,6 +7785,16 @@ jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1:
jest-get-type "^27.5.1"
pretty-format "^27.5.1"
+jest-matcher-utils@^29.1.2:
+ version "29.1.2"
+ resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.1.2.tgz#e68c4bcc0266e70aa1a5c13fb7b8cd4695e318a1"
+ integrity sha512-MV5XrD3qYSW2zZSHRRceFzqJ39B2z11Qv0KPyZYxnzDHFeYZGJlgGi0SW+IXSJfOewgJp/Km/7lpcFT+cgZypw==
+ dependencies:
+ chalk "^4.0.0"
+ jest-diff "^29.1.2"
+ jest-get-type "^29.0.0"
+ pretty-format "^29.1.2"
+
jest-message-util@^27.5.1:
version "27.5.1"
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf"
@@ -7654,6 +7810,21 @@ jest-message-util@^27.5.1:
slash "^3.0.0"
stack-utils "^2.0.3"
+jest-message-util@^29.1.2:
+ version "29.1.2"
+ resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.1.2.tgz#c21a33c25f9dc1ebfcd0f921d89438847a09a501"
+ integrity sha512-9oJ2Os+Qh6IlxLpmvshVbGUiSkZVc2FK+uGOm6tghafnB2RyjKAxMZhtxThRMxfX1J1SOMhTn9oK3/MutRWQJQ==
+ dependencies:
+ "@babel/code-frame" "^7.12.13"
+ "@jest/types" "^29.1.2"
+ "@types/stack-utils" "^2.0.0"
+ chalk "^4.0.0"
+ graceful-fs "^4.2.9"
+ micromatch "^4.0.4"
+ pretty-format "^29.1.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"
@@ -7800,6 +7971,18 @@ jest-util@^27.0.0, jest-util@^27.5.1:
graceful-fs "^4.2.9"
picomatch "^2.2.3"
+jest-util@^29.1.2:
+ version "29.1.2"
+ resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.1.2.tgz#ac5798e93cb6a6703084e194cfa0898d66126df1"
+ integrity sha512-vPCk9F353i0Ymx3WQq3+a4lZ07NXu9Ca8wya6o4Fe4/aO1e1awMMprZ3woPFpKwghEOW+UXgd15vVotuNN9ONQ==
+ dependencies:
+ "@jest/types" "^29.1.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"
@@ -7834,7 +8017,7 @@ jest-worker@^27.0.2, jest-worker@^27.4.5, jest-worker@^27.5.1:
merge-stream "^2.0.0"
supports-color "^8.0.0"
-jest@27.5.1:
+jest@27.5.1, jest@^27.5.1:
version "27.5.1"
resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc"
integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==
@@ -7853,6 +8036,11 @@ js-cookie@^2.2.1:
resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8"
integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==
+js-sdsl@^4.1.4:
+ version "4.1.5"
+ resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.5.tgz#1ff1645e6b4d1b028cd3f862db88c9d887f26e2a"
+ integrity sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==
+
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -7878,6 +8066,11 @@ jsdoc-type-pratt-parser@~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.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz#a4a56bdc6e82e5865ffd9febc5b1a227ff28e67e"
+ integrity sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==
+
jsdom@^16.6.0:
version "16.7.0"
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710"
@@ -7948,7 +8141,7 @@ json-stringify-pretty-compact@^2.0.0:
json5@2.x, json5@^2.1.2, json5@^2.2.1:
version "2.2.1"
- resolved "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz"
+ resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
json5@^1.0.1:
@@ -7996,7 +8189,7 @@ kind-of@^5.0.0:
kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3:
version "6.0.3"
- resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
kleur@^3.0.3:
@@ -8011,7 +8204,7 @@ klona@^2.0.4, klona@^2.0.5:
known-css-properties@^0.21.0:
version "0.21.0"
- resolved "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.21.0.tgz"
+ resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.21.0.tgz#15fbd0bbb83447f3ce09d8af247ed47c68ede80d"
integrity sha512-sZLUnTqimCkvkgRS+kbPlYW5o8q5w1cu+uIisKpEWkj31I8mx8kNG162DwRav8Zirkva6N5uoFsm9kzK4mUXjw==
lerc@^3.0.0:
@@ -8066,8 +8259,8 @@ levn@~0.3.0:
liftoff@^2.5.0:
version "2.5.0"
- resolved "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz"
- integrity sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=
+ resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec"
+ integrity sha512-01zfGFqfORP1CGmZZP2Zn51zsqz4RltDi0RDOhbGoLYdUT5Lw+I2gX6QdwXhPITF6hPOHEOp+At6/L24hIg9WQ==
dependencies:
extend "^3.0.0"
findup-sync "^2.0.0"
@@ -8090,7 +8283,7 @@ lines-and-columns@^1.1.6:
lint-staged@^10.2.11:
version "10.5.4"
- resolved "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz"
+ resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.5.4.tgz#cd153b5f0987d2371fc1d2847a409a2fe705b665"
integrity sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg==
dependencies:
chalk "^4.1.0"
@@ -8110,15 +8303,16 @@ lint-staged@^10.2.11:
stringify-object "^3.3.0"
listr2@^3.2.2:
- version "3.10.0"
- resolved "https://registry.npmjs.org/listr2/-/listr2-3.10.0.tgz"
- integrity sha512-eP40ZHihu70sSmqFNbNy2NL1YwImmlMmPh9WO5sLmPDleurMHt3n+SwEWNu2kzKScexZnkyFtc1VI0z/TGlmpw==
+ version "3.14.0"
+ resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e"
+ integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==
dependencies:
cli-truncate "^2.1.0"
- colorette "^1.2.2"
+ colorette "^2.0.16"
log-update "^4.0.0"
p-map "^4.0.0"
- rxjs "^6.6.7"
+ rfdc "^1.3.0"
+ rxjs "^7.5.1"
through "^2.3.8"
wrap-ansi "^7.0.0"
@@ -8141,14 +8335,6 @@ loader-utils@^3.2.0:
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.0.tgz#bcecc51a7898bee7473d4bc6b845b23af8304d4f"
integrity sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==
-locate-path@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz"
- integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=
- dependencies:
- p-locate "^2.0.0"
- path-exists "^3.0.0"
-
locate-path@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
@@ -8183,18 +8369,18 @@ lodash.debounce@^4.0.8:
lodash.flatten@^4.2.0, lodash.flatten@^4.4.0:
version "4.4.0"
- resolved "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz"
- integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
+ resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
+ integrity sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==
lodash.get@^4.4.2:
version "4.4.2"
- resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz"
- integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
+ resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
+ integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==
lodash.isstring@^4.0.1:
version "4.0.1"
- resolved "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz"
- integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
+ resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
+ integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==
lodash.memoize@4.x, lodash.memoize@^4.1.1, lodash.memoize@^4.1.2:
version "4.1.2"
@@ -8216,21 +8402,21 @@ lodash.uniq@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==
-lodash@4.17.21, lodash@^4.1.1, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0:
+lodash@4.17.21, lodash@^4.1.1, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
log-symbols@^2.2.0:
version "2.2.0"
- resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz"
+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==
dependencies:
chalk "^2.0.1"
log-symbols@^4.0.0, log-symbols@^4.1.0:
version "4.1.0"
- resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz"
+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
dependencies:
chalk "^4.1.0"
@@ -8238,7 +8424,7 @@ log-symbols@^4.0.0, log-symbols@^4.1.0:
log-update@^4.0.0:
version "4.0.0"
- resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1"
integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==
dependencies:
ansi-escapes "^4.3.0"
@@ -8248,7 +8434,7 @@ log-update@^4.0.0:
longest-streak@^2.0.0:
version "2.0.4"
- resolved "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4"
integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
@@ -8260,19 +8446,19 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3
lower-case-first@^1.0.0:
version "1.0.2"
- resolved "https://registry.npmjs.org/lower-case-first/-/lower-case-first-1.0.2.tgz"
- integrity sha1-5dp8JvKacHO+AtUrrJmA5ZIq36E=
+ resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-1.0.2.tgz#e5da7c26f29a7073be02d52bac9980e5922adfa1"
+ integrity sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA==
dependencies:
lower-case "^1.1.2"
lower-case@^1.1.0, lower-case@^1.1.1, lower-case@^1.1.2:
version "1.1.4"
- resolved "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz"
- integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw=
+ resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
+ integrity sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==
lower-case@^2.0.2:
version "2.0.2"
- resolved "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz"
+ resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28"
integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==
dependencies:
tslib "^2.0.3"
@@ -8311,7 +8497,7 @@ make-error@1.x, make-error@^1.1.1:
make-iterator@^1.0.0:
version "1.0.1"
- resolved "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz"
+ resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6"
integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==
dependencies:
kind-of "^6.0.2"
@@ -8325,18 +8511,18 @@ makeerror@1.0.12:
map-cache@^0.2.0, map-cache@^0.2.2:
version "0.2.2"
- resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz"
- integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=
+ resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
+ integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==
map-obj@^1.0.0:
version "1.0.1"
- resolved "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz"
- integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=
+ resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
+ integrity sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==
map-obj@^4.0.0:
- version "4.2.1"
- resolved "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz"
- integrity sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a"
+ integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==
map-visit@^1.0.0:
version "1.0.0"
@@ -8357,14 +8543,14 @@ marked@4.0.18:
matchmediaquery@^0.3.0:
version "0.3.1"
- resolved "https://registry.npmjs.org/matchmediaquery/-/matchmediaquery-0.3.1.tgz"
+ resolved "https://registry.yarnpkg.com/matchmediaquery/-/matchmediaquery-0.3.1.tgz#8247edc47e499ebb7c58f62a9ff9ccf5b815c6d7"
integrity sha512-Hlk20WQHRIm9EE9luN1kjRjYXAQToHOIAHPJn9buxBwuhfTHoKUcX+lXBbxc85DVQfXYbEQ4HcwQdd128E3qHQ==
dependencies:
css-mediaquery "^0.1.2"
mathml-tag-names@^2.1.3:
version "2.1.3"
- resolved "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz"
+ resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3"
integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==
md5-file@^5.0.0:
@@ -8374,7 +8560,7 @@ md5-file@^5.0.0:
mdast-util-from-markdown@^0.8.0:
version "0.8.5"
- resolved "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz"
+ resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz#d1ef2ca42bc377ecb0463a987910dae89bd9a28c"
integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==
dependencies:
"@types/mdast" "^3.0.0"
@@ -8385,7 +8571,7 @@ mdast-util-from-markdown@^0.8.0:
mdast-util-to-markdown@^0.6.0:
version "0.6.5"
- resolved "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz"
+ resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz#b33f67ca820d69e6cc527a93d4039249b504bebe"
integrity sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==
dependencies:
"@types/unist" "^2.0.0"
@@ -8397,7 +8583,7 @@ mdast-util-to-markdown@^0.6.0:
mdast-util-to-string@^2.0.0:
version "2.0.0"
- resolved "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b"
integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==
mdn-data@2.0.14:
@@ -8429,7 +8615,7 @@ memoize-one@^4.0.0:
meow@^9.0.0:
version "9.0.0"
- resolved "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/meow/-/meow-9.0.0.tgz#cd9510bc5cac9dee7d03c73ee1f9ad959f4ea364"
integrity sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==
dependencies:
"@types/minimist" "^1.2.0"
@@ -8462,7 +8648,7 @@ merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1:
micromark@~2.11.0:
version "2.11.4"
- resolved "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz"
+ resolved "https://registry.yarnpkg.com/micromark/-/micromark-2.11.4.tgz#d13436138eea826383e822449c9a5c50ee44665a"
integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==
dependencies:
debug "^4.0.0"
@@ -8470,7 +8656,7 @@ micromark@~2.11.0:
micromatch@^3.0.4:
version "3.1.10"
- resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==
dependencies:
arr-diff "^4.0.0"
@@ -8512,11 +8698,6 @@ mime@^1.4.1:
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
-mime@^2.3.1:
- version "2.5.2"
- resolved "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz"
- integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==
-
mimic-fn@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
@@ -8532,14 +8713,6 @@ min-indent@^1.0.0:
resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
-mini-create-react-context@^0.4.0:
- version "0.4.1"
- resolved "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz"
- integrity sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==
- dependencies:
- "@babel/runtime" "^7.12.1"
- tiny-warning "^1.0.3"
-
mini-css-extract-plugin@^2.6.0:
version "2.6.1"
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz#9a1251d15f2035c342d99a468ab9da7a0451b71e"
@@ -8563,7 +8736,7 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
minimist-options@4.1.0:
version "4.1.0"
- resolved "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz"
+ resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619"
integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==
dependencies:
arrify "^1.0.1"
@@ -8614,28 +8787,23 @@ mobx@5.13.0:
moment-timezone@0.5.34:
version "0.5.34"
- resolved "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.34.tgz"
+ resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.34.tgz#a75938f7476b88f155d3504a9343f7519d9a405c"
integrity sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg==
dependencies:
moment ">= 2.9.0"
moment-timezone@^0.5.35:
- version "0.5.35"
- resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.35.tgz#6fa2631bdbe8ff04f6b8753f7199516be6dc9839"
- integrity sha512-cY/pBOEXepQvlgli06ttCTKcIf8cD1nmNwOKQQAdHBqYApQSpAqotBMX0RJZNgMp6i0PlZuf1mFtnlyEkwyvFw==
+ version "0.5.37"
+ resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.37.tgz#adf97f719c4e458fdb12e2b4e87b8bec9f4eef1e"
+ integrity sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==
dependencies:
moment ">= 2.9.0"
-moment@2.29.4, moment@2.x:
+moment@2.29.4, moment@2.x, "moment@>= 2.9.0":
version "2.29.4"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
-"moment@>= 2.9.0":
- version "2.29.1"
- resolved "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz"
- integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
-
monaco-editor@^0.31.1:
version "0.31.1"
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.31.1.tgz#67f597b3e45679d1f551237e12a3a42c4438b97b"
@@ -8648,6 +8816,11 @@ moo-color@^1.0.2:
dependencies:
color-name "^1.1.4"
+mrmime@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.1.tgz#5f90c825fad4bdd41dc914eff5d1a8cfdaf24f27"
+ integrity sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==
+
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@@ -8720,19 +8893,19 @@ needle@^3.1.0:
neo-async@^2.6.0, neo-async@^2.6.2:
version "2.6.2"
- resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz"
+ resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
no-case@^2.2.0, no-case@^2.3.2:
version "2.3.2"
- resolved "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz"
+ resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac"
integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==
dependencies:
lower-case "^1.1.1"
no-case@^3.0.4:
version "3.0.4"
- resolved "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d"
integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==
dependencies:
lower-case "^2.0.2"
@@ -8748,10 +8921,10 @@ node-int64@^0.4.0:
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==
-node-plop@~0.26.2:
- version "0.26.2"
- resolved "https://registry.npmjs.org/node-plop/-/node-plop-0.26.2.tgz"
- integrity sha512-q444beWkMvZwAiYC3BRGJUHgRlpOItQHy+xdy6egXg8KjxDY/Ro309spQTNvH01qK9A8XF6pc0xLKbrHDpxW7w==
+node-plop@^0.26.3:
+ version "0.26.3"
+ resolved "https://registry.yarnpkg.com/node-plop/-/node-plop-0.26.3.tgz#d6fa7e71393c8b940513ba8c4868f8aaa6dea9df"
+ integrity sha512-Cov028YhBZ5aB7MdMWJEmwyBig43aGL5WT4vdoB28Oitau1zZAcHUn8Sgfk9HM33TqhtLJ9PlM/O0Mv+QpV/4Q==
dependencies:
"@babel/runtime-corejs3" "^7.9.2"
"@types/inquirer" "^6.5.0"
@@ -8765,11 +8938,6 @@ node-plop@~0.26.2:
mkdirp "^0.5.1"
resolve "^1.12.0"
-node-releases@^2.0.5:
- version "2.0.5"
- resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz"
- integrity sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==
-
node-releases@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503"
@@ -8786,12 +8954,12 @@ normalize-package-data@^2.5.0:
validate-npm-package-license "^3.0.1"
normalize-package-data@^3.0.0:
- version "3.0.2"
- resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz"
- integrity sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e"
+ integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==
dependencies:
hosted-git-info "^4.0.1"
- resolve "^1.20.0"
+ is-core-module "^2.5.0"
semver "^7.3.4"
validate-npm-package-license "^3.0.1"
@@ -8807,7 +8975,7 @@ normalize-range@^0.1.2:
normalize-selector@^0.2.0:
version "0.2.0"
- resolved "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz"
+ resolved "https://registry.yarnpkg.com/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03"
integrity sha512-dxvWdI8gw6eAvk9BlPffgEoGfM7AdijoCwOEJge3e3ulT2XLgmU7KvvxprOaCu05Q1uGRHmOhHe1r6emZoKyFw==
normalize-url@^6.0.1:
@@ -8835,9 +9003,9 @@ num2fraction@^1.2.2:
integrity sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==
nwsapi@^2.2.0:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.1.tgz#10a9f268fbf4c461249ebcfe38e359aa36e2577c"
- integrity sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg==
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0"
+ integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==
object-assign@4.x, object-assign@^4.1.1:
version "4.1.1"
@@ -8853,7 +9021,7 @@ object-copy@^0.1.0:
define-property "^0.2.5"
kind-of "^3.0.3"
-object-inspect@^1.11.0, object-inspect@^1.12.0, object-inspect@^1.9.0:
+object-inspect@^1.12.2, object-inspect@^1.9.0:
version "1.12.2"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==
@@ -8870,7 +9038,7 @@ object-visit@^1.0.0:
dependencies:
isobject "^3.0.0"
-object.assign@^4.1.0, object.assign@^4.1.2, object.assign@^4.1.3:
+object.assign@^4.1.0, object.assign@^4.1.3, object.assign@^4.1.4:
version "4.1.4"
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f"
integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==
@@ -8882,8 +9050,8 @@ object.assign@^4.1.0, object.assign@^4.1.2, object.assign@^4.1.3:
object.defaults@^1.1.0:
version "1.1.0"
- resolved "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz"
- integrity sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=
+ resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf"
+ integrity sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==
dependencies:
array-each "^1.0.1"
array-slice "^1.0.0"
@@ -8908,7 +9076,7 @@ object.fromentries@^2.0.5:
define-properties "^1.1.3"
es-abstract "^1.19.1"
-object.hasown@^1.1.0:
+object.hasown@^1.1.0, object.hasown@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.1.tgz#ad1eecc60d03f49460600430d97f23882cf592a3"
integrity sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==
@@ -8918,22 +9086,22 @@ object.hasown@^1.1.0:
object.map@^1.0.0:
version "1.0.1"
- resolved "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz"
- integrity sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=
+ resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37"
+ integrity sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==
dependencies:
for-own "^1.0.0"
make-iterator "^1.0.0"
object.pick@^1.2.0, object.pick@^1.3.0:
version "1.3.0"
- resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz"
- integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=
+ resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747"
+ integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==
dependencies:
isobject "^3.0.1"
object.values@^1.1.5:
version "1.1.5"
- resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz"
+ resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac"
integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==
dependencies:
call-bind "^1.0.2"
@@ -8990,7 +9158,7 @@ open@^8.4.0:
opener@^1.5.2:
version "1.5.2"
- resolved "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz"
+ resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598"
integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==
optionator@^0.8.1:
@@ -9019,7 +9187,7 @@ optionator@^0.9.1:
ora@^3.4.0:
version "3.4.0"
- resolved "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz"
+ resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318"
integrity sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==
dependencies:
chalk "^2.4.2"
@@ -9049,13 +9217,6 @@ os-tmpdir@~1.0.2:
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==
-p-limit@^1.1.0:
- version "1.3.0"
- resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz"
- integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==
- dependencies:
- p-try "^1.0.0"
-
p-limit@^2.0.0, p-limit@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
@@ -9070,13 +9231,6 @@ p-limit@^3.0.2:
dependencies:
yocto-queue "^0.1.0"
-p-locate@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz"
- integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=
- dependencies:
- p-limit "^1.1.0"
-
p-locate@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
@@ -9107,16 +9261,11 @@ p-map@^3.0.0:
p-map@^4.0.0:
version "4.0.0"
- resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b"
integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==
dependencies:
aggregate-error "^3.0.0"
-p-try@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz"
- integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=
-
p-try@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
@@ -9134,14 +9283,14 @@ papaparse@5.3.2:
param-case@^2.1.0:
version "2.1.1"
- resolved "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz"
- integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc=
+ resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247"
+ integrity sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==
dependencies:
no-case "^2.2.0"
param-case@^3.0.4:
version "3.0.4"
- resolved "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5"
integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==
dependencies:
dot-case "^3.0.4"
@@ -9156,7 +9305,7 @@ parent-module@^1.0.0:
parse-entities@^2.0.0:
version "2.0.0"
- resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8"
integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==
dependencies:
character-entities "^1.0.0"
@@ -9168,8 +9317,8 @@ parse-entities@^2.0.0:
parse-filepath@^1.0.1:
version "1.0.2"
- resolved "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz"
- integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=
+ resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891"
+ integrity sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==
dependencies:
is-absolute "^1.0.0"
map-cache "^0.2.0"
@@ -9197,8 +9346,8 @@ parse-node-version@^1.0.1:
parse-passwd@^1.0.0:
version "1.0.0"
- resolved "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz"
- integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=
+ resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
+ integrity sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==
parse5@6.0.1, parse5@^6.0.1:
version "6.0.1"
@@ -9207,15 +9356,15 @@ parse5@6.0.1, parse5@^6.0.1:
pascal-case@^2.0.0:
version "2.0.1"
- resolved "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz"
- integrity sha1-LVeNNFX2YNpl7KGO+VtODekSdh4=
+ resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-2.0.1.tgz#2d578d3455f660da65eca18ef95b4e0de912761e"
+ integrity sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==
dependencies:
camel-case "^3.0.0"
upper-case-first "^1.1.0"
pascal-case@^3.1.2:
version "3.1.2"
- resolved "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz"
+ resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb"
integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==
dependencies:
no-case "^3.0.4"
@@ -9228,14 +9377,14 @@ pascalcase@^0.1.1:
path-case@^2.1.0:
version "2.1.1"
- resolved "https://registry.npmjs.org/path-case/-/path-case-2.1.1.tgz"
- integrity sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU=
+ resolved "https://registry.yarnpkg.com/path-case/-/path-case-2.1.1.tgz#94b8037c372d3fe2906e465bb45e25d226e8eea5"
+ integrity sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==
dependencies:
no-case "^2.2.0"
path-case@^3.0.4:
version "3.0.4"
- resolved "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/path-case/-/path-case-3.0.4.tgz#9168645334eb942658375c56f80b4c0cb5f82c6f"
integrity sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==
dependencies:
dot-case "^3.0.4"
@@ -9261,26 +9410,26 @@ path-key@^3.0.0, path-key@^3.1.0:
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
-path-parse@^1.0.6, path-parse@^1.0.7:
+path-parse@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
path-root-regex@^0.1.0:
version "0.1.2"
- resolved "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz"
- integrity sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=
+ resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d"
+ integrity sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==
path-root@^0.1.1:
version "0.1.1"
- resolved "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz"
- integrity sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=
+ resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7"
+ integrity sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==
dependencies:
path-root-regex "^0.1.0"
path-to-regexp@^1.7.0:
version "1.8.0"
- resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz"
+ resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a"
integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==
dependencies:
isarray "0.0.1"
@@ -9351,22 +9500,22 @@ pkg-up@^3.1.0:
please-upgrade-node@^3.2.0:
version "3.2.0"
- resolved "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz"
+ resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942"
integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==
dependencies:
semver-compare "^1.0.0"
plop@^2.7.4:
- version "2.7.4"
- resolved "https://registry.npmjs.org/plop/-/plop-2.7.4.tgz"
- integrity sha512-SaqN3mwug/Ur2RE/ryo05oLTLy+8qZGwosNt9JnrFWca+dLCsPJR1j2ZXwjrccmNu6LA7eB56lRyk/G0fKf9HA==
+ version "2.7.6"
+ resolved "https://registry.yarnpkg.com/plop/-/plop-2.7.6.tgz#1fa5360cd5b04e9932ce677bb6bd44750d97ae67"
+ integrity sha512-IgnYAsC3Ni7t1cDU7wH2151CD22YhMxH8PFh+iPzCf+WuGEWXslJ5t1Tpr0N/gjL23CAV/HbLAWug2IPM2YrHg==
dependencies:
- "@types/liftoff" "^2.5.0"
+ "@types/liftoff" "^2.5.1"
chalk "^1.1.3"
interpret "^1.2.0"
liftoff "^2.5.0"
- minimist "^1.2.0"
- node-plop "~0.26.2"
+ minimist "^1.2.5"
+ node-plop "^0.26.3"
ora "^3.4.0"
v8flags "^2.0.10"
@@ -9449,9 +9598,9 @@ postcss-custom-media@^8.0.0:
postcss-value-parser "^4.2.0"
postcss-custom-properties@^12.1.5:
- version "12.1.8"
- resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-12.1.8.tgz#aa003e1885c5bd28e2e32496cd597e389ca889e4"
- integrity sha512-8rbj8kVu00RQh2fQF81oBqtduiANu4MIxhyf0HbbStgPtnFlWn0yiaYTpLHrPnJbffVY1s9apWsIoVZcc68FxA==
+ version "12.1.9"
+ resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-12.1.9.tgz#0883429a7ef99f1ba239d1fea29ce84906daa8bd"
+ integrity sha512-/E7PRvK8DAVljBbeWrcEQJPG72jaImxF3vvCNFwv9cC8CzigVoNIpeyfnJzphnN3Fd8/auBf5wvkw6W9MfmTyg==
dependencies:
postcss-value-parser "^4.2.0"
@@ -9535,7 +9684,7 @@ postcss-gap-properties@^3.0.3:
postcss-html@^0.36.0:
version "0.36.0"
- resolved "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz"
+ resolved "https://registry.yarnpkg.com/postcss-html/-/postcss-html-0.36.0.tgz#b40913f94eaacc2453fd30a1327ad6ee1f88b204"
integrity sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==
dependencies:
htmlparser2 "^3.10.0"
@@ -9562,7 +9711,7 @@ postcss-lab-function@^4.1.2:
postcss-less@^3.1.4:
version "3.1.4"
- resolved "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz"
+ resolved "https://registry.yarnpkg.com/postcss-less/-/postcss-less-3.1.4.tgz#369f58642b5928ef898ffbc1a6e93c958304c5ad"
integrity sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==
dependencies:
postcss "^7.0.14"
@@ -9597,8 +9746,8 @@ postcss-media-minmax@^5.0.0:
postcss-media-query-parser@^0.2.3:
version "0.2.3"
- resolved "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz"
- integrity sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=
+ resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244"
+ integrity sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==
postcss-merge-longhand@^5.1.6:
version "5.1.6"
@@ -9679,9 +9828,9 @@ postcss-modules-values@^4.0.0:
icss-utils "^5.0.0"
postcss-nesting@^10.1.3:
- version "10.1.10"
- resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-10.1.10.tgz#9c396df3d8232cbedfa95baaac6b765b8fd2a817"
- integrity sha512-lqd7LXCq0gWc0wKXtoKDru5wEUNjm3OryLVNRZ8OnW8km6fSNUuFrjEhU3nklxXE2jvd4qrox566acgh+xQt8w==
+ version "10.2.0"
+ resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-10.2.0.tgz#0b12ce0db8edfd2d8ae0aaf86427370b898890be"
+ integrity sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==
dependencies:
"@csstools/selector-specificity" "^2.0.0"
postcss-selector-parser "^6.0.10"
@@ -9859,19 +10008,19 @@ postcss-replace-overflow-wrap@^4.0.0:
postcss-resolve-nested-selector@^0.1.1:
version "0.1.1"
- resolved "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz"
- integrity sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=
+ resolved "https://registry.yarnpkg.com/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz#29ccbc7c37dedfac304e9fff0bf1596b3f6a0e4e"
+ integrity sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==
postcss-safe-parser@^4.0.2:
version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz"
+ resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz#a6d4e48f0f37d9f7c11b2a581bf00f8ba4870b96"
integrity sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==
dependencies:
postcss "^7.0.26"
postcss-sass@^0.4.4:
version "0.4.4"
- resolved "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.4.4.tgz"
+ resolved "https://registry.yarnpkg.com/postcss-sass/-/postcss-sass-0.4.4.tgz#91f0f3447b45ce373227a98b61f8d8f0785285a3"
integrity sha512-BYxnVYx4mQooOhr+zer0qWbSPYnarAy8ZT7hAQtbxtgVf8gy+LSLT/hHGe35h14/pZDTw1DsxdbrwxBN++H+fg==
dependencies:
gonzales-pe "^4.3.0"
@@ -9879,7 +10028,7 @@ postcss-sass@^0.4.4:
postcss-scss@^2.1.1:
version "2.1.1"
- resolved "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz"
+ resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-2.1.1.tgz#ec3a75fa29a55e016b90bf3269026c53c1d2b383"
integrity sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==
dependencies:
postcss "^7.0.6"
@@ -9893,7 +10042,7 @@ postcss-selector-not@^5.0.0:
postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9:
version "6.0.10"
- resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz"
+ resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d"
integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==
dependencies:
cssesc "^3.0.0"
@@ -9909,7 +10058,7 @@ postcss-svgo@^5.1.0:
postcss-syntax@^0.36.2:
version "0.36.2"
- resolved "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz"
+ resolved "https://registry.yarnpkg.com/postcss-syntax/-/postcss-syntax-0.36.2.tgz#f08578c7d95834574e5593a82dfbfa8afae3b51c"
integrity sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==
postcss-unique-selectors@^5.1.1:
@@ -9926,16 +10075,16 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.35, postcss@^7.0.6:
version "7.0.39"
- resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309"
integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==
dependencies:
picocolors "^0.2.1"
source-map "^0.6.1"
postcss@^8.3.5, postcss@^8.4.12, postcss@^8.4.7:
- version "8.4.16"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.16.tgz#33a1d675fac39941f5f445db0de4db2b6e01d43c"
- integrity sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==
+ version "8.4.17"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.17.tgz#f87863ec7cd353f81f7ab2dec5d67d861bbb1be5"
+ integrity sha512-UNxNOLQydcOFi41yHNMcKRZ39NeXlr8AxGuZJsdub8vIb12fHzcq37DTU/QtbI6WLxNg2gF9Z+8qtRwTj1UI1Q==
dependencies:
nanoid "^3.3.4"
picocolors "^1.0.0"
@@ -9956,6 +10105,13 @@ prelude-ls@~1.1.2:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==
+prettier-linter-helpers@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b"
+ integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==
+ dependencies:
+ fast-diff "^1.1.2"
+
prettier@2.7.1, prettier@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64"
@@ -9978,6 +10134,15 @@ pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1:
ansi-styles "^5.0.0"
react-is "^17.0.1"
+pretty-format@^29.0.0, pretty-format@^29.1.2:
+ version "29.1.2"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.1.2.tgz#b1f6b75be7d699be1a051f5da36e8ae9e76a8e6a"
+ integrity sha512-CGJ6VVGXVRP2o2Dorl4mAwwvDWT25luIsYhkyVQW32E4nL+TgW939J7LlKT/npq5Cpq6j3s+sy+13yk7xYpBmg==
+ dependencies:
+ "@jest/schemas" "^29.0.0"
+ ansi-styles "^5.0.0"
+ react-is "^18.0.0"
+
prismjs@1.28.0:
version "1.28.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.28.0.tgz#0d8f561fa0f7cf6ebca901747828b149147044b6"
@@ -9991,7 +10156,7 @@ prompts@^2.0.1, prompts@^2.4.2:
kleur "^3.0.3"
sisteransi "^1.0.5"
-prop-types@15.x, prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
+prop-types@15.x, prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -10000,15 +10165,6 @@ prop-types@15.x, prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.5.8, pr
object-assign "^4.1.1"
react-is "^16.13.1"
-prop-types@^15.6.1:
- version "15.7.2"
- resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz"
- integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
- dependencies:
- loose-envify "^1.4.0"
- object-assign "^4.1.1"
- react-is "^16.8.1"
-
protocol-buffers-schema@^3.3.1:
version "3.6.0"
resolved "https://registry.yarnpkg.com/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz#77bc75a48b2ff142c1ad5b5b90c94cd0fa2efd03"
@@ -10038,9 +10194,9 @@ punycode@^2.1.0, punycode@^2.1.1:
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
query-string@*:
- version "7.0.0"
- resolved "https://registry.npmjs.org/query-string/-/query-string-7.0.0.tgz"
- integrity sha512-Iy7moLybliR5ZgrK/1R3vjrXq03S13Vz4Rbm5Jg3EFq1LUmQppto0qtXz4vqZ386MSRjZgnTSZ9QC+NZOSd/XA==
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.1.tgz#754620669db978625a90f635f12617c271a088e1"
+ integrity sha512-MplouLRDHBZSG9z7fpuAAcI7aAYjDLhtsiVZsevsfaHWDS2IDdORKbSd1kWUA+V4zyva/HZoSfpwnYMMQDhb0w==
dependencies:
decode-uri-component "^0.2.0"
filter-obj "^1.1.0"
@@ -10059,7 +10215,7 @@ queue-microtask@^1.2.2:
quick-lru@^4.0.1:
version "4.0.1"
- resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz"
+ resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f"
integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==
quickselect@^2.0.0:
@@ -10168,20 +10324,20 @@ rc-overflow@^1.0.0:
rc-resize-observer "^1.0.0"
rc-util "^5.19.2"
-rc-resize-observer@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.0.0.tgz"
- integrity sha512-RgKGukg1mlzyGdvzF7o/LGFC8AeoMH9aGzXTUdp6m+OApvmRdUuOscq/Y2O45cJA+rXt1ApWlpFoOIioXL3AGg==
+rc-resize-observer@^1.0.0, rc-resize-observer@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/rc-resize-observer/-/rc-resize-observer-1.2.0.tgz#9f46052f81cdf03498be35144cb7c53fd282c4c7"
+ integrity sha512-6W+UzT3PyDM0wVCEHfoW3qTHPTvbdSgiA43buiy8PzmeMnfgnDeb9NjdimMXMl3/TcrvvWl5RRVdp+NqcR47pQ==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "^2.2.1"
- rc-util "^5.0.0"
+ rc-util "^5.15.0"
resize-observer-polyfill "^1.5.1"
rc-select@~14.1.0:
- version "14.1.9"
- resolved "https://registry.yarnpkg.com/rc-select/-/rc-select-14.1.9.tgz#9c9eceff00920ad8a0a53b77b76afc177ffe5ab4"
- integrity sha512-DK01+Q7oCWr5jVPiEp/BTQ8xCB4rI4LfXzZtSmBWJhOMuibyZD1Vlz/DlVKCUFmtBM4SzG4/SltGHoGlcbCqiw==
+ version "14.1.13"
+ resolved "https://registry.yarnpkg.com/rc-select/-/rc-select-14.1.13.tgz#7eb53d00be82fb8e5050de3094e72edcf27ce6f6"
+ integrity sha512-WMEsC3gTwA1dbzWOdVIXDmWyidYNLq68AwvvUlRROw790uGUly0/vmqDozXrIr0QvN/A3CEULx12o+WtLCAefg==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "2.x"
@@ -10203,14 +10359,14 @@ rc-slider@9.7.5:
shallowequal "^1.1.0"
rc-table@^7.17.1:
- version "7.17.1"
- resolved "https://registry.npmjs.org/rc-table/-/rc-table-7.17.1.tgz"
- integrity sha512-ZSWQXuZKW4Hx2+fPWF9d1rLxVM6R2+yS2AsKVvqA4SYASfcgdxNIFshpgkA3J00tF/Qkwh+xjbBJkadaYMfBlg==
+ version "7.27.2"
+ resolved "https://registry.yarnpkg.com/rc-table/-/rc-table-7.27.2.tgz#fda8e2d7f742456ded40a54398a28624e1687f6d"
+ integrity sha512-8+wyj6WTY2L2tTdwmQBNcZey0U35K9mEoAloRS7KEFgjD9aZnx0snJMBA/G4uPphLslQRcsy8ln562PJ9VYm8A==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "^2.2.5"
- rc-resize-observer "^1.0.0"
- rc-util "^5.13.0"
+ rc-resize-observer "^1.1.0"
+ rc-util "^5.22.5"
shallowequal "^1.1.0"
rc-time-picker@^3.7.3:
@@ -10235,9 +10391,9 @@ rc-tooltip@^5.0.1:
rc-trigger "^5.0.0"
rc-tree@~5.6.3:
- version "5.6.6"
- resolved "https://registry.yarnpkg.com/rc-tree/-/rc-tree-5.6.6.tgz#c04253d8f8345ec52fc196dec2be06c7e708125b"
- integrity sha512-HI/q4D4AHOp48OZcBUvJFWkI5OfnZivvGYI0xzI0dy0Mita2KcTGZv7/Yl6Aq3bL3od3x5AqAXq/7qxR3x4Kkg==
+ version "5.6.9"
+ resolved "https://registry.yarnpkg.com/rc-tree/-/rc-tree-5.6.9.tgz#b73290a6dcad65e4ed5d8dc21cb198b30316404b"
+ integrity sha512-si8aGuWQ2/sh2Ibk+WdUdDeAxoviT/+kDY+NLtJ+RhqfySqPFqWM5uHTwgFRrWUvKCqEeE/PjCYuuhHrK7Y7+A==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "2.x"
@@ -10280,24 +10436,15 @@ rc-util@^4.0.4, rc-util@^4.15.3, rc-util@^4.4.0:
react-lifecycles-compat "^3.0.4"
shallowequal "^1.1.0"
-rc-util@^5.0.0, rc-util@^5.15.0, rc-util@^5.16.1, rc-util@^5.19.2, rc-util@^5.21.0, rc-util@^5.3.0, rc-util@^5.6.1, rc-util@^5.7.0:
- version "5.23.0"
- resolved "https://registry.yarnpkg.com/rc-util/-/rc-util-5.23.0.tgz#a583b1ec3e1832a80eced7a700a494af0b590743"
- integrity sha512-lgm6diJ/pLgyfoZY59Vz7sW4mSoQCgozqbBye9IJ7/mb5w5h4T7h+i2JpXAx/UBQxscBZe68q0sP7EW+qfkKUg==
+rc-util@^5.15.0, rc-util@^5.16.1, rc-util@^5.19.2, rc-util@^5.21.0, rc-util@^5.22.5, rc-util@^5.3.0, rc-util@^5.6.1, rc-util@^5.7.0:
+ version "5.24.4"
+ resolved "https://registry.yarnpkg.com/rc-util/-/rc-util-5.24.4.tgz#a4126f01358c86f17c1bf380a1d83d6c9155ae65"
+ integrity sha512-2a4RQnycV9eV7lVZPEJ7QwJRPlZNc06J7CwcwZo4vIHr3PfUqtYgl1EkUV9ETAc6VRRi8XZOMFhYG63whlIC9Q==
dependencies:
"@babel/runtime" "^7.18.3"
react-is "^16.12.0"
shallowequal "^1.1.0"
-rc-util@^5.13.0:
- version "5.13.1"
- resolved "https://registry.npmjs.org/rc-util/-/rc-util-5.13.1.tgz"
- integrity sha512-Dws2tjXBBihfjVQFlG5JzZ/5O3Wutctm0W94Wb1+M7GD2roWJPrQdSa4AkWm2pn0Ms32zoVPPkWodFeAYZPLfA==
- dependencies:
- "@babel/runtime" "^7.12.5"
- react-is "^16.12.0"
- shallowequal "^1.1.0"
-
rc-virtual-list@^3.2.0, rc-virtual-list@^3.4.8:
version "3.4.8"
resolved "https://registry.yarnpkg.com/rc-virtual-list/-/rc-virtual-list-3.4.8.tgz#c24c10c6940546b7e2a5e9809402c6716adfd26c"
@@ -10336,12 +10483,12 @@ react-colorful@5.5.1:
integrity sha512-M1TJH2X3RXEt12sWkpa6hLc/bbYS0H6F4rIqjQZ+RxNBstpY67d9TrFXtqdZwhpmBXcCwEi7stKqFue3ZRkiOg==
react-copy-to-clipboard@^5.0.2:
- version "5.0.3"
- resolved "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.3.tgz"
- integrity sha512-9S3j+m+UxDZOM0Qb8mhnT/rMR0NGSrj9A/073yz2DSxPMYhmYFBMYIdI2X4o8AjOjyFsSNxDRnCX6s/gRxpriw==
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz#09aae5ec4c62750ccb2e6421a58725eabc41255c"
+ integrity sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==
dependencies:
- copy-to-clipboard "^3"
- prop-types "^15.5.8"
+ copy-to-clipboard "^3.3.1"
+ prop-types "^15.8.1"
react-custom-scrollbars-2@4.5.0:
version "4.5.0"
@@ -10410,7 +10557,7 @@ react-dropzone@14.2.2:
react-emoji-render@^1.2.4:
version "1.2.4"
- resolved "https://registry.npmjs.org/react-emoji-render/-/react-emoji-render-1.2.4.tgz"
+ resolved "https://registry.yarnpkg.com/react-emoji-render/-/react-emoji-render-1.2.4.tgz#fa3542a692e1eed3236f0f12b8e3a61b2818e2c2"
integrity sha512-AqktVXV38uDpgf02BoCXrzLYFsHAsxfdWwjrLexSJ22l1JgB01y1KejjxW/zTuCzod6O7BZfiMS866LEEfMHmA==
dependencies:
classnames "^2.2.5"
@@ -10463,11 +10610,16 @@ react-inlinesvg@3.0.0:
exenv "^1.2.2"
react-from-dom "^0.6.2"
-react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1:
+react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
+"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.0.0:
+ version "18.2.0"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
+ integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
+
react-is@^17.0.1, react-is@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
@@ -10506,9 +10658,9 @@ react-popper@2.3.0, react-popper@^2.3.0:
warning "^4.0.2"
react-redux@^7.2.0:
- version "7.2.8"
- resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.8.tgz#a894068315e65de5b1b68899f9c6ee0923dd28de"
- integrity sha512-6+uDjhs3PSIclqoCk0kd6iX74gzrGc3W5zcAjbrFgEdIjRSQObdIwfx80unTkVUYvbQ95Y8Av3OvFHq1w5EOUw==
+ version "7.2.9"
+ resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.9.tgz#09488fbb9416a4efe3735b7235055442b042481d"
+ integrity sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==
dependencies:
"@babel/runtime" "^7.15.4"
"@types/react-redux" "^7.1.20"
@@ -10519,7 +10671,7 @@ react-redux@^7.2.0:
react-responsive@^8.1.0:
version "8.2.0"
- resolved "https://registry.npmjs.org/react-responsive/-/react-responsive-8.2.0.tgz"
+ resolved "https://registry.yarnpkg.com/react-responsive/-/react-responsive-8.2.0.tgz#e0ffb306cfd8f38c9c12e26725b9e1245fa9debc"
integrity sha512-iagCqVrw4QSjhxKp3I/YK6+ODkWY6G+YPElvdYKiUUbywwh9Ds0M7r26Fj2/7dWFFbOpcGnJE6uE7aMck8j5Qg==
dependencies:
hyphenate-style-name "^1.0.0"
@@ -10528,28 +10680,27 @@ react-responsive@^8.1.0:
shallow-equal "^1.1.0"
react-router-dom@^5.2.0:
- version "5.2.0"
- resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz"
- integrity sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==
+ version "5.3.4"
+ resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.4.tgz#2ed62ffd88cae6db134445f4a0c0ae8b91d2e5e6"
+ integrity sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==
dependencies:
- "@babel/runtime" "^7.1.2"
+ "@babel/runtime" "^7.12.13"
history "^4.9.0"
loose-envify "^1.3.1"
prop-types "^15.6.2"
- react-router "5.2.0"
+ react-router "5.3.4"
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
-react-router@5.2.0:
- version "5.2.0"
- resolved "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz"
- integrity sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==
+react-router@5.3.4:
+ version "5.3.4"
+ resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.3.4.tgz#8ca252d70fcc37841e31473c7a151cf777887bb5"
+ integrity sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==
dependencies:
- "@babel/runtime" "^7.1.2"
+ "@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"
@@ -10576,9 +10727,17 @@ react-select@5.4.0:
prop-types "^15.6.0"
react-transition-group "^4.3.0"
+react-shallow-renderer@^16.13.1:
+ version "16.15.0"
+ resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz#48fb2cf9b23d23cde96708fe5273a7d3446f4457"
+ integrity sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==
+ dependencies:
+ object-assign "^4.1.1"
+ react-is "^16.12.0 || ^17.0.0 || ^18.0.0"
+
react-sortable-hoc@^1.11.0:
version "1.11.0"
- resolved "https://registry.npmjs.org/react-sortable-hoc/-/react-sortable-hoc-1.11.0.tgz"
+ resolved "https://registry.yarnpkg.com/react-sortable-hoc/-/react-sortable-hoc-1.11.0.tgz#fe4022362bbafc4b836f5104b9676608a40a278f"
integrity sha512-v1CDCvdfoR3zLGNp6qsBa4J1BWMEVH25+UKxF/RvQRh+mrB+emqtVHMgZ+WreUiKJoEaiwYoScaueIKhMVBHUg==
dependencies:
"@babel/runtime" "^7.2.0"
@@ -10587,7 +10746,7 @@ react-sortable-hoc@^1.11.0:
react-string-replace@^0.4.4:
version "0.4.4"
- resolved "https://registry.npmjs.org/react-string-replace/-/react-string-replace-0.4.4.tgz"
+ resolved "https://registry.yarnpkg.com/react-string-replace/-/react-string-replace-0.4.4.tgz#24006fbe0db573d5be583133df38b1a735cb4225"
integrity sha512-FAMkhxmDpCsGTwTZg7p/2v+/GTmxAp73so3fbSvlAcBBX36ujiGRNEaM/1u+jiYQrArhns+7eE92g2pi5E5FUA==
dependencies:
lodash "^4.17.4"
@@ -10597,6 +10756,16 @@ react-table@7.8.0:
resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.8.0.tgz#07858c01c1718c09f7f1aed7034fcfd7bda907d2"
integrity sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==
+react-test-renderer@^17.0.2:
+ version "17.0.2"
+ resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-17.0.2.tgz#4cd4ae5ef1ad5670fc0ef776e8cc7e1231d9866c"
+ integrity sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==
+ dependencies:
+ object-assign "^4.1.1"
+ react-is "^17.0.2"
+ react-shallow-renderer "^16.13.1"
+ scheduler "^0.20.2"
+
react-transition-group@4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470"
@@ -10679,7 +10848,7 @@ read-pkg@^5.2.0:
readable-stream@^3.1.1, readable-stream@^3.4.0:
version "3.6.0"
- resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
dependencies:
inherits "^2.0.3"
@@ -10695,8 +10864,8 @@ readdirp@~3.6.0:
rechoir@^0.6.2:
version "0.6.2"
- resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz"
- integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=
+ resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
+ integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==
dependencies:
resolve "^1.1.6"
@@ -10722,10 +10891,10 @@ redux@^4.0.0, redux@^4.0.4:
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"
- integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==
+regenerate-unicode-properties@^10.1.0:
+ version "10.1.0"
+ resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c"
+ integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==
dependencies:
regenerate "^1.4.2"
@@ -10774,14 +10943,14 @@ regexpp@^3.2.0:
integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
regexpu-core@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.1.0.tgz#2f8504c3fd0ebe11215783a41541e21c79942c6d"
- integrity sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA==
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.2.1.tgz#a69c26f324c1e962e9ffd0b88b055caba8089139"
+ integrity sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==
dependencies:
regenerate "^1.4.2"
- regenerate-unicode-properties "^10.0.1"
- regjsgen "^0.6.0"
- regjsparser "^0.8.2"
+ regenerate-unicode-properties "^10.1.0"
+ regjsgen "^0.7.1"
+ regjsparser "^0.9.1"
unicode-match-property-ecmascript "^2.0.0"
unicode-match-property-value-ecmascript "^2.0.0"
@@ -10790,15 +10959,15 @@ regextras@^0.8.0:
resolved "https://registry.yarnpkg.com/regextras/-/regextras-0.8.0.tgz#ec0f99853d4912839321172f608b544814b02217"
integrity sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ==
-regjsgen@^0.6.0:
- version "0.6.0"
- resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d"
- integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==
+regjsgen@^0.7.1:
+ version "0.7.1"
+ resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.7.1.tgz#ee5ef30e18d3f09b7c369b76e7c2373ed25546f6"
+ integrity sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==
-regjsparser@^0.8.2:
- version "0.8.4"
- resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f"
- integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==
+regjsparser@^0.9.1:
+ version "0.9.1"
+ resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709"
+ integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==
dependencies:
jsesc "~0.5.0"
@@ -10809,21 +10978,21 @@ relateurl@^0.2.7:
remark-parse@^9.0.0:
version "9.0.0"
- resolved "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-9.0.0.tgz#4d20a299665880e4f4af5d90b7c7b8a935853640"
integrity sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==
dependencies:
mdast-util-from-markdown "^0.8.0"
remark-stringify@^9.0.0:
version "9.0.1"
- resolved "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz"
+ resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-9.0.1.tgz#576d06e910548b0a7191a71f27b33f1218862894"
integrity sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==
dependencies:
mdast-util-to-markdown "^0.6.0"
remark@^13.0.0:
version "13.0.0"
- resolved "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/remark/-/remark-13.0.0.tgz#d15d9bf71a402f40287ebe36067b66d54868e425"
integrity sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==
dependencies:
remark-parse "^9.0.0"
@@ -10848,7 +11017,7 @@ repeat-element@^1.1.2:
repeat-string@^1.0.0, repeat-string@^1.6.1:
version "1.6.1"
- resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz"
+ resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==
replace-in-file-webpack-plugin@1.0.6:
@@ -10885,8 +11054,8 @@ resolve-cwd@^3.0.0:
resolve-dir@^1.0.0, resolve-dir@^1.0.1:
version "1.0.1"
- resolved "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz"
- integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=
+ resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43"
+ integrity sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==
dependencies:
expand-tilde "^2.0.0"
global-modules "^1.0.0"
@@ -10903,7 +11072,7 @@ resolve-from@^5.0.0:
resolve-pathname@^3.0.0:
version "3.0.0"
- resolved "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd"
integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==
resolve-protobuf-schema@^2.1.0:
@@ -10923,15 +11092,7 @@ resolve.exports@^1.1.0:
resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9"
integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==
-resolve@^1.1.6, resolve@^1.1.7, resolve@^1.20.0:
- version "1.20.0"
- resolved "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz"
- integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
- dependencies:
- is-core-module "^2.2.0"
- path-parse "^1.0.6"
-
-resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.19.0:
+resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0:
version "1.22.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
@@ -10975,6 +11136,11 @@ reusify@^1.0.4:
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
+rfdc@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b"
+ integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==
+
rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
@@ -10991,7 +11157,7 @@ rtl-css-js@^1.14.0:
run-async@^2.4.0:
version "2.4.1"
- resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz"
+ resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455"
integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==
run-parallel@^1.1.9:
@@ -11006,20 +11172,27 @@ rw@1, rw@^1.3.3:
resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4"
integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==
-rxjs@7.5.6, rxjs@^7.5.5:
+rxjs@7.5.6:
version "7.5.6"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.6.tgz#0446577557862afd6903517ce7cae79ecb9662bc"
integrity sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==
dependencies:
tslib "^2.1.0"
-rxjs@^6.4.0, rxjs@^6.6.0, rxjs@^6.6.7:
+rxjs@^6.4.0, rxjs@^6.6.0:
version "6.6.7"
- resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9"
integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==
dependencies:
tslib "^1.9.0"
+rxjs@^7.5.1, rxjs@^7.5.5:
+ version "7.5.7"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.7.tgz#2ec0d57fdc89ece220d2e702730ae8f1e49def39"
+ integrity sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==
+ dependencies:
+ tslib "^2.1.0"
+
safe-buffer@^5.1.0, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
@@ -11030,6 +11203,15 @@ safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
+safe-regex-test@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295"
+ integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==
+ dependencies:
+ call-bind "^1.0.2"
+ get-intrinsic "^1.1.3"
+ is-regex "^1.1.4"
+
safe-regex@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e"
@@ -11051,17 +11233,17 @@ sass-loader@^12.6.0:
neo-async "^2.6.2"
sass-loader@^13.0.2:
- version "13.0.2"
- resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-13.0.2.tgz#e81a909048e06520e9f2ff25113a801065adb3fe"
- integrity sha512-BbiqbVmbfJaWVeOOAu2o7DhYWtcNmTfvroVgFXa6k2hHheMxNAeDHLNoDy/Q5aoaVlz0LH+MbMktKwm9vN/j8Q==
+ version "13.1.0"
+ resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-13.1.0.tgz#e5b9acf14199a9bc6eaed7a0b8b23951c2cebf6f"
+ integrity sha512-tZS1RJQ2n2+QNyf3CCAo1H562WjL/5AM6Gi8YcPVVoNxQX8d19mx8E+8fRrMWsyc93ZL6Q8vZDSM0FHVTJaVnQ==
dependencies:
klona "^2.0.4"
neo-async "^2.6.2"
sass@^1.49.9:
- version "1.54.5"
- resolved "https://registry.yarnpkg.com/sass/-/sass-1.54.5.tgz#93708f5560784f6ff2eab8542ade021a4a947b3a"
- integrity sha512-p7DTOzxkUPa/63FU0R3KApkRHwcVZYC0PLnLm5iyZACyp15qSi32x7zVUhRdABAATmkALqgGrjCJAcWvobmhHw==
+ version "1.55.0"
+ resolved "https://registry.yarnpkg.com/sass/-/sass-1.55.0.tgz#0c4d3c293cfe8f8a2e8d3b666e1cf1bff8065d1c"
+ integrity sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==
dependencies:
chokidar ">=3.0.0 <4.0.0"
immutable "^4.0.0"
@@ -11136,23 +11318,18 @@ selection-is-backward@^1.0.0:
semver-compare@^1.0.0:
version "1.0.0"
- resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz"
- integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
+ resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
+ integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==
"semver@2 || 3 || 4 || 5", semver@^5.6.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
-semver@7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
- integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==
-
-semver@7.x, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, 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==
+semver@7.x, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8:
+ version "7.3.8"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
+ integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==
dependencies:
lru-cache "^6.0.0"
@@ -11163,15 +11340,15 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0:
sentence-case@^2.1.0:
version "2.1.1"
- resolved "https://registry.npmjs.org/sentence-case/-/sentence-case-2.1.1.tgz"
- integrity sha1-H24t2jnBaL+S0T+G1KkYkz9mftQ=
+ resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-2.1.1.tgz#1f6e2dda39c168bf92d13f86d4a918933f667ed4"
+ integrity sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==
dependencies:
no-case "^2.2.0"
upper-case-first "^1.1.2"
sentence-case@^3.0.4:
version "3.0.4"
- resolved "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-3.0.4.tgz#3645a7b8c117c787fde8702056225bb62a45131f"
integrity sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==
dependencies:
no-case "^3.0.4"
@@ -11202,7 +11379,7 @@ set-value@^2.0.0, set-value@^2.0.1:
shallow-equal@^1.1.0:
version "1.2.1"
- resolved "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz"
+ resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da"
integrity sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==
shallowequal@^1.1.0:
@@ -11242,9 +11419,9 @@ signal-exit@^3.0.2, signal-exit@^3.0.3:
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
simple-git@^3.6.0:
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-3.13.0.tgz#36589e201c28cecaca6f3a898e7257c6610e8588"
- integrity sha512-VYrs3joeHvWGcN3K135RpGpPjm4AHYeOrclwew6LlfHgq6ozQYIW2yMnmjf4PCgVOuSYCbXkdUjyiFawuJz8MA==
+ version "3.14.1"
+ resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-3.14.1.tgz#68018a5f168f8a568862e30b692004b37c3b5ced"
+ integrity sha512-1ThF4PamK9wBORVGMK9HK5si4zoGS2GpRO7tkAFObA4FZv6dKaCVHLQT+8zlgiBm6K2h+wEU9yOaFCu/SR3OyA==
dependencies:
"@kwsites/file-exists" "^1.1.1"
"@kwsites/promise-deferred" "^1.1.1"
@@ -11256,12 +11433,12 @@ simple-is@~0.2.0:
integrity sha512-GJXhv3r5vdj5tGWO+rcrWgjU2azLB+fb7Ehh3SmZpXE0o4KrrFLti0w4mdDCbR29X/z0Ls20ApjZitlpAXhAeg==
sirv@^1.0.7:
- version "1.0.12"
- resolved "https://registry.npmjs.org/sirv/-/sirv-1.0.12.tgz"
- integrity sha512-+jQoCxndz7L2tqQL4ZyzfDhky0W/4ZJip3XoOuxyQWnAwMxindLl3Xv1qT4x1YX/re0leShvTm8Uk0kQspGhBg==
+ version "1.0.19"
+ resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.19.tgz#1d73979b38c7fe91fcba49c85280daa9c2363b49"
+ integrity sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==
dependencies:
- "@polka/url" "^1.0.0-next.15"
- mime "^2.3.1"
+ "@polka/url" "^1.0.0-next.20"
+ mrmime "^1.0.0"
totalist "^1.0.0"
sisteransi@^1.0.5:
@@ -11279,7 +11456,7 @@ slash@^4.0.0:
resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7"
integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==
-slate-base64-serializer@^0.2.111:
+slate-base64-serializer@^0.2.111, slate-base64-serializer@^0.2.112:
version "0.2.115"
resolved "https://registry.yarnpkg.com/slate-base64-serializer/-/slate-base64-serializer-0.2.115.tgz#438e051959bde013b50507f3144257e74039ff7f"
integrity sha512-GnLV7bUW/UQ5j7rVIxCU5zdB6NOVsEU6YWsCp68dndIjSGTGLaQv2+WwV3NcnrGGZEYe5qgo33j2QWrPws2C1A==
@@ -11301,30 +11478,52 @@ slate-hotkeys@^0.2.9:
is-hotkey "0.1.4"
slate-dev-environment "^0.2.2"
-slate-plain-serializer@0.7.10:
- version "0.7.10"
- resolved "https://registry.yarnpkg.com/slate-plain-serializer/-/slate-plain-serializer-0.7.10.tgz#bc4a6942cf52fde826019bb1095dffd0dac8cc08"
- integrity sha512-/QvMCQ0F3NzbnuoW+bxsLIChPdRgxBjQeGhYhpRGTVvlZCLOmfDvavhN6fHsuEwkvdwOmocNF30xT1WVlmibYg==
+slate-plain-serializer@0.7.11:
+ version "0.7.11"
+ resolved "https://registry.yarnpkg.com/slate-plain-serializer/-/slate-plain-serializer-0.7.11.tgz#74ff6eb949e9fbd92ad98ed833d74d5082f2688b"
+ integrity sha512-vzXQ68GiHHcTUcAB6ggf2qN/sX9BoLs77SMHacp5Gkg+oHAA/NxRzRH4efDAhpiJqfJZDrA3rQySK6+Y7KAuwg==
-slate-plain-serializer@^0.7.10:
+slate-plain-serializer@^0.7.10, slate-plain-serializer@^0.7.11:
version "0.7.13"
resolved "https://registry.yarnpkg.com/slate-plain-serializer/-/slate-plain-serializer-0.7.13.tgz#6de8f5c645dd749f1b2e4426c20de74bfd213adf"
integrity sha512-TtrlaslxQBEMV0LYdf3s7VAbTxRPe1xaW10WNNGAzGA855/0RhkaHjKkQiRjHv5rvbRleVf7Nxr9fH+4uErfxQ==
-slate-prop-types@^0.5.41:
+slate-prop-types@^0.5.41, slate-prop-types@^0.5.42:
version "0.5.44"
resolved "https://registry.yarnpkg.com/slate-prop-types/-/slate-prop-types-0.5.44.tgz#da60b69c3451c3bd6cdd60a45d308eeba7e83c76"
integrity sha512-JS0iW7uaciE/W3ADuzeN1HOnSjncQhHPXJ65nZNQzB0DF7mXVmbwQKI6cmCo/xKni7XRJT0JbWSpXFhEdPiBUA==
-slate-react-placeholder@^0.2.8:
+slate-react-placeholder@^0.2.8, slate-react-placeholder@^0.2.9:
version "0.2.9"
resolved "https://registry.yarnpkg.com/slate-react-placeholder/-/slate-react-placeholder-0.2.9.tgz#30f450a05d4871c7d1a27668ebe7907861e7ca74"
integrity sha512-YSJ9Gb4tGpbzPje3eNKtu26hWM8ApxTk9RzjK+6zfD5V/RMTkuWONk24y6c9lZk0OAYNZNUmrnb/QZfU3j9nag==
-slate@0.47.8:
- version "0.47.8"
- resolved "https://registry.yarnpkg.com/slate/-/slate-0.47.8.tgz#1e987b74d8216d44ec56154f0e6d3c722ce21e6e"
- integrity sha512-/Jt0eq4P40qZvtzeKIvNb+1N97zVICulGQgQoMDH0TI8h8B+5kqa1YeckRdRnuvfYJm3J/9lWn2V3J1PrF+hag==
+slate-react@0.22.10:
+ version "0.22.10"
+ resolved "https://registry.yarnpkg.com/slate-react/-/slate-react-0.22.10.tgz#01296dadb707869ace6cb21d336c90bedfb567bf"
+ integrity sha512-B2Ms1u/REbdd8yKkOItKgrw/tX8klgz5l5x6PP86+oh/yqmB6EHe0QyrYlQ9fc3WBlJUVTOL+nyAP1KmlKj2/w==
+ dependencies:
+ debug "^3.1.0"
+ get-window "^1.1.1"
+ is-window "^1.0.2"
+ lodash "^4.1.1"
+ memoize-one "^4.0.0"
+ prop-types "^15.5.8"
+ react-immutable-proptypes "^2.1.0"
+ selection-is-backward "^1.0.0"
+ slate-base64-serializer "^0.2.112"
+ slate-dev-environment "^0.2.2"
+ slate-hotkeys "^0.2.9"
+ slate-plain-serializer "^0.7.11"
+ slate-prop-types "^0.5.42"
+ slate-react-placeholder "^0.2.9"
+ tiny-invariant "^1.0.1"
+ tiny-warning "^0.0.3"
+
+slate@0.47.9:
+ version "0.47.9"
+ resolved "https://registry.yarnpkg.com/slate/-/slate-0.47.9.tgz#090597dd790e79718f782994907d34a903739443"
+ integrity sha512-EK4O6b7lGt+g5H9PGw9O5KCM4RrOvOgE9mPi3rzQ0zDRlgAb2ga4TdpS6XNQbrsJWsc8I1fjaSsUeCqCUhhi9A==
dependencies:
debug "^3.1.0"
direction "^0.1.5"
@@ -11337,7 +11536,7 @@ slate@0.47.8:
slice-ansi@^3.0.0:
version "3.0.0"
- resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787"
integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==
dependencies:
ansi-styles "^4.0.0"
@@ -11355,14 +11554,14 @@ slice-ansi@^4.0.0:
snake-case@^2.1.0:
version "2.1.0"
- resolved "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz"
- integrity sha1-Qb2xtz8w7GagTU4srRt2OH1NbZ8=
+ resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-2.1.0.tgz#41bdb1b73f30ec66a04d4e2cad1b76387d4d6d9f"
+ integrity sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==
dependencies:
no-case "^2.2.0"
snake-case@^3.0.4:
version "3.0.4"
- resolved "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c"
integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==
dependencies:
dot-case "^3.0.4"
@@ -11498,12 +11697,12 @@ spdx-license-ids@^3.0.0:
specificity@^0.4.1:
version "0.4.1"
- resolved "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz"
+ resolved "https://registry.yarnpkg.com/specificity/-/specificity-0.4.1.tgz#aab5e645012db08ba182e151165738d00887b019"
integrity sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==
split-on-first@^1.0.0:
version "1.1.0"
- resolved "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz"
+ resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f"
integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==
split-string@^3.0.1, split-string@^3.0.2:
@@ -11574,12 +11773,12 @@ static-extend@^0.1.1:
strict-uri-encode@^2.0.0:
version "2.0.0"
- resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz"
- integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY=
+ resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546"
+ integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==
string-argv@0.3.1:
version "0.3.1"
- resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz"
+ resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da"
integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==
string-length@^4.0.1:
@@ -11592,8 +11791,8 @@ string-length@^4.0.1:
string-replace-to-array@^1.0.1:
version "1.0.3"
- resolved "https://registry.npmjs.org/string-replace-to-array/-/string-replace-to-array-1.0.3.tgz"
- integrity sha1-yT66mZpe4k1zGuu69auja18Y978=
+ resolved "https://registry.yarnpkg.com/string-replace-to-array/-/string-replace-to-array-1.0.3.tgz#c93eba999a5ee24d731aebbaf5aba36b5f18f7bf"
+ integrity sha512-QIdKvmfXbdFvblXAAz6IIjR7A+C6SU6m2A+e7fE/0EYDC5yfeWNMJQ193fPsW7nG+9q52dv/UjnVrDaNVZXpmQ==
dependencies:
invariant "^2.2.1"
lodash.flatten "^4.2.0"
@@ -11601,14 +11800,14 @@ string-replace-to-array@^1.0.1:
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
version "4.2.3"
- resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
-string.prototype.matchall@^4.0.6:
+string.prototype.matchall@^4.0.6, string.prototype.matchall@^4.0.7:
version "4.0.7"
resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz#8e6ecb0d8a1fb1fda470d81acecb2dba057a481d"
integrity sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==
@@ -11622,7 +11821,7 @@ string.prototype.matchall@^4.0.6:
regexp.prototype.flags "^1.4.1"
side-channel "^1.0.4"
-string.prototype.trimend@^1.0.4, string.prototype.trimend@^1.0.5:
+string.prototype.trimend@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0"
integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==
@@ -11631,7 +11830,7 @@ string.prototype.trimend@^1.0.4, string.prototype.trimend@^1.0.5:
define-properties "^1.1.4"
es-abstract "^1.19.5"
-string.prototype.trimstart@^1.0.4, string.prototype.trimstart@^1.0.5:
+string.prototype.trimstart@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef"
integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==
@@ -11649,7 +11848,7 @@ string_decoder@^1.1.1:
stringify-object@^3.3.0:
version "3.3.0"
- resolved "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz"
+ resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629"
integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==
dependencies:
get-own-enumerable-property-symbols "^3.0.0"
@@ -11665,14 +11864,14 @@ strip-ansi@^3.0.0:
strip-ansi@^5.2.0:
version "5.2.0"
- resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
dependencies:
ansi-regex "^4.1.0"
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
- resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"
@@ -11711,8 +11910,8 @@ style-loader@^3.3.1:
style-search@^0.1.0:
version "0.1.0"
- resolved "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz"
- integrity sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=
+ resolved "https://registry.yarnpkg.com/style-search/-/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902"
+ integrity sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==
stylehacks@^5.1.0:
version "5.1.0"
@@ -11722,21 +11921,33 @@ stylehacks@^5.1.0:
browserslist "^4.16.6"
postcss-selector-parser "^6.0.4"
+stylelint-config-prettier@^9.0.3:
+ version "9.0.3"
+ resolved "https://registry.yarnpkg.com/stylelint-config-prettier/-/stylelint-config-prettier-9.0.3.tgz#0dccebeff359dcc393c9229184408b08964d561c"
+ integrity sha512-5n9gUDp/n5tTMCq1GLqSpA30w2sqWITSSEiAWQlpxkKGAUbjcemQ0nbkRvRUa0B1LgD3+hCvdL7B1eTxy1QHJg==
+
stylelint-config-recommended@^5.0.0:
version "5.0.0"
- resolved "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-5.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/stylelint-config-recommended/-/stylelint-config-recommended-5.0.0.tgz#fb5653f495a60b4938f2ad3e77712d9e1039ae78"
integrity sha512-c8aubuARSu5A3vEHLBeOSJt1udOdS+1iue7BmJDTSXoCBmfEQmmWX+59vYIj3NQdJBY6a/QRv1ozVFpaB9jaqA==
stylelint-config-standard@^22.0.0:
version "22.0.0"
- resolved "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-22.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/stylelint-config-standard/-/stylelint-config-standard-22.0.0.tgz#c860be9a13ebbc1b084456fa10527bf13a44addf"
integrity sha512-uQVNi87SHjqTm8+4NIP5NMAyY/arXrBgimaaT7skvRfE9u3JKXRK9KBkbr4pVmeciuCcs64kAdjlxfq6Rur7Hw==
dependencies:
stylelint-config-recommended "^5.0.0"
+stylelint-prettier@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/stylelint-prettier/-/stylelint-prettier-2.0.0.tgz#ead781aea522379f2ffa2d136bafdfc451d699a5"
+ integrity sha512-jvT3G+9lopkeB0ARmDPszyfaOnvnIF+30QCjZxyt7E6fynI1T9mOKgYDNb9bXX17M7PXMZaX3j/26wqakjp1tw==
+ dependencies:
+ prettier-linter-helpers "^1.0.0"
+
stylelint@^13.13.1:
version "13.13.1"
- resolved "https://registry.npmjs.org/stylelint/-/stylelint-13.13.1.tgz"
+ resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-13.13.1.tgz#fca9c9f5de7990ab26a00f167b8978f083a18f3c"
integrity sha512-Mv+BQr5XTUrKqAXmpqm6Ddli6Ief+AiPZkRsIrAoUKFuq/ElkUh9ZMYxXD0iQNZ5ADghZKLOWz1h7hTClB7zgQ==
dependencies:
"@stylelint/postcss-css-in-js" "^0.37.2"
@@ -11794,13 +12005,13 @@ stylis@4.0.13:
integrity sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==
stylis@^4.0.6:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.1.tgz#e46c6a9bbf7c58db1e65bb730be157311ae1fe12"
- integrity sha512-lVrM/bNdhVX2OgBFNa2YJ9Lxj7kPzylieHd3TNjuGE0Re9JB7joL5VUKOVH1kdNNJTgGPpT8hmwIAPLaSyEVFQ==
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.2.tgz#870b3c1c2275f51b702bb3da9e94eedad87bba41"
+ integrity sha512-Nn2CCrG2ZaFziDxaZPN43CXqn+j7tcdjPFCkRBkFue8QYXC2HdEwnw5TCBo4yQZ2WxKYeSi0fdoOrtEqgDrXbA==
sugarss@^2.0.0:
version "2.0.0"
- resolved "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-2.0.0.tgz#ddd76e0124b297d40bf3cca31c8b22ecb43bc61d"
integrity sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==
dependencies:
postcss "^7.0.2"
@@ -11832,9 +12043,9 @@ supports-color@^8.0.0:
has-flag "^4.0.0"
supports-hyperlinks@^2.0.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb"
- integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624"
+ integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==
dependencies:
has-flag "^4.0.0"
supports-color "^7.0.0"
@@ -11846,8 +12057,8 @@ supports-preserve-symlinks-flag@^1.0.0:
svg-tags@^1.0.0:
version "1.0.0"
- resolved "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz"
- integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=
+ resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764"
+ integrity sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==
svgo@^2.7.0:
version "2.8.0"
@@ -11864,8 +12075,8 @@ svgo@^2.7.0:
swap-case@^1.1.0:
version "1.1.2"
- resolved "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz"
- integrity sha1-w5IDpFhzhfrTyFCgvRvK+ggZdOM=
+ resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-1.1.2.tgz#c39203a4587385fad3c850a0bd1bcafa081974e3"
+ integrity sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==
dependencies:
lower-case "^1.1.1"
upper-case "^1.1.1"
@@ -11882,7 +12093,7 @@ systemjs@0.20.19:
table@^6.6.0:
version "6.8.0"
- resolved "https://registry.npmjs.org/table/-/table-6.8.0.tgz"
+ resolved "https://registry.yarnpkg.com/table/-/table-6.8.0.tgz#87e28f14fa4321c3377ba286f07b79b281a3b3ca"
integrity sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==
dependencies:
ajv "^8.0.1"
@@ -11910,9 +12121,9 @@ terminal-link@^2.0.0:
supports-hyperlinks "^2.0.0"
terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.3.1:
- version "5.3.5"
- resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.5.tgz#f7d82286031f915a4f8fb81af4bd35d2e3c011bc"
- integrity sha512-AOEDLDxD2zylUGf/wxHxklEkOe2/r+seuyOWujejFrIxHf11brA1/dWQNIgXa1c6/Wkxgu7zvv0JhOWfc2ELEA==
+ version "5.3.6"
+ resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz#5590aec31aa3c6f771ce1b1acca60639eab3195c"
+ integrity sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==
dependencies:
"@jridgewell/trace-mapping" "^0.3.14"
jest-worker "^27.4.5"
@@ -11921,9 +12132,9 @@ terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.3.1:
terser "^5.14.1"
terser@^5.10.0, terser@^5.14.1:
- version "5.15.0"
- resolved "https://registry.yarnpkg.com/terser/-/terser-5.15.0.tgz#e16967894eeba6e1091509ec83f0c60e179f2425"
- integrity sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==
+ version "5.15.1"
+ resolved "https://registry.yarnpkg.com/terser/-/terser-5.15.1.tgz#8561af6e0fd6d839669c73b92bdd5777d870ed6c"
+ integrity sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==
dependencies:
"@jridgewell/source-map" "^0.3.2"
acorn "^8.5.0"
@@ -11951,7 +12162,7 @@ throat@^6.0.1:
throttle-debounce@^2.1.0:
version "2.3.0"
- resolved "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.3.0.tgz"
+ resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-2.3.0.tgz#fd31865e66502071e411817e241465b3e9c372e2"
integrity sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==
throttle-debounce@^3.0.1:
@@ -11961,27 +12172,22 @@ throttle-debounce@^3.0.1:
through@^2.3.6, through@^2.3.8:
version "2.3.8"
- resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz"
- integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
+ resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
+ integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
-tiny-invariant@^1.0.1, tiny-invariant@^1.0.6:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.2.0.tgz#a1141f86b672a9148c72e978a19a73b9b94a15a9"
- integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==
-
-tiny-invariant@^1.0.2:
- version "1.1.0"
- resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz"
- integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==
+tiny-invariant@^1.0.1, tiny-invariant@^1.0.2, tiny-invariant@^1.0.6:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642"
+ integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==
tiny-warning@^0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-0.0.3.tgz#1807eb4c5f81784a6354d58ea1d5024f18c6c81f"
integrity sha512-r0SSA5Y5IWERF9Xh++tFPx0jITBgGggOsRLDWWew6YRw/C2dr4uNO1fw1vanrBmHsICmPyMLNBZboTlxUmUuaA==
-tiny-warning@^1.0.0, tiny-warning@^1.0.3:
+tiny-warning@^1.0.0:
version "1.0.3"
- resolved "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz"
+ resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
tinycolor2@1.4.2:
@@ -11991,8 +12197,8 @@ tinycolor2@1.4.2:
title-case@^2.1.0:
version "2.1.1"
- resolved "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz"
- integrity sha1-PhJyFtpY0rxb7PE3q5Ha46fNj6o=
+ resolved "https://registry.yarnpkg.com/title-case/-/title-case-2.1.1.tgz#3e127216da58d2bc5becf137ab91dae3a7cd8faa"
+ integrity sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==
dependencies:
no-case "^2.2.0"
upper-case "^1.0.3"
@@ -12067,18 +12273,18 @@ to-space-case@^1.0.0:
toggle-selection@^1.0.6:
version "1.0.6"
- resolved "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz"
- integrity sha1-bkWxJj8gF/oKzH2J14sVuL932jI=
+ resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
+ integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==
totalist@^1.0.0:
version "1.1.0"
- resolved "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz"
+ resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df"
integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==
tough-cookie@^4.0.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.0.tgz#039b203b2ad95cd9d2a2aae07b238cb83adc46c7"
- integrity sha512-IVX6AagLelGwl6F0E+hoRpXzuD192cZhAcmT7/eoLr0PnsB1wv2E5c+A2O+V8xth9FlL2p0OstFsWn0bZpVn4w==
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874"
+ integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==
dependencies:
psl "^1.1.33"
punycode "^2.1.1"
@@ -12094,12 +12300,12 @@ tr46@^2.1.0:
trim-newlines@^3.0.0:
version "3.0.1"
- resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz"
+ resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144"
integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==
trough@^1.0.0:
version "1.0.5"
- resolved "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz"
+ resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406"
integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==
ts-easing@^0.2.0:
@@ -12121,10 +12327,24 @@ ts-jest@27.1.3:
semver "7.x"
yargs-parser "20.x"
+ts-jest@^27.1.3:
+ version "27.1.5"
+ resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.5.tgz#0ddf1b163fbaae3d5b7504a1e65c914a95cff297"
+ integrity sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==
+ dependencies:
+ bs-logger "0.x"
+ fast-json-stable-stringify "2.x"
+ jest-util "^27.0.0"
+ json5 "2.x"
+ lodash.memoize "4.x"
+ make-error "1.x"
+ semver "7.x"
+ yargs-parser "20.x"
+
ts-loader@^9.3.1:
- version "9.3.1"
- resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.3.1.tgz#fe25cca56e3e71c1087fe48dc67f4df8c59b22d4"
- integrity sha512-OkyShkcZTsTwyS3Kt7a4rsT/t2qvEVQuKCTg4LJmpj9fhFR7ukGdZwV6Qq3tRUkqcXtfGpPR7+hFKHCG/0d3Lw==
+ version "9.4.1"
+ resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.4.1.tgz#b6f3d82db0eac5a8295994f8cb5e4940ff6b1060"
+ integrity sha512-384TYAqGs70rn9F0VBnh6BPTfhga7yFNdC5gXbQpDrBj9/KsT4iRkGqKXhziofHOlE2j6YEaiTYVGKKvPhGWvw==
dependencies:
chalk "^4.1.0"
enhanced-resolve "^5.0.0"
@@ -12143,14 +12363,14 @@ ts-node@^9.1.0:
source-map-support "^0.5.17"
yn "3.1.1"
-tsconfig-paths@^3.12.0:
- version "3.12.0"
- resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz"
- integrity sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==
+tsconfig-paths@^3.14.1:
+ version "3.14.1"
+ resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a"
+ integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==
dependencies:
"@types/json5" "^0.0.29"
json5 "^1.0.1"
- minimist "^1.2.0"
+ minimist "^1.2.6"
strip-bom "^3.0.0"
tslib@2.4.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0:
@@ -12191,7 +12411,7 @@ type-detect@4.0.8:
type-fest@^0.18.0:
version "0.18.1"
- resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f"
integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==
type-fest@^0.20.2:
@@ -12242,11 +12462,11 @@ ua-parser-js@^1.0.2:
integrity sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg==
uglify-js@^3.1.4:
- version "3.13.10"
- resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.10.tgz"
- integrity sha512-57H3ACYFXeo1IaZ1w02sfA71wI60MGco/IQFjOqK+WtKoprh7Go2/yvd2HPtoJILO2Or84ncLccI4xoHMTSbGg==
+ version "3.17.3"
+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.3.tgz#f0feedf019c4510f164099e8d7e72ff2d7304377"
+ integrity sha512-JmMFDME3iufZnBpyKL+uS78LRiC+mK55zWfM5f/pWBJfpOttXAqYfdDGRukYhJuyRinvPVAtUhvy7rlDybNtFg==
-unbox-primitive@^1.0.1, unbox-primitive@^1.0.2:
+unbox-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==
@@ -12258,8 +12478,8 @@ unbox-primitive@^1.0.1, unbox-primitive@^1.0.2:
unc-path-regex@^0.1.2:
version "0.1.2"
- resolved "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz"
- integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo=
+ resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
+ integrity sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==
unicode-canonical-property-names-ecmascript@^2.0.0:
version "2.0.0"
@@ -12280,13 +12500,13 @@ unicode-match-property-value-ecmascript@^2.0.0:
integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==
unicode-property-aliases-ecmascript@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8"
- integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd"
+ integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==
unified@^9.1.0:
version "9.2.2"
- resolved "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz"
+ resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975"
integrity sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==
dependencies:
bail "^1.0.0"
@@ -12308,19 +12528,19 @@ union-value@^1.0.0:
unist-util-find-all-after@^3.0.2:
version "3.0.2"
- resolved "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-3.0.2.tgz"
+ resolved "https://registry.yarnpkg.com/unist-util-find-all-after/-/unist-util-find-all-after-3.0.2.tgz#fdfecd14c5b7aea5e9ef38d5e0d5f774eeb561f6"
integrity sha512-xaTC/AGZ0rIM2gM28YVRAFPIZpzbpDtU3dRmp7EXlNVA8ziQc4hY3H7BHXM1J49nEmiqc3svnqMReW+PGqbZKQ==
dependencies:
unist-util-is "^4.0.0"
unist-util-is@^4.0.0:
version "4.1.0"
- resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz"
+ resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797"
integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==
unist-util-stringify-position@^2.0.0:
version "2.0.3"
- resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz"
+ resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da"
integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==
dependencies:
"@types/unist" "^2.0.2"
@@ -12343,10 +12563,10 @@ unset-value@^1.0.0:
has-value "^0.3.1"
isobject "^3.0.0"
-update-browserslist-db@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38"
- integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==
+update-browserslist-db@^1.0.9:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3"
+ integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==
dependencies:
escalade "^3.1.1"
picocolors "^1.0.0"
@@ -12358,26 +12578,26 @@ uplot@1.6.22:
upper-case-first@^1.1.0, upper-case-first@^1.1.2:
version "1.1.2"
- resolved "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz"
- integrity sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=
+ resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-1.1.2.tgz#5d79bedcff14419518fd2edb0a0507c9b6859115"
+ integrity sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==
dependencies:
upper-case "^1.1.1"
upper-case-first@^2.0.2:
version "2.0.2"
- resolved "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz"
+ resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-2.0.2.tgz#992c3273f882abd19d1e02894cc147117f844324"
integrity sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==
dependencies:
tslib "^2.0.3"
upper-case@^1.0.3, upper-case@^1.1.0, upper-case@^1.1.1, upper-case@^1.1.3:
version "1.1.3"
- resolved "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz"
- integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=
+ resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598"
+ integrity sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==
upper-case@^2.0.2:
version "2.0.2"
- resolved "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz"
+ resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-2.0.2.tgz#d89810823faab1df1549b7d97a76f8662bae6f7a"
integrity sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==
dependencies:
tslib "^2.0.3"
@@ -12412,9 +12632,9 @@ url-parse@^1.5.3:
requires-port "^1.0.0"
use-memo-one@^1.1.1:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.2.tgz#0c8203a329f76e040047a35a1197defe342fab20"
- integrity sha512-u2qFKtxLsia/r8qG0ZKkbytbztzRb317XCkT7yP8wxL0tZ/CzK2G+WWie5vWvpyeP7+YoPIwbJoIHJ4Ba4k0oQ==
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.3.tgz#2fd2e43a2169eabc7496960ace8c79efef975e99"
+ integrity sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==
use@^3.1.0:
version "3.1.1"
@@ -12423,8 +12643,8 @@ use@^3.1.0:
user-home@^1.1.1:
version "1.1.1"
- resolved "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz"
- integrity sha1-K1viOjK2Onyd640PKNSFcko98ZA=
+ resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190"
+ integrity sha512-aggiKfEEubv3UwRNqTzLInZpAOmKzwdHqEBmW/hBA/mt99eg+b4VrX6i+IRLxU8+WJYfa33rGwRseg4eElUgsQ==
util-deprecate@^1.0.1, util-deprecate@^1.0.2:
version "1.0.2"
@@ -12443,7 +12663,7 @@ uuid@8.3.2, uuid@^8.3.2:
v8-compile-cache@^2.0.3, v8-compile-cache@^2.3.0:
version "2.3.0"
- resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz"
+ resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
v8-to-istanbul@^8.1.0:
@@ -12457,8 +12677,8 @@ v8-to-istanbul@^8.1.0:
v8flags@^2.0.10:
version "2.1.1"
- resolved "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz"
- integrity sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=
+ resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4"
+ integrity sha512-SKfhk/LlaXzvtowJabLZwD4K6SGRYeoxA7KJeISlUMAB/NT4CBkZjMq3WceX2Ckm4llwqYVo8TICgsDYCBU2tA==
dependencies:
user-home "^1.1.1"
@@ -12472,12 +12692,12 @@ validate-npm-package-license@^3.0.1:
value-equal@^1.0.1:
version "1.0.1"
- resolved "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz"
+ resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c"
integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==
vfile-message@^2.0.0:
version "2.0.4"
- resolved "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a"
integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==
dependencies:
"@types/unist" "^2.0.0"
@@ -12485,7 +12705,7 @@ vfile-message@^2.0.0:
vfile@^4.0.0:
version "4.2.1"
- resolved "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz"
+ resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624"
integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==
dependencies:
"@types/unist" "^2.0.0"
@@ -12659,8 +12879,8 @@ word-wrap@^1.2.3, word-wrap@~1.2.3:
wordwrap@^1.0.0:
version "1.0.0"
- resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz"
- integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
+ resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
+ integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
wrap-ansi@^6.2.0:
version "6.2.0"
@@ -12673,7 +12893,7 @@ wrap-ansi@^6.2.0:
wrap-ansi@^7.0.0:
version "7.0.0"
- resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
@@ -12687,7 +12907,7 @@ wrappy@1:
write-file-atomic@^3.0.0, write-file-atomic@^3.0.3:
version "3.0.3"
- resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz"
+ resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8"
integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==
dependencies:
imurmurhash "^0.1.4"
@@ -12695,12 +12915,7 @@ write-file-atomic@^3.0.0, write-file-atomic@^3.0.3:
signal-exit "^3.0.2"
typedarray-to-buffer "^3.1.5"
-ws@^7.3.1:
- version "7.4.6"
- resolved "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz"
- integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
-
-ws@^7.4.6:
+ws@^7.3.1, ws@^7.4.6:
version "7.5.9"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591"
integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==
@@ -12711,9 +12926,9 @@ xml-name-validator@^3.0.0:
integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
xml-utils@^1.0.2:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/xml-utils/-/xml-utils-1.2.0.tgz#6ff0f45087154c6be7004e6dbeeb9eb26ec3f558"
- integrity sha512-z4unVPZruEDC3tfyd7wvWfjclnMz34iwQpv8H28H+qREpjKkR083MBvcrWXfJrIcrSmHR5ghguOcgQqWdnBpVA==
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/xml-utils/-/xml-utils-1.3.0.tgz#f1043534e3ac3deda12ddab39f8442e16da98ebb"
+ integrity sha512-i4PIrX33Wd66dvwo4syicwlwmnr6wuvvn4f2ku9hA67C2Uk62Xubczuhct+Evnd12/DV71qKNeDdJwES8HX1RA==
xml@^1.0.1:
version "1.0.1"
@@ -12745,12 +12960,12 @@ yallist@^4.0.0:
yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2:
version "1.10.2"
- resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz"
+ resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
yargs-parser@20.x, yargs-parser@^20.2.2, yargs-parser@^20.2.3:
version "20.2.9"
- resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
yargs@^16.2.0:
@@ -12778,5 +12993,5 @@ yocto-queue@^0.1.0:
zwitch@^1.0.0:
version "1.0.5"
- resolved "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz"
+ resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920"
integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==
diff --git a/helm/oncall/Chart.yaml b/helm/oncall/Chart.yaml
index a4849952..f7708ca6 100644
--- a/helm/oncall/Chart.yaml
+++ b/helm/oncall/Chart.yaml
@@ -8,13 +8,13 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
-version: 1.0.5
+version: 1.0.6
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
-appVersion: "v1.0.35"
+appVersion: "v1.0.40"
dependencies:
- name: cert-manager
version: v1.8.0
diff --git a/helm/oncall/templates/_env.tpl b/helm/oncall/templates/_env.tpl
index ed3c2f83..25072fc1 100644
--- a/helm/oncall/templates/_env.tpl
+++ b/helm/oncall/templates/_env.tpl
@@ -33,10 +33,10 @@
value: {{ .Values.oncall.slack.clientId | default "" | quote }}
- name: SLACK_CLIENT_OAUTH_SECRET
value: {{ .Values.oncall.slack.clientSecret | default "" | quote }}
-- name: SLACK_API_TOKEN
- value: {{ .Values.oncall.slack.apiToken | default "" | quote }}
-- name: SLACK_API_TOKEN_COMMON
- value: {{ .Values.oncall.slack.apiTokenCommon | default "" | quote }}
+- name: SLACK_SIGNING_SECRET
+ value: {{ .Values.oncall.slack.signingSecret | default "" | quote }}
+- name: SLACK_INSTALL_RETURN_REDIRECT_HOST
+ value: "https://{{ .Values.base_url }}"
{{- else -}}
- name: FEATURE_SLACK_INTEGRATION_ENABLED
value: {{ .Values.oncall.slack.enabled | toString | title | quote }}
@@ -47,7 +47,7 @@
{{- if .Values.oncall.telegram.enabled -}}
- name: FEATURE_TELEGRAM_INTEGRATION_ENABLED
value: {{ .Values.oncall.telegram.enabled | toString | title | quote }}
-- name: TELEGRAM_WEBHOOK_URL
+- name: TELEGRAM_WEBHOOK_HOST
value: {{ .Values.oncall.telegram.webhookUrl | default "" | quote }}
- name: TELEGRAM_TOKEN
value: {{ .Values.oncall.telegram.token | default "" | quote }}
@@ -58,16 +58,26 @@
{{- end }}
{{- define "snippet.celery.env" -}}
+{{- if .Values.celery.worker_queue }}
- name: CELERY_WORKER_QUEUE
- value: "default,critical,long,slack,telegram,webhook,celery"
+ value: {{ .Values.celery.worker_queue }}
+{{- end -}}
+{{- if .Values.celery.worker_concurrency }}
- name: CELERY_WORKER_CONCURRENCY
- value: "1"
+ value: {{ .Values.celery.worker_concurrency | quote }}
+{{- end -}}
+{{- if .Values.celery.worker_max_tasks_per_child }}
- name: CELERY_WORKER_MAX_TASKS_PER_CHILD
- value: "100"
-- name: CELERY_WORKER_SHUTDOWN_INTERVAL
- value: "65m"
+ value: {{ .Values.celery.worker_max_tasks_per_child | quote }}
+{{- end -}}
+{{- if .Values.celery.worker_beat_enabled }}
- name: CELERY_WORKER_BEAT_ENABLED
- value: "True"
+ value: {{ .Values.celery.worker_beat_enabled | quote }}
+{{- end -}}
+{{- if .Values.celery.worker_shutdown_interval }}
+- name: CELERY_WORKER_SHUTDOWN_INTERVAL
+ value: {{ .Values.celery.worker_shutdown_interval }}
+{{- end -}}
{{- end }}
{{- define "snippet.mysql.env" -}}
@@ -219,3 +229,28 @@
name: {{ template "snippet.redis.password.secret.name" . }}
key: redis-password
{{- end }}
+
+{{- define "snippet.oncall.smtp.env" -}}
+{{- if .Values.oncall.smtp.enabled -}}
+- name: FEATURE_EMAIL_INTEGRATION_ENABLED
+ value: {{ .Values.oncall.smtp.enabled | toString | title | quote }}
+- name: EMAIL_HOST
+ value: {{ .Values.oncall.smtp.host | quote }}
+- name: EMAIL_PORT
+ value: {{ .Values.oncall.smtp.port | default "587" | quote }}
+- name: EMAIL_HOST_USER
+ value: {{ .Values.oncall.smtp.username | quote }}
+- name: EMAIL_HOST_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: {{ include "oncall.fullname" . }}-smtp
+ key: smtp-password
+- name: EMAIL_USE_TLS
+ value: {{ .Values.oncall.smtp.tls | toString | title | quote }}
+- name: DEFAULT_FROM_EMAIL
+ value: {{ .Values.oncall.smtp.fromEmail | quote }}
+{{- else -}}
+- name: FEATURE_EMAIL_INTEGRATION_ENABLED
+ value: {{ .Values.oncall.smtp.enabled | toString | title | quote }}
+{{- end -}}
+{{- end }}
diff --git a/helm/oncall/templates/celery/_deployment.tpl b/helm/oncall/templates/celery/_deployment.tpl
index 5378c834..0892c0cb 100644
--- a/helm/oncall/templates/celery/_deployment.tpl
+++ b/helm/oncall/templates/celery/_deployment.tpl
@@ -41,6 +41,7 @@ spec:
{{- include "snippet.oncall.env" . | nindent 12 }}
{{- include "snippet.oncall.slack.env" . | nindent 12 }}
{{- include "snippet.oncall.telegram.env" . | nindent 12 }}
+ {{- include "snippet.oncall.smtp.env" . | nindent 12 }}
{{- include "snippet.mysql.env" . | nindent 12 }}
{{- include "snippet.rabbitmq.env" . | nindent 12 }}
{{- include "snippet.redis.env" . | nindent 12 }}
diff --git a/helm/oncall/templates/engine/deployment.yaml b/helm/oncall/templates/engine/deployment.yaml
index 216d3055..5b1f7776 100644
--- a/helm/oncall/templates/engine/deployment.yaml
+++ b/helm/oncall/templates/engine/deployment.yaml
@@ -47,6 +47,7 @@ spec:
{{- include "snippet.oncall.env" . | nindent 12 }}
{{- include "snippet.oncall.slack.env" . | nindent 12 }}
{{- include "snippet.oncall.telegram.env" . | nindent 12 }}
+ {{- include "snippet.oncall.smtp.env" . | nindent 12 }}
{{- include "snippet.mysql.env" . | nindent 12 }}
{{- include "snippet.rabbitmq.env" . | nindent 12 }}
{{- include "snippet.redis.env" . | nindent 12 }}
diff --git a/helm/oncall/templates/engine/job-migrate.yaml b/helm/oncall/templates/engine/job-migrate.yaml
index 5bfc3019..8778f420 100644
--- a/helm/oncall/templates/engine/job-migrate.yaml
+++ b/helm/oncall/templates/engine/job-migrate.yaml
@@ -43,6 +43,7 @@ spec:
python manage.py migrate
env:
{{- include "snippet.oncall.env" . | nindent 12 }}
+ {{- include "snippet.oncall.smtp.env" . | nindent 12 }}
{{- include "snippet.mysql.env" . | nindent 12 }}
{{- include "snippet.rabbitmq.env" . | nindent 12 }}
{{- include "snippet.redis.env" . | nindent 12 }}
diff --git a/helm/oncall/templates/secrets.yaml b/helm/oncall/templates/secrets.yaml
index 88b4eaed..64d1e22c 100644
--- a/helm/oncall/templates/secrets.yaml
+++ b/helm/oncall/templates/secrets.yaml
@@ -40,4 +40,13 @@ type: Opaque
data:
redis-password: {{ required "externalRedis.password is required if not redis.enabled" .Values.externalRedis.password | b64enc | quote }}
{{- end }}
-
+---
+{{ if .Values.oncall.smtp.enabled -}}
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{ include "oncall.fullname" . }}-smtp
+type: Opaque
+data:
+ smtp-password: {{ required "oncall.smtp.password is required if oncall.smtp.enabled" .Values.oncall.smtp.password | b64enc | quote }}
+{{- end }}
diff --git a/helm/oncall/values.yaml b/helm/oncall/values.yaml
index 87e2516f..db665bd6 100644
--- a/helm/oncall/values.yaml
+++ b/helm/oncall/values.yaml
@@ -44,6 +44,16 @@ engine:
# Celery workers pods configuration
celery:
replicaCount: 1
+ worker_queue: "default,critical,long,slack,telegram,webhook,celery"
+ worker_concurrency: "1"
+ worker_max_tasks_per_child: "100"
+ worker_beat_enabled: "True"
+ ## Restart of the celery workers once in a given interval as an additional precaution to the probes
+ ## If this setting is enabled TERM signal will be sent to celery workers
+ ## It will lead to warm shutdown (waiting for the tasks to complete) and restart the container
+ ## If this setting is set numbers of pod restarts will increase
+ ## Comment this line out if you want to remove restarts
+ worker_shutdown_interval: "65m"
livenessProbe:
enabled: true
initialDelaySeconds: 30
@@ -58,17 +68,34 @@ celery:
# memory: 128Mi
oncall:
+ # slack configures the Grafana Oncall Slack ChatOps integration.
slack:
+ # enabled enable the Slack ChatOps integration for the Oncall Engine.
enabled: false
- command: ~
+ # command sets the Slack bot slash-command
+ command: oncall
+ # clientId configures the Slack app OAuth2 client ID.
+ # api.slack.com/apps/ -> Basic Information -> App Credentials -> Client ID
clientId: ~
+ # clientSecret configures the Slack app OAuth2 client secret.
+ # api.slack.com/apps/ -> Basic Information -> App Credentials -> Client Secret
clientSecret: ~
- apiToken: ~
- apiTokenCommon: ~
+ # signingSecret configures the Slack app signature secret used to sign
+ # requests comming from Slack.
+ # api.slack.com/apps/ -> Basic Information -> App Credentials -> Signing Secret
+ signingSecret: ~
telegram:
enabled: false
token: ~
webhookUrl: ~
+ smtp:
+ enabled: false
+ host: ~
+ port: ~
+ username: ~
+ password: ~
+ tls: ~
+ fromEmail: ~
# Whether to run django database migrations automatically
migrate:
diff --git a/tools/pagerduty-migrator/README.md b/tools/pagerduty-migrator/README.md
index b83f550d..0399bb2c 100644
--- a/tools/pagerduty-migrator/README.md
+++ b/tools/pagerduty-migrator/README.md
@@ -37,7 +37,8 @@ pd-oncall-migrator
Please read the generated report carefully since depending on the content of the report, some PagerDuty resources could not be migrated and some existing Grafana OnCall resources could be deleted.
-Note that users are matched by email, so if there are users in the report with "no Grafana OnCall user found with this email" error, it's possible to fix it by adding these users to your Grafana organization.
+Note that users are matched by email, so if there are users in the report with "no Grafana OnCall user found with this email" error, it's possible to fix it by adding these users to your Grafana organization.
+If there is a large number of unmatched users, please also [see the script](scripts/README.md) that can automatically create missing Grafana users via Grafana HTTP API.
### Example migration plan
diff --git a/tools/pagerduty-migrator/migrator/config.py b/tools/pagerduty-migrator/migrator/config.py
index 951a41cd..a30804cc 100644
--- a/tools/pagerduty-migrator/migrator/config.py
+++ b/tools/pagerduty-migrator/migrator/config.py
@@ -8,7 +8,10 @@ assert MODE in (MODE_PLAN, MODE_MIGRATE)
PAGERDUTY_API_TOKEN = os.environ["PAGERDUTY_API_TOKEN"]
ONCALL_API_TOKEN = os.environ["ONCALL_API_TOKEN"]
-ONCALL_API_URL = urljoin(os.environ["ONCALL_API_URL"], "api/v1/")
+ONCALL_API_URL = urljoin(
+ os.environ["ONCALL_API_URL"].removesuffix("/") + "/",
+ "api/v1/",
+)
ONCALL_DELAY_OPTIONS = [1, 5, 15, 30, 60]
ONCALL_DEFAULT_CONTACT_METHOD = "notify_by_" + os.getenv(
diff --git a/tools/pagerduty-migrator/migrator/report.py b/tools/pagerduty-migrator/migrator/report.py
index 29a66ce0..39c769ca 100644
--- a/tools/pagerduty-migrator/migrator/report.py
+++ b/tools/pagerduty-migrator/migrator/report.py
@@ -55,6 +55,10 @@ def format_integration(integration: dict) -> str:
ERROR_SIGN, result
)
)
+
+ if integration["vendor_name"]:
+ result += ": '{}'".format(integration["vendor_name"])
+
elif integration["is_escalation_policy_flawed"]:
policy_name = integration["service"]["escalation_policy"]["summary"]
result = "{} {} — escalation policy '{}' references unmatched users or schedules with unmatched users".format(
diff --git a/tools/pagerduty-migrator/migrator/resources/integrations.py b/tools/pagerduty-migrator/migrator/resources/integrations.py
index 5d8a0932..90c91943 100644
--- a/tools/pagerduty-migrator/migrator/resources/integrations.py
+++ b/tools/pagerduty-migrator/migrator/resources/integrations.py
@@ -17,20 +17,15 @@ def match_integration(integration: dict, oncall_integrations: list[dict]) -> Non
def match_integration_type(integration: dict, vendors: list[dict]) -> None:
vendors_map = {vendor["id"]: vendor for vendor in vendors}
- if (
- integration["type"]
- not in [
- "generic_events_api_inbound_integration",
- "events_api_v2_inbound_integration",
- ]
- or integration["vendor"] is None
- ):
+ if integration["vendor"] is None:
+ integration["vendor_name"] = None
integration["oncall_type"] = None
return
vendor_id = integration["vendor"]["id"]
vendor_name = vendors_map[vendor_id]["name"]
+ integration["vendor_name"] = vendor_name
integration["oncall_type"] = PAGERDUTY_TO_ONCALL_VENDOR_MAP.get(vendor_name)
diff --git a/tools/pagerduty-migrator/scripts/README.md b/tools/pagerduty-migrator/scripts/README.md
index c1aab511..ddd50f87 100644
--- a/tools/pagerduty-migrator/scripts/README.md
+++ b/tools/pagerduty-migrator/scripts/README.md
@@ -1,12 +1,16 @@
# PagerDuty migrator scripts
-When we run MODE="plan" we can notice that there is escalation, integration in pagerduty that needs to be linked to a user.
+When running the migrator in `plan` mode, it can potentially show that some users cannot be matched (meaning that there are no users in Grafana with the same email as in PagerDuty).
-To solve this problem, we can run the add_users_pagerduty_to_grafana.py script
+If there is a large number of unmatched users, it can be easier to use the following script that automatically creates missing Grafana users:
```bash
-docker run -it --rm -e PAGERDUTY_API_TOKEN="mytoken" -e GRAFANA_URL="http://localhost:3000" -e GRAFANA_USERNAME="admin" -e GRAFANA_PASSWORD="admin" pd-oncall-migrator python /app/scripts/add_users_pagerduty_to_grafana.py
+docker run --rm \
+-e PAGERDUTY_API_TOKEN="" \
+-e GRAFANA_URL="http://localhost:3000" \
+-e GRAFANA_USERNAME="admin" \
+-e GRAFANA_PASSWORD="admin" \
+pd-oncall-migrator python /app/scripts/add_users_pagerduty_to_grafana.py
```
-It is worth remembering that this script will create a user with a random password.
-To access with the user created, it will be necessary to change the password in grafana web.
\ No newline at end of file
+The script will create users with random passwords, so they will need to reset their passwords later in Grafana.
diff --git a/tools/pagerduty-migrator/scripts/add_users_pagerduty_to_grafana.py b/tools/pagerduty-migrator/scripts/add_users_pagerduty_to_grafana.py
index 28aa542e..b0d7bd7d 100644
--- a/tools/pagerduty-migrator/scripts/add_users_pagerduty_to_grafana.py
+++ b/tools/pagerduty-migrator/scripts/add_users_pagerduty_to_grafana.py
@@ -1,19 +1,20 @@
import os
import secrets
import sys
-import requests
-
from urllib.parse import urljoin
+
+import requests
from pdpyras import APISession
PAGERDUTY_API_TOKEN = os.environ["PAGERDUTY_API_TOKEN"]
PATH_USERS_GRAFANA = "/api/admin/users"
-GRAFANA_URL = os.environ["GRAFANA_URL"] # Example: http://localhost:3000
+GRAFANA_URL = os.environ["GRAFANA_URL"] # Example: http://localhost:3000
GRAFANA_USERNAME = os.environ["GRAFANA_USERNAME"]
GRAFANA_PASSWORD = os.environ["GRAFANA_PASSWORD"]
SUCCESS_SIGN = "✅"
ERROR_SIGN = "❌"
+
def list_pagerduty_users():
session = APISession(PAGERDUTY_API_TOKEN)
@@ -22,21 +23,30 @@ def list_pagerduty_users():
for user in users:
password = secrets.token_urlsafe(15)
username = user["email"].split("@")[0]
- json = {"name": user["name"], "email": user["email"], "login": username, "password": password}
+ json = {
+ "name": user["name"],
+ "email": user["email"],
+ "login": username,
+ "password": password,
+ }
create_grafana_user(json)
+
def create_grafana_user(data):
url = urljoin(GRAFANA_URL, PATH_USERS_GRAFANA)
- response = requests.request("POST", url, auth=(GRAFANA_USERNAME, GRAFANA_PASSWORD), json=data)
+ response = requests.request(
+ "POST", url, auth=(GRAFANA_USERNAME, GRAFANA_PASSWORD), json=data
+ )
if response.status_code == 200:
print(SUCCESS_SIGN + " User created: " + data["login"])
elif response.status_code == 401:
sys.exit(ERROR_SIGN + " Invalid username or password.")
elif response.status_code == 412:
- print(ERROR_SIGN + " User " + data["login"] + " already exists." )
- else:
+ print(ERROR_SIGN + " User " + data["login"] + " already exists.")
+ else:
print("{} {}".format(ERROR_SIGN, response.text))
+
if __name__ == "__main__":
- list_pagerduty_users()
\ No newline at end of file
+ list_pagerduty_users()