diff --git a/.versionrc.js b/.versionrc.js index b993050b3..3f1091303 100644 --- a/.versionrc.js +++ b/.versionrc.js @@ -74,10 +74,6 @@ module.exports = { filename: './packages/internal/docs/package.json', type: 'json', }, - { - filename: './packages/internal/local-ws-server/package.json', - type: 'json', - }, { filename: './packages/internal/status-dashboard/package.json', type: 'json', diff --git a/docker-compose.local.yml b/docker-compose.local.yml index 944997340..8c9fcc735 100644 --- a/docker-compose.local.yml +++ b/docker-compose.local.yml @@ -7,6 +7,9 @@ volumes: web_backend_staticfiles: {} + redis_cache: + driver: local + services: db: volumes: @@ -28,7 +31,6 @@ services: - localstack - mailcatcher - workers - - localwsserver workers: volumes: @@ -49,6 +51,10 @@ services: ports: - "3005:3005" + redis: + volumes: + - redis_cache:/data + localstack: image: localstack/localstack:2.3.0 ports: @@ -78,13 +84,3 @@ services: - "1080:1080" - "1025:1025" restart: always - - localwsserver: - build: ./packages/internal/local-ws-server - ports: - - "8080:8080" - environment: - - BE_ENDPOINT_URL=http://backend:5001/ - volumes: - - ./packages/internal/local-ws-server/:/app/ - - /app/node_modules/ diff --git a/docker-compose.yml b/docker-compose.yml index 3c32de0e7..00972592b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,9 +29,12 @@ services: condition: service_started db: condition: service_healthy + redis: + condition: service_healthy restart: unless-stopped links: - db + - redis environment: - AWS_ACCESS_KEY_ID=foo - AWS_SECRET_ACCESS_KEY=bar @@ -49,6 +52,17 @@ services: links: - db + redis: + image: redis:7.2.4-alpine + restart: always + ports: + - '6379:6379' + healthcheck: + test: [ "CMD", "redis-cli", "--raw", "incr", "ping" ] + interval: 10s + timeout: 5s + retries: 5 + stripemock: image: stripe/stripe-mock:v0.170.0 ports: diff --git a/packages/backend/.env.shared b/packages/backend/.env.shared index f15fd1f58..ff3c291c4 100644 --- a/packages/backend/.env.shared +++ b/packages/backend/.env.shared @@ -15,6 +15,7 @@ TASKS_LOCAL_URL=http://workers:3005 TASKS_BASE_HANDLER=common.tasks.TaskLocalInvoke DB_CONNECTION={"dbname":"backend","username":"backend","password":"backend","host":"db","port":5432} +REDIS_CONNECTION=redis://redis:6379 AWS_ENDPOINT_URL=http://localstack:4566 WORKERS_EVENT_BUS_NAME=local-workers diff --git a/packages/backend/.test.env b/packages/backend/.test.env index 6d4cb09f7..c150bd4d7 100644 --- a/packages/backend/.test.env +++ b/packages/backend/.test.env @@ -11,6 +11,7 @@ DJANGO_DEFAULT_FILE_STORAGE=common.tests.storages.MockS3Boto3Storage HASHID_FIELD_SALT=9q#3t$5gs9ob682b@(6^fdv2kg*0ztr(3doa((w&kyq!d8rbt^y DB_CONNECTION='{"dbname":"backend","username":"backend","password":"backend","host":"db","port":5432}' +REDIS_CONNECTION=redis://redis:6379 WORKERS_EVENT_BUS_NAME=local-workers diff --git a/packages/backend/Dockerfile b/packages/backend/Dockerfile index 4cddb5c0c..58ae536ef 100644 --- a/packages/backend/Dockerfile +++ b/packages/backend/Dockerfile @@ -41,6 +41,7 @@ ENV HASHID_FIELD_SALT='' \ DJANGO_PARENT_HOST='' \ DJANGO_SECRET_KEY='build' \ DB_CONNECTION='{"dbname":"build","username":"build","password":"build","host":"db","port":5432}' \ + REDIS_CONNECTION=redis://redis:6379 \ WORKERS_EVENT_BUS_NAME='' \ PYTHONPATH=/pkgs/__pypackages__/3.11/lib diff --git a/packages/backend/apps/demo/tests/test_schema.py b/packages/backend/apps/demo/tests/test_schema.py index c7d03057c..b4e19dd25 100644 --- a/packages/backend/apps/demo/tests/test_schema.py +++ b/packages/backend/apps/demo/tests/test_schema.py @@ -167,38 +167,6 @@ def test_create_new_item_sends_notification(self, graphene_client, user_factory, } assert notification.issuer == user - def test_create_new_item_sends_notification_through_websockets( - self, mocker, graphene_client, user_factory, graph_ql_subscription_factory, input_data - ): - post_to_connection = mocker.patch("apps.websockets.apigateway.post_to_connection") - user = user_factory() - admin = user_factory(admin=True) - graph_ql_subscription_factory( - connection__connection_id="conn-id", - connection__user=admin, - operation_name="notificationsListSubscription", - relay_id="1", - query=self.NOTIFICATIONS_SUBSCRIPTION, - ) - - graphene_client.force_authenticate(user) - graphene_client.mutate(self.CREATE_MUTATION, variable_values={"input": input_data}) - - assert Notification.objects.count() == 1 - notification = Notification.objects.first() - notification_global_id = to_global_id("NotificationType", str(notification.id)) - post_to_connection.assert_called_once_with( - { - "id": "1", - "type": "next", - "payload": { - "data": {"notificationCreated": {"edges": [{"node": {"id": notification_global_id}}]}}, - "errors": None, - }, - }, - "conn-id", - ) - class TestUpdateCrudDemoItemMutation: UPDATE_MUTATION = """ @@ -296,43 +264,6 @@ def test_update_existing_item_sends_notification_to_admins_skipping_creator_if_h assert Notification.objects.filter(user=admins[0], type=constants.Notification.CRUD_ITEM_UPDATED.value).exists() assert Notification.objects.filter(user=admins[1], type=constants.Notification.CRUD_ITEM_UPDATED.value).exists() - def test_update_existing_item_sends_notification_through_websocket_to_admin_with_open_subscription( - self, mocker, graphene_client, crud_demo_item, user_factory, graph_ql_subscription_factory, input_data_factory - ): - post_to_connection = mocker.patch("apps.websockets.apigateway.post_to_connection") - user = user_factory() - crud_demo_item.user = user - crud_demo_item.save() - admins = user_factory.create_batch(2, admin=True) - input_data = input_data_factory(crud_demo_item) - graph_ql_subscription_factory( - connection__connection_id="conn-id", - connection__user=admins[0], - operation_name="notificationsListSubscription", - relay_id="1", - query=self.NOTIFICATIONS_SUBSCRIPTION, - ) - - graphene_client.force_authenticate(user) - graphene_client.mutate( - self.UPDATE_MUTATION, - variable_values={"input": input_data}, - ) - - notification = Notification.objects.get(user=admins[0], type=constants.Notification.CRUD_ITEM_UPDATED.value) - notification_global_id = to_global_id("NotificationType", str(notification.id)) - post_to_connection.assert_called_once_with( - { - "id": "1", - "type": "next", - "payload": { - "data": {"notificationCreated": {"edges": [{"node": {"id": notification_global_id}}]}}, - "errors": None, - }, - }, - "conn-id", - ) - class TestDeleteCrudDemoItemMutation: DELETE_MUTATION = """ diff --git a/packages/backend/apps/notifications/schema.py b/packages/backend/apps/notifications/schema.py index 2ba5705ba..672372e6d 100644 --- a/packages/backend/apps/notifications/schema.py +++ b/packages/backend/apps/notifications/schema.py @@ -1,15 +1,17 @@ +import channels_graphql_ws import graphene +from apps.users.models import User +from apps.users.services.users import get_user_avatar_url +from channels.db import database_sync_to_async +from common.acl.policies import IsAuthenticatedFullAccess +from common.graphql import mutations +from common.graphql.acl import permission_classes from graphene import relay from graphene.types.generic import GenericScalar from graphene_django import DjangoObjectType - -from common.graphql import mutations from . import models from . import serializers from . import services -from apps.users.models import User - -from apps.users.services.users import get_user_avatar_url, get_user_from_resolver class HasUnreadNotificationsMixin: @@ -31,11 +33,11 @@ class Meta: @staticmethod def resolve_first_name(parent, info): - return get_user_from_resolver(info).profile.first_name + return parent.profile.first_name @staticmethod def resolve_last_name(parent, info): - return get_user_from_resolver(info).profile.last_name + return parent.profile.last_name @staticmethod def resolve_avatar(parent, info): @@ -102,9 +104,29 @@ def resolve_has_unread_notifications(root, info): return models.Notification.objects.filter(user=info.context.user, read_at=None).exists() -class Subscription(graphene.ObjectType): - notification_created = graphene.relay.ConnectionField(NotificationConnection) +class NotificationCreatedSubscription(channels_graphql_ws.Subscription): + """Simple GraphQL subscription.""" + + # Leave only latest 64 messages in the server queue. + notification_queue_limit = 64 + + notification = graphene.Field(NotificationType) + + @staticmethod + def subscribe(root, info): + return [str(info.context.channels_scope['user'].id)] + + @staticmethod + @database_sync_to_async + def get_response(id: str): + notification = models.Notification.objects.prefetch_related('issuer', 'issuer__profile').get(id=id) + return NotificationCreatedSubscription(notification) @staticmethod - def resolve_notification_created(root, info): - return root + async def publish(payload, info): + return await NotificationCreatedSubscription.get_response(id=payload['id']) + + +@permission_classes(IsAuthenticatedFullAccess) +class Subscription(graphene.ObjectType): + notification_created = NotificationCreatedSubscription.Field() diff --git a/packages/backend/apps/notifications/signals.py b/packages/backend/apps/notifications/signals.py index fbee7baba..1cb62ca63 100644 --- a/packages/backend/apps/notifications/signals.py +++ b/packages/backend/apps/notifications/signals.py @@ -1,13 +1,10 @@ from django.db.models.signals import post_save from django.dispatch import receiver -from apps.websockets import utils -from . import models, constants +from . import models, schema @receiver(post_save, sender=models.Notification) def notify_about_entry(sender, instance: models.Notification, created, update_fields, **kwargs): if created: - utils.send_subscriptions_messages( - instance.user, constants.Subscription.NOTIFICATIONS_LIST_SUBSCRIPTION.value, root_value=[instance] - ) + schema.NotificationCreatedSubscription.broadcast(payload={'id': str(instance.id)}, group=str(instance.user.id)) diff --git a/packages/backend/apps/users/authentication.py b/packages/backend/apps/users/authentication.py index 748cf6b55..4a6b693a6 100644 --- a/packages/backend/apps/users/authentication.py +++ b/packages/backend/apps/users/authentication.py @@ -1,4 +1,6 @@ +from channels.db import database_sync_to_async from django.conf import settings +from django.http import parse_cookie from rest_framework import HTTP_HEADER_ENCODING from rest_framework_simplejwt import authentication @@ -19,3 +21,48 @@ def get_header(self, request): def get_raw_token(self, header): return header + + +class JSONWebTokenChannelsAuthentication(authentication.JWTAuthentication): + def get_header(self, scope): + for name, value in scope.get("headers", []): + if name == b"cookie": + cookies = parse_cookie(value.decode("latin1")) + break + else: + # No cookie header found - add an empty default. + cookies = {} + + """ + Extracts the header containing the JSON web token from the given + request. + """ + header = cookies.get(settings.ACCESS_TOKEN_COOKIE) + + if isinstance(header, str): + # Work around django test client oddness + header = header.encode(HTTP_HEADER_ENCODING) + + return header + + def get_raw_token(self, header): + return header + + +class JSONWebTokenCookieMiddleware: + def __init__(self, app): + self.app = app + + @database_sync_to_async + def authenticate(self, scope): + auth_backend = JSONWebTokenChannelsAuthentication() + return auth_backend.authenticate(scope) + + async def __call__(self, scope, receive, send): + scope = dict(scope) + result = await self.authenticate(scope) + if result is not None: + user, _ = result + scope["user"] = user + + return await self.app(scope, receive, send) diff --git a/packages/backend/apps/websockets/admin.py b/packages/backend/apps/websockets/admin.py deleted file mode 100644 index dc62b18a6..000000000 --- a/packages/backend/apps/websockets/admin.py +++ /dev/null @@ -1,13 +0,0 @@ -from django.contrib import admin - -from . import models - - -@admin.register(models.WebSocketConnection) -class WebSocketConnectionAdmin(admin.ModelAdmin): - pass - - -@admin.register(models.GraphQLSubscription) -class GraphQLSubscriptionAdmin(admin.ModelAdmin): - pass diff --git a/packages/backend/apps/websockets/apigateway.py b/packages/backend/apps/websockets/apigateway.py deleted file mode 100644 index dc9ad0c57..000000000 --- a/packages/backend/apps/websockets/apigateway.py +++ /dev/null @@ -1,21 +0,0 @@ -import json - -import boto3 -from django.conf import settings - -from .models import WebSocketConnection -from .local_client import LocalWebsocketClient - - -def get_client(): - if settings.IS_LOCAL_DEBUG: - return LocalWebsocketClient() - return boto3.client('apigatewaymanagementapi', endpoint_url=settings.WEB_SOCKET_API_ENDPOINT_URL) - - -def post_to_connection(data, connection_id): - client = get_client() - try: - client.post_to_connection(Data=json.dumps(data).encode(), ConnectionId=connection_id) - except client.exceptions.GoneException: - WebSocketConnection.objects.filter(connection_id=connection_id).delete() diff --git a/packages/backend/apps/websockets/consumers.py b/packages/backend/apps/websockets/consumers.py new file mode 100644 index 000000000..1dfb088c1 --- /dev/null +++ b/packages/backend/apps/websockets/consumers.py @@ -0,0 +1,9 @@ +import channels_graphql_ws + +from config.schema import schema as graphql_schema + + +class DefaultGraphqlWsConsumer(channels_graphql_ws.GraphqlWsConsumer): + """Channels WebSocket consumer which provides GraphQL API.""" + + schema = graphql_schema diff --git a/packages/backend/apps/websockets/graphql.py b/packages/backend/apps/websockets/graphql.py deleted file mode 100644 index 56a7d52e2..000000000 --- a/packages/backend/apps/websockets/graphql.py +++ /dev/null @@ -1,18 +0,0 @@ -from config.schema import subscriptions_schema - - -class UserContext: - def __init__(self, user): - self.user = user - - -def execute_graphql_subscription_query(query, user, **kwargs): - return subscriptions_schema.execute( - query.replace("subscription", "query"), - context_value=UserContext(user), - **kwargs, - ) - - -def prepare_relay_data_message(relay_subscription_id, data, errors): - return {"type": "next", "id": relay_subscription_id, "payload": {"data": data, "errors": errors}} diff --git a/packages/backend/apps/websockets/local_client.py b/packages/backend/apps/websockets/local_client.py deleted file mode 100644 index 7ca0eeda2..000000000 --- a/packages/backend/apps/websockets/local_client.py +++ /dev/null @@ -1,11 +0,0 @@ -import requests - - -class LocalWebsocketClient: - def post_to_connection(self, Data=None, ConnectionId=None): - requests.post( - f'http://localwsserver:8080/{ConnectionId}', - data=Data, - headers={'Content-type': 'application/json'}, - timeout=5, - ) diff --git a/packages/backend/apps/websockets/migrations/0003_remove_websocketconnection_user_and_more.py b/packages/backend/apps/websockets/migrations/0003_remove_websocketconnection_user_and_more.py new file mode 100644 index 000000000..9be2c76b1 --- /dev/null +++ b/packages/backend/apps/websockets/migrations/0003_remove_websocketconnection_user_and_more.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2 on 2024-01-29 13:42 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ('websockets', '0002_alter_graphqlsubscription_relay_id'), + ] + + operations = [ + migrations.RemoveField( + model_name='websocketconnection', + name='user', + ), + migrations.DeleteModel( + name='GraphQLSubscription', + ), + migrations.DeleteModel( + name='WebSocketConnection', + ), + ] diff --git a/packages/backend/apps/websockets/models.py b/packages/backend/apps/websockets/models.py deleted file mode 100644 index cfc30a48b..000000000 --- a/packages/backend/apps/websockets/models.py +++ /dev/null @@ -1,21 +0,0 @@ -from django.conf import settings -from django.db import models - - -class WebSocketConnection(models.Model): - user: settings.AUTH_USER_MODEL = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) - connection_id: str = models.CharField(max_length=32) - - def __str__(self) -> str: - return self.connection_id - - -class GraphQLSubscription(models.Model): - connection: WebSocketConnection = models.ForeignKey(WebSocketConnection, on_delete=models.CASCADE) - relay_id: str = models.CharField(max_length=36) - operation_name: str = models.CharField(max_length=32) - query: str = models.TextField() - variables: dict = models.JSONField(default=dict, blank=True) - - def __str__(self) -> str: - return self.relay_id diff --git a/packages/backend/apps/websockets/serializers.py b/packages/backend/apps/websockets/serializers.py deleted file mode 100644 index 8b7f1acb1..000000000 --- a/packages/backend/apps/websockets/serializers.py +++ /dev/null @@ -1,66 +0,0 @@ -import uuid - -from rest_framework import serializers -from hashid_field import rest -from django.contrib import auth as dj_auth - -from . import models, apigateway - - -class DebugConnectionCreateSerializer(serializers.Serializer): - user_pk = rest.HashidSerializerCharField(source_field="users.User.id", source="user.id", write_only=True) - connection_id = serializers.CharField(max_length=32, write_only=True) - - def validate(self, attrs): - user = None - try: - user = dj_auth.get_user_model().objects.get(pk=attrs.pop("user")["id"]) - except dj_auth.get_user_model().DoesNotExist: - pass - - return {**attrs, 'user': user} - - def create(self, validated_data): - user = validated_data.pop('user') - - if user: - ws_connection = models.WebSocketConnection(user=user, connection_id=validated_data["connection_id"]) - ws_connection.save() - - return {} - - -class DebugMessageSerializer(serializers.Serializer): - connection_id = serializers.CharField() - id = serializers.CharField(required=False) - type = serializers.CharField() - payload = serializers.DictField() - - def create(self, validated_data): - operation_type = validated_data.get("type") - payload = validated_data.get("payload") - subscription_id = validated_data.get("id") - connection_id = validated_data.get("connection_id") - - if operation_type == "connection_init": - apigateway.post_to_connection( - {"id": str(uuid.uuid4()), "type": "connection_ack", "payload": {"con_id": connection_id}}, - connection_id, - ) - elif operation_type == "subscribe" or operation_type == "start": - connection = models.WebSocketConnection.objects.filter(connection_id=connection_id).first() - if connection: - subscription = models.GraphQLSubscription( - connection=connection, - relay_id=subscription_id, - operation_name=payload.get("operationName"), - query=payload.get("query"), - variables=payload.get("variables"), - ) - subscription.save() - elif operation_type == "complete" or operation_type == "stop": - models.GraphQLSubscription.filter( - connection__connection_id=connection_id, relay_id=subscription_id - ).delete() - - return connection_id diff --git a/packages/backend/apps/websockets/tests/factories.py b/packages/backend/apps/websockets/tests/factories.py deleted file mode 100644 index 491d93608..000000000 --- a/packages/backend/apps/websockets/tests/factories.py +++ /dev/null @@ -1,16 +0,0 @@ -import factory - -from .. import models - - -class WebSocketConnectionFactory(factory.django.DjangoModelFactory): - class Meta: - model = models.WebSocketConnection - - -class GraphQlSubscriptionFactory(factory.django.DjangoModelFactory): - connection = factory.SubFactory(WebSocketConnectionFactory) - variables = {} - - class Meta: - model = models.GraphQLSubscription diff --git a/packages/backend/apps/websockets/tests/fixtures.py b/packages/backend/apps/websockets/tests/fixtures.py deleted file mode 100644 index 5a285c642..000000000 --- a/packages/backend/apps/websockets/tests/fixtures.py +++ /dev/null @@ -1,13 +0,0 @@ -import pytest - -import pytest_factoryboy - -from . import factories - -pytest_factoryboy.register(factories.WebSocketConnectionFactory) -pytest_factoryboy.register(factories.GraphQlSubscriptionFactory) - - -@pytest.fixture -def post_to_connection(mocker): - return mocker.patch("apps.websockets.apigateway.post_to_connection") diff --git a/packages/backend/apps/websockets/tests/test_utils.py b/packages/backend/apps/websockets/tests/test_utils.py deleted file mode 100644 index d9aa295a2..000000000 --- a/packages/backend/apps/websockets/tests/test_utils.py +++ /dev/null @@ -1,45 +0,0 @@ -from unittest import mock - -from .. import utils -import pytest - -pytestmark = pytest.mark.django_db - - -class TestSendSubscriptionsMessages: - def test_with_no_subscriptions(self, post_to_connection, user): - utils.send_subscriptions_messages(user, "someOperation") - post_to_connection.assert_not_called() - - def test_with_existing_subscriptions_and_multiple_users( - self, post_to_connection, user_factory, graph_ql_subscription_factory - ): - user = user_factory() - graph_ql_subscription_factory( - connection__connection_id="conn-id", connection__user=user, operation_name="someOperation" - ) - graph_ql_subscription_factory( - connection__connection_id="other-conn-id", connection__user=user_factory(), operation_name="someOperation" - ) - - utils.send_subscriptions_messages(user, "someOperation") - - post_to_connection.assert_called_once_with( - {"id": "", "type": "next", "payload": {"data": None, "errors": mock.ANY}}, "conn-id" - ) - - def test_with_existing_subscriptions_and_multiple_subscriptions( - self, post_to_connection, user, graph_ql_subscription_factory - ): - graph_ql_subscription_factory( - connection__connection_id="conn-id", connection__user=user, operation_name="someOperation" - ) - graph_ql_subscription_factory( - connection__connection_id="conn-id", connection__user=user, operation_name="otherOperation" - ) - - utils.send_subscriptions_messages(user, "someOperation") - - post_to_connection.assert_called_once_with( - {"id": "", "type": "next", "payload": {"data": None, "errors": mock.ANY}}, "conn-id" - ) diff --git a/packages/backend/apps/websockets/urls_debug.py b/packages/backend/apps/websockets/urls_debug.py deleted file mode 100644 index 7208e7685..000000000 --- a/packages/backend/apps/websockets/urls_debug.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.urls import path - -from . import views - -urlpatterns = [ - path("connect/", views.DebugConnectionCreateView.as_view(), name="websocket_debug_connect"), - path( - "disconnect//", views.DebugDisconnectionCreateView.as_view(), name="websocket_debug_disconnect" - ), - path("message//", views.DebugMessageView.as_view(), name="websocket_debug_message"), -] diff --git a/packages/backend/apps/websockets/utils.py b/packages/backend/apps/websockets/utils.py deleted file mode 100644 index cb1358bac..000000000 --- a/packages/backend/apps/websockets/utils.py +++ /dev/null @@ -1,15 +0,0 @@ -from . import models, apigateway, graphql - - -def get_subscriptions(user, operation_name): - return models.GraphQLSubscription.objects.filter( - connection__user=user, operation_name=operation_name - ).select_related("connection") - - -def send_subscriptions_messages(user, operation_name, **kwargs): - subscriptions = get_subscriptions(user, operation_name) - for subscription in subscriptions: - result = graphql.execute_graphql_subscription_query(subscription.query, user, **kwargs) - data = graphql.prepare_relay_data_message(subscription.relay_id, result.data, result.errors) - apigateway.post_to_connection(data, subscription.connection.connection_id) diff --git a/packages/backend/apps/websockets/views.py b/packages/backend/apps/websockets/views.py deleted file mode 100644 index 7b4de097e..000000000 --- a/packages/backend/apps/websockets/views.py +++ /dev/null @@ -1,37 +0,0 @@ -from rest_framework import generics, status -from rest_framework.response import Response - -from common.acl import policies -from . import serializers, models - - -class DebugConnectionCreateView(generics.CreateAPIView): - permission_classes = (policies.IsAnonymousFullAccess,) - serializer_class = serializers.DebugConnectionCreateSerializer - - def create(self, request, *args, **kwargs): - serializer = self.get_serializer(data=request.data) - serializer.is_valid(raise_exception=True) - self.perform_create(serializer) - return Response(serializer.data, status=status.HTTP_201_CREATED) - - -class DebugDisconnectionCreateView(generics.DestroyAPIView): - permission_classes = (policies.IsAnonymousFullAccess,) - queryset = models.WebSocketConnection.objects.all() - lookup_field = 'connection_id' - - def destroy(self, request, *args, **kwargs): - instance = self.get_object() - self.perform_destroy(instance) - return Response(status=status.HTTP_204_NO_CONTENT) - - -class DebugMessageView(generics.GenericAPIView): - permission_classes = (policies.IsAnonymousFullAccess,) - serializer_class = serializers.DebugMessageSerializer - - def post(self, request, connection_id, *args, **kwargs): - serializer = self.get_serializer(data={"connection_id": connection_id, **request.data}) - serializer.is_valid(raise_exception=True) - return Response(serializer.save(), status=status.HTTP_200_OK, headers={"Sec-WebSocket-Protocol": "graphql-ws"}) diff --git a/packages/backend/common/graphql/acl/decorators.py b/packages/backend/common/graphql/acl/decorators.py index e221e1de8..d4f195f45 100644 --- a/packages/backend/common/graphql/acl/decorators.py +++ b/packages/backend/common/graphql/acl/decorators.py @@ -1,6 +1,7 @@ from types import FunctionType from typing import Iterable, Type, Union, Callable +import channels_graphql_ws import graphene from graphene.types import Field from rest_framework.permissions import BasePermission @@ -52,6 +53,9 @@ def permission_checker(obj: types.Resolver): if not perms: return obj + if isinstance(obj, channels_graphql_ws.Subscription): + raise Exception('permission_checker for channels_graphql_ws.Subscription type is not supported') + if isinstance(obj, FunctionType): return wrappers.wraps_resolver_function(fn=obj, perms=perms) elif isinstance(obj, Field): diff --git a/packages/backend/common/graphql/acl/wrappers.py b/packages/backend/common/graphql/acl/wrappers.py index a9aafbce1..1dabf68a0 100644 --- a/packages/backend/common/graphql/acl/wrappers.py +++ b/packages/backend/common/graphql/acl/wrappers.py @@ -5,20 +5,19 @@ import graphene from graphene.relay.node import NodeField from graphene.types import Field -from rest_framework.request import Request from rest_framework.exceptions import PermissionDenied - +from rest_framework.request import Request from . import types - PERMISSION_DENIED_MESSAGE = "permission_denied" __wrapped_fns = threading.local() -__wrapped_fns.value = set() __wrapped_field_names = threading.local() -__wrapped_field_names.value = set() -def check_permissions(perms: types.PermissionsClasses, request: Request, root): +def check_permissions(perms: types.PermissionsClasses, request: Request | dict, root): + if hasattr(request, "channels_scope"): + return + for permission_class in perms: permission = permission_class() if not permission.has_permission(request=request, view=root): @@ -26,6 +25,9 @@ def check_permissions(perms: types.PermissionsClasses, request: Request, root): def wraps_resolver_function(fn: Callable, perms: types.PermissionsClasses, node_resolver: bool = False) -> Callable: + if not hasattr(__wrapped_fns, 'value'): + __wrapped_fns.value = set() + # Avoid wrapping function twice if fn in __wrapped_fns.value: return fn @@ -60,6 +62,9 @@ def wraps_field(field: Field, perms: types.PermissionsClasses, parent_resolver=N def wraps_object_type(obj: Type[graphene.ObjectType], perms: types.PermissionsClasses) -> Type[graphene.ObjectType]: + if not hasattr(__wrapped_field_names, 'value'): + __wrapped_field_names.value = set() + for field_name, field in obj._meta.fields.items(): parent_resolver = getattr(obj, f"resolve_{field_name}", None) # for overwriting mutation's fields diff --git a/packages/backend/config/asgi.py b/packages/backend/config/asgi.py index 7f81489c6..451771767 100644 --- a/packages/backend/config/asgi.py +++ b/packages/backend/config/asgi.py @@ -9,8 +9,26 @@ import os +from channels.routing import ProtocolTypeRouter, URLRouter from django.core.asgi import get_asgi_application +from django.urls import path os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') -application = get_asgi_application() +django_asgi_app = get_asgi_application() + +from apps.users.authentication import JSONWebTokenCookieMiddleware # noqa +from apps.websockets.consumers import DefaultGraphqlWsConsumer # noqa + +application = ProtocolTypeRouter( + { + "http": django_asgi_app, + "websocket": JSONWebTokenCookieMiddleware( + URLRouter( + [ + path("api/graphql/", DefaultGraphqlWsConsumer.as_asgi()), + ] + ) + ), + } +) diff --git a/packages/backend/gunicorn.py b/packages/backend/config/gunicorn.py similarity index 93% rename from packages/backend/gunicorn.py rename to packages/backend/config/gunicorn.py index dfe44404c..a8f394982 100644 --- a/packages/backend/gunicorn.py +++ b/packages/backend/config/gunicorn.py @@ -23,7 +23,7 @@ def max_workers(): accesslog = "-" errorlog = "-" workers = max_workers() -worker_class = "gevent" +worker_class = "uvicorn.workers.UvicornWorker" class HealthCheckFilter(logging.Filter): diff --git a/packages/backend/config/settings.py b/packages/backend/config/settings.py index fc09a75dc..6a6444071 100644 --- a/packages/backend/config/settings.py +++ b/packages/backend/config/settings.py @@ -14,6 +14,8 @@ DJANGO_DEBUG=(bool, False) ) +ASGI_APPLICATION = "config.asgi.application" + ENVIRONMENT_NAME = env("ENVIRONMENT_NAME", default="") SENTRY_DSN = env("SENTRY_DSN", default=None) @@ -50,6 +52,8 @@ "social_django", "whitenoise", "graphene_django", + 'channels', + # 'channels_postgres', "aws_xray_sdk.ext.django", ] @@ -63,7 +67,14 @@ "apps.integrations", ] -INSTALLED_APPS = DJANGO_CORE_APPS + THIRD_PARTY_APPS + LOCAL_APPS +INSTALLED_APPS = ( + [ + "daphne", + ] + + DJANGO_CORE_APPS + + THIRD_PARTY_APPS + + LOCAL_APPS +) SILENCED_SYSTEM_CHECKS = [] # default django value @@ -153,6 +164,33 @@ "PASSWORD": DB_CONNECTION["password"], "HOST": DB_PROXY_ENDPOINT or DB_CONNECTION["host"], "PORT": DB_CONNECTION["port"], + }, + "channels_postgres": { + "ENGINE": "django.db.backends.postgresql", + "NAME": DB_CONNECTION["dbname"], + "USER": DB_CONNECTION["username"], + "PASSWORD": DB_CONNECTION["password"], + "HOST": DB_PROXY_ENDPOINT or DB_CONNECTION["host"], + "PORT": DB_CONNECTION["port"], + }, +} + +REDIS_CONNECTION = env("REDIS_CONNECTION") + +CHANNEL_LAYERS = { + "default": { + "BACKEND": "channels_redis.core.RedisChannelLayer", + "CONFIG": { + "hosts": [{"address": REDIS_CONNECTION}], + }, + }, +} + +CACHES = { + "default": { + "BACKEND": "django_redis.cache.RedisCache", + "LOCATION": REDIS_CONNECTION, + "OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient"}, } } @@ -175,7 +213,6 @@ USE_TZ = True - # Storages # https://docs.djangoproject.com/en/4.2/ref/settings/#std-setting-STORAGES STORAGES = { @@ -187,7 +224,6 @@ }, } - # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ @@ -271,7 +307,6 @@ TASKS_BASE_HANDLER = env("TASKS_BASE_HANDLER", default="common.tasks.Task") TASKS_LOCAL_URL = env("TASKS_LOCAL_URL", default=None) - STRIPE_LIVE_SECRET_KEY = env("STRIPE_LIVE_SECRET_KEY", default="sk_") STRIPE_TEST_SECRET_KEY = env("STRIPE_TEST_SECRET_KEY", default="sk_test_") STRIPE_LIVE_MODE = env.bool("STRIPE_LIVE_MODE", default=False) @@ -322,7 +357,6 @@ OTP_AUTH_TOKEN_LIFETIME_MINUTES = datetime.timedelta(minutes=env.int('OTP_AUTH_TOKEN_LIFETIME_MINUTES', default=5)) OTP_VALIDATE_PATH = "/auth/validate-otp" - OPENAI_API_KEY = env("OPENAI_API_KEY", default="") UPLOADED_DOCUMENT_SIZE_LIMIT = env.int("UPLOADED_DOCUMENT_SIZE_LIMIT", default=10 * 1024 * 1024) diff --git a/packages/backend/config/urls_api.py b/packages/backend/config/urls_api.py index 87ce4ac55..c62422cf1 100644 --- a/packages/backend/config/urls_api.py +++ b/packages/backend/config/urls_api.py @@ -41,15 +41,3 @@ def get_schema(self, request=None, public=False): ), ), ] - -if settings.IS_LOCAL_DEBUG: - urlpatterns += [ - path( - "debug/", - include( - [ - path("ws/", include("apps.websockets.urls_debug")), - ] - ), - ) - ] diff --git a/packages/backend/config/wsgi.py b/packages/backend/config/wsgi.py deleted file mode 100644 index 891c13396..000000000 --- a/packages/backend/config/wsgi.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -WSGI config for project. - -It exposes the WSGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/ -""" - -import os - -from django.core.wsgi import get_wsgi_application - -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings") - -application = get_wsgi_application() diff --git a/packages/backend/conftest.py b/packages/backend/conftest.py index 1fdf75a57..0b57acebf 100644 --- a/packages/backend/conftest.py +++ b/packages/backend/conftest.py @@ -20,7 +20,6 @@ 'apps.demo.tests.fixtures', 'apps.content.tests.fixtures', 'apps.notifications.tests.fixtures', - 'apps.websockets.tests.fixtures', 'apps.integrations.tests.fixtures', ] diff --git a/packages/backend/infra/stacks/api/stack.ts b/packages/backend/infra/stacks/api/stack.ts index 3c8bcae8c..09786a8aa 100644 --- a/packages/backend/infra/stacks/api/stack.ts +++ b/packages/backend/infra/stacks/api/stack.ts @@ -15,6 +15,7 @@ import { MainKmsKey, MainDatabase, MainECSCluster, + MainRedisCluster, EnvComponentsStack, FargateServiceResources, } from '@sb/infra-shared'; @@ -137,6 +138,15 @@ export class ApiStack extends Stack { props.envSettings, ), ), + REDIS_CONNECTION: Fn.join('', [ + 'redis://', + Fn.importValue( + MainRedisCluster.getMainRedisClusterAddressExportName( + props.envSettings, + ), + ), + ':6379', + ]), }, secrets: { DB_CONNECTION: ecs.Secret.fromSecretsManager( diff --git a/packages/backend/infra/stacks/migrations/stack.ts b/packages/backend/infra/stacks/migrations/stack.ts index 7cf8be7b0..da6a86f1a 100644 --- a/packages/backend/infra/stacks/migrations/stack.ts +++ b/packages/backend/infra/stacks/migrations/stack.ts @@ -6,14 +6,12 @@ import * as sm from 'aws-cdk-lib/aws-secretsmanager'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as logs from 'aws-cdk-lib/aws-logs'; -import { - EnvConstructProps, - EnvironmentSettings, -} from '@sb/infra-core'; +import { EnvConstructProps, EnvironmentSettings } from '@sb/infra-core'; import { FargateServiceResources, MainDatabase, MainKmsKey, + MainRedisCluster, } from '@sb/infra-shared'; export interface MigrationsStackProps extends StackProps, EnvConstructProps {} @@ -26,12 +24,12 @@ export class MigrationsStack extends Stack { const resources = new FargateServiceResources( this, 'MigrationsResources', - props + props, ); const containerName = 'migrations'; const dbSecretArn = Fn.importValue( - MainDatabase.getDatabaseSecretArnOutputExportName(envSettings) + MainDatabase.getDatabaseSecretArnOutputExportName(envSettings), ); const taskRole = this.createTaskRole(props); @@ -42,13 +40,13 @@ export class MigrationsStack extends Stack { taskRole, cpu: 256, memoryLimitMiB: 512, - } + }, ); const containerDef = migrationsTaskDefinition.addContainer(containerName, { image: ecs.ContainerImage.fromEcrRepository( resources.backendRepository, - envSettings.version + envSettings.version, ), logging: this.createAWSLogDriver(this.node.id, props.envSettings), environment: { @@ -56,13 +54,22 @@ export class MigrationsStack extends Stack { CHAMBER_KMS_KEY_ALIAS: MainKmsKey.getKeyAlias(envSettings), DB_PROXY_ENDPOINT: Fn.importValue( MainDatabase.getDatabaseProxyEndpointOutputExportName( - props.envSettings - ) + props.envSettings, + ), ), + REDIS_CONNECTION: Fn.join('', [ + 'redis://', + Fn.importValue( + MainRedisCluster.getMainRedisClusterAddressExportName( + props.envSettings, + ), + ), + ':6379', + ]), }, secrets: { DB_CONNECTION: ecs.Secret.fromSecretsManager( - sm.Secret.fromSecretCompleteArn(this, 'DbSecret', dbSecretArn) + sm.Secret.fromSecretCompleteArn(this, 'DbSecret', dbSecretArn), ), }, }); @@ -87,11 +94,14 @@ export class MigrationsStack extends Stack { }); } - protected createAWSLogDriver(prefix: string, envSettings: EnvironmentSettings): ecs.AwsLogDriver { - const logGroup = new logs.LogGroup(this, "TaskLogGroup", { + protected createAWSLogDriver( + prefix: string, + envSettings: EnvironmentSettings, + ): ecs.AwsLogDriver { + const logGroup = new logs.LogGroup(this, 'TaskLogGroup', { logGroupName: `${envSettings.projectEnvName}-migrations-log-group`, - retention: logs.RetentionDays.INFINITE - }) + retention: logs.RetentionDays.INFINITE, + }); return new ecs.AwsLogDriver({ streamPrefix: prefix, logGroup }); } @@ -108,17 +118,17 @@ export class MigrationsStack extends Stack { actions: ['kms:Get*', 'kms:Describe*', 'kms:List*', 'kms:Decrypt'], resources: [ Fn.importValue( - MainKmsKey.getMainKmsOutputExportName(props.envSettings) + MainKmsKey.getMainKmsOutputExportName(props.envSettings), ), ], - }) + }), ); taskRole.addToPolicy( new iam.PolicyStatement({ actions: ['ssm:DescribeParameters'], resources: ['*'], - }) + }), ); taskRole.addToPolicy( @@ -127,7 +137,7 @@ export class MigrationsStack extends Stack { resources: [ `arn:aws:ssm:${stack.region}:${stack.account}:parameter/${chamberServiceName}/*`, ], - }) + }), ); return taskRole; diff --git a/packages/backend/pdm.lock b/packages/backend/pdm.lock index 0acb9bb61..a900526d3 100644 --- a/packages/backend/pdm.lock +++ b/packages/backend/pdm.lock @@ -30,6 +30,16 @@ name = "aniso8601" version = "9.0.1" summary = "A library for parsing ISO 8601 strings." +[[package]] +name = "anyio" +version = "4.2.0" +requires_python = ">=3.8" +summary = "High level compatibility layer for multiple asynchronous event loop implementations" +dependencies = [ + "idna>=2.8", + "sniffio>=1.1", +] + [[package]] name = "asgiref" version = "3.6.0" @@ -54,6 +64,27 @@ version = "21.4.0" requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" summary = "Classes Without Boilerplate" +[[package]] +name = "autobahn" +version = "23.6.2" +requires_python = ">=3.9" +summary = "WebSocket client & server library, WAMP real-time framework" +dependencies = [ + "cryptography>=3.4.6", + "hyperlink>=21.0.0", + "setuptools", + "txaio>=21.2.1", +] + +[[package]] +name = "automat" +version = "22.10.0" +summary = "Self-service finite-state machines for the programmer on the go." +dependencies = [ + "attrs>=19.2.0", + "six", +] + [[package]] name = "aws-sam-translator" version = "1.47.0" @@ -143,6 +174,39 @@ dependencies = [ "sarif-om~=1.0.4", ] +[[package]] +name = "channels" +version = "4.0.0" +requires_python = ">=3.7" +summary = "Brings async, event-driven capabilities to Django 3.2 and up." +dependencies = [ + "Django>=3.2", + "asgiref<4,>=3.5.0", +] + +[[package]] +name = "channels-redis" +version = "4.2.0" +requires_python = ">=3.8" +summary = "Redis-backed ASGI channel layer implementation" +dependencies = [ + "asgiref<4,>=3.2.10", + "channels", + "msgpack~=1.0", + "redis>=4.6", +] + +[[package]] +name = "channels" +version = "4.0.0" +extras = ["daphne"] +requires_python = ">=3.7" +summary = "Brings async, event-driven capabilities to Django 3.2 and up." +dependencies = [ + "channels==4.0.0", + "daphne>=4.0.0", +] + [[package]] name = "charset-normalizer" version = "2.1.0" @@ -164,6 +228,12 @@ version = "0.4.5" requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" summary = "Cross-platform colored terminal text." +[[package]] +name = "constantly" +version = "23.10.4" +requires_python = ">=3.8" +summary = "Symbolic constants in Python" + [[package]] name = "coreapi" version = "2.3.3" @@ -212,11 +282,22 @@ dependencies = [ [[package]] name = "cryptography" -version = "37.0.4" -requires_python = ">=3.6" +version = "42.0.0" +requires_python = ">=3.7" summary = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." dependencies = [ - "cffi>=1.12", + "cffi>=1.12; platform_python_implementation != \"PyPy\"", +] + +[[package]] +name = "daphne" +version = "4.0.0" +requires_python = ">=3.7" +summary = "Django ASGI (HTTP/WebSocket) server" +dependencies = [ + "asgiref<4,>=3.5.2", + "autobahn>=22.4.2", + "twisted[tls]>=22.4", ] [[package]] @@ -280,6 +361,21 @@ dependencies = [ "tzdata; sys_platform == \"win32\"", ] +[[package]] +name = "django-channels-graphql-ws" +version = "1.0.0rc6" +requires_python = ">=3.8.0,<4.0.0" +summary = "Django Channels based WebSocket GraphQL server with Graphene-like subscriptions" +dependencies = [ + "Django<5,>=4", + "aiohttp<4,>=3", + "asgiref<4,>=3", + "channels<5,>=4", + "graphene<4,>=3", + "graphql-core==3.2.3", + "msgpack<2,>=1", +] + [[package]] name = "django-environ" version = "0.9.0" @@ -316,6 +412,16 @@ version = "4.0.0" requires_python = ">=3.7" summary = "Cache-based rate-limiting for Django." +[[package]] +name = "django-redis" +version = "5.4.0" +requires_python = ">=3.6" +summary = "Full featured redis cache backend for Django." +dependencies = [ + "Django>=3.2", + "redis!=4.0.0,!=4.0.1,>=3", +] + [[package]] name = "django-storages" version = "1.13.2" @@ -527,18 +633,44 @@ dependencies = [ "packaging", ] +[[package]] +name = "h11" +version = "0.14.0" +requires_python = ">=3.7" +summary = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" + [[package]] name = "hashids" version = "1.3.1" requires_python = ">=2.7" summary = "Implements the hashids algorithm in python. For more information, visit http://hashids.org/" +[[package]] +name = "httptools" +version = "0.6.1" +requires_python = ">=3.8.0" +summary = "A collection of framework independent HTTP protocol utils." + +[[package]] +name = "hyperlink" +version = "21.0.0" +requires_python = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +summary = "A featureful, immutable, and correct URL for Python." +dependencies = [ + "idna>=2.5", +] + [[package]] name = "idna" version = "3.3" requires_python = ">=3.5" summary = "Internationalized Domain Names in Applications (IDNA)" +[[package]] +name = "incremental" +version = "22.10.0" +summary = "\"A small library that versions your Python projects.\"" + [[package]] name = "inflection" version = "0.5.1" @@ -677,6 +809,12 @@ dependencies = [ "sshpubkeys>=3.1.0", ] +[[package]] +name = "msgpack" +version = "1.0.7" +requires_python = ">=3.8" +summary = "MessagePack serializer" + [[package]] name = "multidict" version = "6.0.4" @@ -824,6 +962,15 @@ name = "pyasn1" version = "0.4.8" summary = "ASN.1 types and codecs" +[[package]] +name = "pyasn1-modules" +version = "0.3.0" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +summary = "A collection of ASN.1-based protocols modules" +dependencies = [ + "pyasn1<0.6.0,>=0.4.6", +] + [[package]] name = "pycparser" version = "2.21" @@ -877,6 +1024,15 @@ version = "2.4.0" requires_python = ">=3.6" summary = "JSON Web Token implementation in Python" +[[package]] +name = "pyopenssl" +version = "24.0.0" +requires_python = ">=3.7" +summary = "Python wrapper module around the OpenSSL library" +dependencies = [ + "cryptography<43,>=41.0.5", +] + [[package]] name = "pyotp" version = "2.8.0" @@ -1034,6 +1190,15 @@ version = "6.0.1" requires_python = ">=3.6" summary = "YAML parser and emitter for Python" +[[package]] +name = "redis" +version = "5.0.1" +requires_python = ">=3.7" +summary = "Python client for Redis database and key-value store" +dependencies = [ + "async-timeout>=4.0.2; python_full_version <= \"3.11.2\"", +] + [[package]] name = "requests" version = "2.28.2" @@ -1115,6 +1280,18 @@ dependencies = [ "urllib3>=1.26.11; python_version >= \"3.6\"", ] +[[package]] +name = "service-identity" +version = "24.1.0" +requires_python = ">=3.8" +summary = "Service identity verification for pyOpenSSL & cryptography." +dependencies = [ + "attrs>=19.1.0", + "cryptography", + "pyasn1", + "pyasn1-modules", +] + [[package]] name = "setuptools" version = "63.2.0" @@ -1127,6 +1304,12 @@ version = "1.16.0" requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" summary = "Python 2 and 3 compatibility utilities" +[[package]] +name = "sniffio" +version = "1.3.0" +requires_python = ">=3.7" +summary = "Sniff out which async library your code is running under" + [[package]] name = "social-auth-app-django" version = "5.0.0" @@ -1207,6 +1390,46 @@ dependencies = [ "colorama; platform_system == \"Windows\"", ] +[[package]] +name = "twisted" +version = "23.10.0" +requires_python = ">=3.8.0" +summary = "An asynchronous networking framework written in Python" +dependencies = [ + "attrs>=21.3.0", + "automat>=0.8.0", + "constantly>=15.1", + "hyperlink>=17.1.1", + "incremental>=22.10.0", + "twisted-iocpsupport<2,>=1.0.2; platform_system == \"Windows\"", + "typing-extensions>=4.2.0", + "zope-interface>=5", +] + +[[package]] +name = "twisted-iocpsupport" +version = "1.0.4" +summary = "An extension for use in the twisted I/O Completion Ports reactor." + +[[package]] +name = "twisted" +version = "23.10.0" +extras = ["tls"] +requires_python = ">=3.8.0" +summary = "An asynchronous networking framework written in Python" +dependencies = [ + "idna>=2.4", + "pyopenssl>=21.0.0", + "service-identity>=18.1.0", + "twisted==23.10.0", +] + +[[package]] +name = "txaio" +version = "23.1.1" +requires_python = ">=3.7" +summary = "Compatibility API between asyncio/Twisted/Trollius" + [[package]] name = "typeapi" version = "2.1.1" @@ -1240,18 +1463,66 @@ version = "1.26.14" requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" summary = "HTTP library with thread-safe connection pooling, file post, and more." +[[package]] +name = "uvicorn" +version = "0.27.1" +requires_python = ">=3.8" +summary = "The lightning-fast ASGI server." +dependencies = [ + "click>=7.0", + "h11>=0.8", +] + +[[package]] +name = "uvicorn" +version = "0.27.1" +extras = ["standard"] +requires_python = ">=3.8" +summary = "The lightning-fast ASGI server." +dependencies = [ + "colorama>=0.4; sys_platform == \"win32\"", + "httptools>=0.5.0", + "python-dotenv>=0.13", + "pyyaml>=5.1", + "uvicorn==0.27.1", + "uvloop!=0.15.0,!=0.15.1,>=0.14.0; sys_platform != \"win32\" and (sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\")", + "watchfiles>=0.13", + "websockets>=10.4", +] + +[[package]] +name = "uvloop" +version = "0.19.0" +requires_python = ">=3.8.0" +summary = "Fast implementation of asyncio event loop on top of libuv" + [[package]] name = "watchdog" version = "2.3.1" requires_python = ">=3.6" summary = "Filesystem events monitoring" +[[package]] +name = "watchfiles" +version = "0.21.0" +requires_python = ">=3.8" +summary = "Simple, modern and high performance file watching and code reload in python." +dependencies = [ + "anyio>=3.0.0", +] + [[package]] name = "websocket-client" version = "1.3.3" requires_python = ">=3.7" summary = "WebSocket client for Python with low level API options" +[[package]] +name = "websockets" +version = "12.0" +requires_python = ">=3.8" +summary = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" + [[package]] name = "werkzeug" version = "2.1.2" @@ -1314,7 +1585,7 @@ dependencies = [ [metadata] lock_version = "4.2" groups = ["default", "dev"] -content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115c7e79f1" +content_hash = "sha256:62bc5a1ce73e65a64098e42203e5d43db325fd0582a2a758f2f89b6ceb456e10" [metadata.files] "aiohttp 3.8.4" = [ @@ -1414,6 +1685,10 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/cb/72/be3db445b03944bfbb2b02b82d00cb2a2bcf96275c4543f14bf60fa79e12/aniso8601-9.0.1.tar.gz", hash = "sha256:72e3117667eedf66951bb2d93f4296a56b94b078a8a95905a052611fb3f1b973"}, {url = "https://files.pythonhosted.org/packages/e3/04/e97c12dc034791d7b504860acfcdd2963fa21ae61eaca1c9d31245f812c3/aniso8601-9.0.1-py2.py3-none-any.whl", hash = "sha256:1d2b7ef82963909e93c4f24ce48d4de9e66009a21bf1c1e1c85bdd0812fe412f"}, ] +"anyio 4.2.0" = [ + {url = "https://files.pythonhosted.org/packages/2d/b8/7333d87d5f03247215d86a86362fd3e324111788c6cdd8d2e6196a6ba833/anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"}, + {url = "https://files.pythonhosted.org/packages/bf/cd/d6d9bb1dadf73e7af02d18225cbd2c93f8552e13130484f1c8dcfece292b/anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"}, +] "asgiref 3.6.0" = [ {url = "https://files.pythonhosted.org/packages/78/2d/797c0537426266d6c9377a2ed6a4ac61e50c2d5b1ab4da101a4b9bfe26e2/asgiref-3.6.0.tar.gz", hash = "sha256:9567dfe7bd8d3c8c892227827c41cce860b368104c3431da67a0c5a65a949506"}, {url = "https://files.pythonhosted.org/packages/8f/29/38d10a47b322a77b2d12c2b79c789f52956f733cb701d4d5157c76b5f238/asgiref-3.6.0-py3-none-any.whl", hash = "sha256:71e68008da809b957b7ee4b43dbccff33d1b23519fb8344e33f049897077afac"}, @@ -1430,6 +1705,13 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/be/be/7abce643bfdf8ca01c48afa2ddf8308c2308b0c3b239a44e57d020afa0ef/attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, {url = "https://files.pythonhosted.org/packages/d7/77/ebb15fc26d0f815839ecd897b919ed6d85c050feeb83e100e020df9153d2/attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, ] +"autobahn 23.6.2" = [ + {url = "https://files.pythonhosted.org/packages/92/ee/c3320c326919394ff597592549ff5d29d2f7bf12be9ddaa9017caff1a170/autobahn-23.6.2.tar.gz", hash = "sha256:ec9421c52a2103364d1ef0468036e6019ee84f71721e86b36fe19ad6966c1181"}, +] +"automat 22.10.0" = [ + {url = "https://files.pythonhosted.org/packages/29/90/64aabce6c1b820395452cc5472b8f11cd98320f40941795b8069aef4e0e0/Automat-22.10.0-py2.py3-none-any.whl", hash = "sha256:c3164f8742b9dc440f3682482d32aaff7bb53f71740dd018533f9de286b64180"}, + {url = "https://files.pythonhosted.org/packages/7a/7b/9c3d26d8a0416eefbc0428f168241b32657ca260fb7ef507596ff5c2f6c4/Automat-22.10.0.tar.gz", hash = "sha256:e56beb84edad19dcc11d30e8d9b895f75deeb5ef5e96b84a467066b3b84bb04e"}, +] "aws-sam-translator 1.47.0" = [ {url = "https://files.pythonhosted.org/packages/0c/98/c16af074d75feebdb909b0c6a028487d508e7b5001b68d228dcc4666e127/aws-sam-translator-1.47.0.tar.gz", hash = "sha256:d2fe471a126f58a28ef505d03ea2d37a2f282312ce592a3250f4d8c8efca6946"}, {url = "https://files.pythonhosted.org/packages/9d/5a/2d2390c6b7f6e3585040661a994dcfa1cf05899553c2d5ad299fff4fb191/aws_sam_translator-1.47.0-py3-none-any.whl", hash = "sha256:7bf8e8564cbbdcb1a3a71e6bd8551b4f8488014c5a4d67af5e92d0966c3b1ef8"}, @@ -1551,6 +1833,14 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/30/7d/561475781d6dd8a70d5a1998d0344dabf2d698027f0c058fc8c5238fd7f1/cfn-lint-0.61.3.tar.gz", hash = "sha256:3806e010d77901f5e935496df690c10e39676434a738fce1a1161cf9c7bd36a2"}, {url = "https://files.pythonhosted.org/packages/4b/99/8e41b8b2436fe03dead3fa77d1d7bf87e10388c033d8750ba1889ee69f83/cfn_lint-0.61.3-py3-none-any.whl", hash = "sha256:8e9522fad0c7c98b31ecbdd4724f8d8a5787457cc0f71e62ae0d11104d6e52ab"}, ] +"channels 4.0.0" = [ + {url = "https://files.pythonhosted.org/packages/8e/cb/6fedd9df5972b893a04c8e5d7748873d6480a813e74b0797945bee1f4282/channels-4.0.0.tar.gz", hash = "sha256:0ce53507a7da7b148eaa454526e0e05f7da5e5d1c23440e4886cf146981d8420"}, + {url = "https://files.pythonhosted.org/packages/f5/52/a233dc63996547f171c2013f2d0505dcfa7d0557e7cde8748a2bd70b5a31/channels-4.0.0-py3-none-any.whl", hash = "sha256:2253334ac76f67cba68c2072273f7e0e67dbdac77eeb7e318f511d2f9a53c5e4"}, +] +"channels-redis 4.2.0" = [ + {url = "https://files.pythonhosted.org/packages/11/df/7638755c3adc8463a872562082c66737d1b7d754c2040a2ddfe3c8800f67/channels_redis-4.2.0-py3-none-any.whl", hash = "sha256:2c5b944a39bd984b72aa8005a3ae11637bf29b5092adeb91c9aad4ab819a8ac4"}, + {url = "https://files.pythonhosted.org/packages/fd/c8/d8e4d369a4cbce5dc86e84a559993001d471327f1ef57c13ffc82bdc9efa/channels_redis-4.2.0.tar.gz", hash = "sha256:01c26c4d5d3a203f104bba9e5585c0305a70df390d21792386586068162027fd"}, +] "charset-normalizer 2.1.0" = [ {url = "https://files.pythonhosted.org/packages/93/1d/d9392056df6670ae2a29fcb04cfa5cee9f6fbde7311a1bb511d4115e9b7a/charset-normalizer-2.1.0.tar.gz", hash = "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"}, {url = "https://files.pythonhosted.org/packages/94/69/64b11e8c2fb21f08634468caef885112e682b0ebe2908e74d3616eb1c113/charset_normalizer-2.1.0-py3-none-any.whl", hash = "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5"}, @@ -1563,6 +1853,10 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/2b/65/24d033a9325ce42ccbfa3ca2d0866c7e89cc68e5b9d92ecaba9feef631df/colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, {url = "https://files.pythonhosted.org/packages/77/8b/7550e87b2d308a1b711725dfaddc19c695f8c5fa413c640b2be01662f4e6/colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, ] +"constantly 23.10.4" = [ + {url = "https://files.pythonhosted.org/packages/4d/6f/cb2a94494ff74aa9528a36c5b1422756330a75a8367bf20bd63171fc324d/constantly-23.10.4.tar.gz", hash = "sha256:aa92b70a33e2ac0bb33cd745eb61776594dc48764b06c35e0efd050b7f1c7cbd"}, + {url = "https://files.pythonhosted.org/packages/b8/40/c199d095151addf69efdb4b9ca3a4f20f70e20508d6222bffb9b76f58573/constantly-23.10.4-py3-none-any.whl", hash = "sha256:3fd9b4d1c3dc1ec9757f3c52aef7e53ad9323dbe39f51dfd4c43853b68dfa3f9"}, +] "coreapi 2.3.3" = [ {url = "https://files.pythonhosted.org/packages/ca/f2/5fc0d91a0c40b477b016c0f77d9d419ba25fc47cc11a96c825875ddce5a6/coreapi-2.3.3.tar.gz", hash = "sha256:46145fcc1f7017c076a2ef684969b641d18a2991051fddec9458ad3f78ffc1cb"}, {url = "https://files.pythonhosted.org/packages/fc/3a/9dedaad22962770edd334222f2b3c3e7ad5e1c8cab1d6a7992c30329e2e5/coreapi-2.3.3-py2.py3-none-any.whl", hash = "sha256:bf39d118d6d3e171f10df9ede5666f63ad80bba9a29a8ec17726a66cf52ee6f3"}, @@ -1628,29 +1922,43 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/21/d8/926bf0e57026a9c57c7ba4840a1702ce8a79b529454f224d2dc895e2b1f0/craftr_dsl-0.7.7-py3-none-any.whl", hash = "sha256:3968cb5df76fc349fc608dc564b571ba6177ffc8f19c0e325474536ea0f181de"}, {url = "https://files.pythonhosted.org/packages/80/5c/1dca19538d42494bd441ab839b3d56ef188aa538d2ce611d65405e9de26f/craftr-dsl-0.7.7.tar.gz", hash = "sha256:004d6042b5e8c7971ee26b21e49174e173708476a52b561b0900abfd467365a3"}, ] -"cryptography 37.0.4" = [ - {url = "https://files.pythonhosted.org/packages/1d/07/9c6779f9aac823c760465e59dd6a2ff3fffdd8c8174ef2fbe05f1b77650e/cryptography-37.0.4-cp36-abi3-win32.whl", hash = "sha256:b62439d7cd1222f3da897e9a9fe53bbf5c104fff4d60893ad1355d4c14a24157"}, - {url = "https://files.pythonhosted.org/packages/20/8b/66600f5851ec7893ace9b74445d7eaf3499571b347e339d18c76c876b0f9/cryptography-37.0.4-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2dcb0b3b63afb6df7fd94ec6fbddac81b5492513f7b0436210d390c14d46ee8"}, - {url = "https://files.pythonhosted.org/packages/2e/61/1aa189625666814dfaa1a10c338ba1b5a807e861d9f3b73307b492913e24/cryptography-37.0.4-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:f8c0a6e9e1dd3eb0414ba320f85da6b0dcbd543126e30fcc546e7372a7fbf3b9"}, - {url = "https://files.pythonhosted.org/packages/47/26/0c9eaff097ff4080c2fa6ff6a53074d772fee881d9f0a5d59ea33229512e/cryptography-37.0.4-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc95ed67b6741b2607298f9ea4932ff157e570ef456ef7ff0ef4884a134cc4b"}, - {url = "https://files.pythonhosted.org/packages/55/68/17d21988cec2dec825ce7fb965cc44d5f64e9f48f414084510f5836c5cb3/cryptography-37.0.4-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:3d41b965b3380f10e4611dbae366f6dc3cefc7c9ac4e8842a806b9672ae9add5"}, - {url = "https://files.pythonhosted.org/packages/6a/79/77dc09377aea15ed0238b3cdcac7375f33aa812dea9a26f1af46f7097b6e/cryptography-37.0.4-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:91ce48d35f4e3d3f1d83e29ef4a9267246e6a3be51864a5b7d2247d5086fa99a"}, - {url = "https://files.pythonhosted.org/packages/6b/c0/4cfdc2fa58f86ccb5dcd017c9aa2125a5132e9b52868ccc5d46d0542d29c/cryptography-37.0.4-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:190f82f3e87033821828f60787cfa42bff98404483577b591429ed99bed39d59"}, - {url = "https://files.pythonhosted.org/packages/78/21/59512b7c0d172f28f300284d0618a3581bd24d1c1428d73a6e8b51ac3e70/cryptography-37.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:75976c217f10d48a8b5a8de3d70c454c249e4b91851f6838a4e48b8f41eb71aa"}, - {url = "https://files.pythonhosted.org/packages/86/82/5e81dbf8a94c011e5240595149626d92e78a110f01311face1ab08431566/cryptography-37.0.4-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:b7f8dd0d4c1f21759695c05a5ec8536c12f31611541f8904083f3dc582604280"}, - {url = "https://files.pythonhosted.org/packages/89/d9/5fcd312d5cce0b4d7ee8b551a0ea99e4ea9db0fdbf6dd455a19042e3370b/cryptography-37.0.4.tar.gz", hash = "sha256:63f9c17c0e2474ccbebc9302ce2f07b55b3b3fcb211ded18a42d5764f5c10a82"}, - {url = "https://files.pythonhosted.org/packages/8d/f4/477730b78a6152dafca6f8c47d246979ed95e6d144f27a85bddb845fe894/cryptography-37.0.4-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:d204833f3c8a33bbe11eda63a54b1aad7aa7456ed769a982f21ec599ba5fa282"}, - {url = "https://files.pythonhosted.org/packages/92/bb/31fe12a6bc8d066621d79345c84a517c2bd6bf9ae18e1c53652a5c4e8790/cryptography-37.0.4-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:7099a8d55cd49b737ffc99c17de504f2257e3787e02abe6d1a6d136574873441"}, - {url = "https://files.pythonhosted.org/packages/a4/e4/fcabae3e4c903a0c63e0537c6427a710680f10113a61aaadf8fd74896e00/cryptography-37.0.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2be53f9f5505673eeda5f2736bea736c40f051a739bfae2f92d18aed1eb54596"}, - {url = "https://files.pythonhosted.org/packages/c4/4b/accdc610bca433f99403bdeafc024324052fde973589436e314b926944f1/cryptography-37.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4c590ec31550a724ef893c50f9a97a0c14e9c851c85621c5650d699a7b88f7ab"}, - {url = "https://files.pythonhosted.org/packages/c5/93/23f1cc4a39cee6ca0dc75550dc204e5af71e8bf3012d23feb1bd5b06edea/cryptography-37.0.4-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:a958c52505c8adf0d3822703078580d2c0456dd1d27fabfb6f76fe63d2971cd6"}, - {url = "https://files.pythonhosted.org/packages/ca/44/2384260ffa2fa974894ec5f70896b328cd55a19dc367cf5c7ef32d5b3ba8/cryptography-37.0.4-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f721d1885ecae9078c3f6bbe8a88bc0786b6e749bf32ccec1ef2b18929a05046"}, - {url = "https://files.pythonhosted.org/packages/d4/d7/fa8688ca6ba6dbe44a8ecab9b34cbba0a5ab42c5a3609371968ba3e7f44a/cryptography-37.0.4-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:30788e070800fec9bbcf9faa71ea6d8068f5136f60029759fd8c3efec3c9dcb3"}, - {url = "https://files.pythonhosted.org/packages/e5/4b/45759a0238628b48113ce899ef499d39433d3ac384a132796cd9fb4977a1/cryptography-37.0.4-cp36-abi3-win_amd64.whl", hash = "sha256:f7a6de3e98771e183645181b3627e2563dcde3ce94a9e42a3f427d2255190327"}, - {url = "https://files.pythonhosted.org/packages/e8/ae/8ea6a2010ef1b916e3d158e1dcea6236c5660e7db6425eb9e491f69093a6/cryptography-37.0.4-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:e007f052ed10cc316df59bc90fbb7ff7950d7e2919c9757fd42a2b8ecf8a5f67"}, - {url = "https://files.pythonhosted.org/packages/eb/f0/8bc2246a422eb5cd1fe7cfc2ed522e4e3e0fd6f1c828193c0860c7030ca6/cryptography-37.0.4-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:549153378611c0cca1042f20fd9c5030d37a72f634c9326e225c9f666d472884"}, - {url = "https://files.pythonhosted.org/packages/f1/a2/691402d66e95b8e85e2a96c670038ce2d9fc934e5a40152ac68d3c7fe486/cryptography-37.0.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bc997818309f56c0038a33b8da5c0bfbb3f1f067f315f9abd6fc07ad359398d"}, - {url = "https://files.pythonhosted.org/packages/fd/5a/f47456f062b0c5bd828198992fca1f78bcc7aeadd216d9ce6c3348188b92/cryptography-37.0.4-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80f49023dd13ba35f7c34072fa17f604d2f19bf0989f292cedf7ab5770b87a0b"}, +"cryptography 42.0.0" = [ + {url = "https://files.pythonhosted.org/packages/06/5a/a791677f3c01d6df63e965782f7e9aee503258cef1e15c0a3702ab7c70c3/cryptography-42.0.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ca20550bb590db16223eb9ccc5852335b48b8f597e2f6f0878bbfd9e7314eb17"}, + {url = "https://files.pythonhosted.org/packages/0b/54/521f8a7c29c4ddd9c5c9c64eb5c384e3460456b5e8758221acb7d43c0f4e/cryptography-42.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:14e4b909373bc5bf1095311fa0f7fcabf2d1a160ca13f1e9e467be1ac4cbdf94"}, + {url = "https://files.pythonhosted.org/packages/15/2e/ac05f504e15eaa73044d07c5ea2f68f8228103ac76e2e166cb0a32e9d7da/cryptography-42.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:a2a8d873667e4fd2f34aedab02ba500b824692c6542e017075a2efc38f60a4c0"}, + {url = "https://files.pythonhosted.org/packages/18/d3/987d30dfba4692bf59885dc2c92d48c225e43881c0b3470d50f7cff167c3/cryptography-42.0.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:324721d93b998cb7367f1e6897370644751e5580ff9b370c0a50dc60a2003513"}, + {url = "https://files.pythonhosted.org/packages/1d/95/e81ad3a9caadfc6a4367de7432fd3b779a2e2af760ce9a9cb4f5704d57ca/cryptography-42.0.0.tar.gz", hash = "sha256:6cf9b76d6e93c62114bd19485e5cb003115c134cf9ce91f8ac924c44f8c8c3f4"}, + {url = "https://files.pythonhosted.org/packages/37/f1/246a240613342d8f2b55c3d53e1aaa007dd1a2da89c63c284ab1a1c14c19/cryptography-42.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:bd7cf7a8d9f34cc67220f1195884151426ce616fdc8285df9054bfa10135925f"}, + {url = "https://files.pythonhosted.org/packages/3e/70/622ddb0c709ce19a3e0d19966d8cf6f2c3a5783274008d848cb26b1a18d7/cryptography-42.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:5a217bca51f3b91971400890905a9323ad805838ca3fa1e202a01844f485ee87"}, + {url = "https://files.pythonhosted.org/packages/3f/75/d9d9da7bc4ff3bb10efb2ba97d1fc312eaf6ead7fd9948739ab04f57919a/cryptography-42.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c58115384bdcfe9c7f644c72f10f6f42bed7cf59f7b52fe1bf7ae0a622b3a139"}, + {url = "https://files.pythonhosted.org/packages/40/35/b1ed9dce391efb6be76e2daf6d22bccfbc5906fc9db25ed32ce176a4a7c6/cryptography-42.0.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bdce70e562c69bb089523e75ef1d9625b7417c6297a76ac27b1b8b1eb51b7d0f"}, + {url = "https://files.pythonhosted.org/packages/42/0e/7c08584648a678f72b572a59be10d7dbb707a0f4ada3ba7867c2c24b8820/cryptography-42.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c310767268d88803b653fffe6d6f2f17bb9d49ffceb8d70aed50ad45ea49ab08"}, + {url = "https://files.pythonhosted.org/packages/47/27/f275bcc9c1a43bced5cbfa77b30bd6f65cf654a4820087f585dc0cb4c4d5/cryptography-42.0.0-cp37-abi3-win32.whl", hash = "sha256:8814722cffcfd1fbd91edd9f3451b88a8f26a5fd41b28c1c9193949d1c689dc4"}, + {url = "https://files.pythonhosted.org/packages/48/d5/91e831a6613b05aa2953a55aa0a04ec909c0a3212ea095038932be71fa02/cryptography-42.0.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:8fedec73d590fd30c4e3f0d0f4bc961aeca8390c72f3eaa1a0874d180e868ddf"}, + {url = "https://files.pythonhosted.org/packages/70/be/acec07938369a79785521ec3927fe4f7b218906c117d62f53e82536d63f5/cryptography-42.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:56ce0c106d5c3fec1038c3cca3d55ac320a5be1b44bf15116732d0bc716979a2"}, + {url = "https://files.pythonhosted.org/packages/75/a7/5fa7af8f4d3afc997ea0cadd0b61f429157cfe1e00b32d2f80209ee6e4c9/cryptography-42.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ca482ea80626048975360c8e62be3ceb0f11803180b73163acd24bf014133a0"}, + {url = "https://files.pythonhosted.org/packages/7c/5c/db5bf91d7180237315f9f6ffc232b270efbc548e00354f4fcc81cd38ac22/cryptography-42.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87086eae86a700307b544625e3ba11cc600c3c0ef8ab97b0fda0705d6db3d4e3"}, + {url = "https://files.pythonhosted.org/packages/87/70/3872191532a869ebc64b3724a770f7df027688875569eba466a19442a833/cryptography-42.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:146e971e92a6dd042214b537a726c9750496128453146ab0ee8971a0299dc9bd"}, + {url = "https://files.pythonhosted.org/packages/8d/3d/3748781509216a0a36535bee1a8ad2ffe1f361bd84178e69aa1306727cf4/cryptography-42.0.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3005166a39b70c8b94455fdbe78d87a444da31ff70de3331cdec2c568cf25b7e"}, + {url = "https://files.pythonhosted.org/packages/9e/a3/1bd5fbf562cdc833a3346057989dcb9f4739a3dc23702fdb0a93c22bed31/cryptography-42.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:35cf6ed4c38f054478a9df14f03c1169bb14bd98f0b1705751079b25e1cb58bc"}, + {url = "https://files.pythonhosted.org/packages/a0/2a/ee11ab07177b9677d0a784b44adeba08a2335f96996b53747b13215610ed/cryptography-42.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be41b0c7366e5549265adf2145135dca107718fa44b6e418dc7499cfff6b4689"}, + {url = "https://files.pythonhosted.org/packages/a1/4b/aaa09fcf30295e8eea0c2d31f3e86e7f9ab7ffffce77428f784603ccd17e/cryptography-42.0.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:e9326ca78111e4c645f7e49cbce4ed2f3f85e17b61a563328c85a5208cf34440"}, + {url = "https://files.pythonhosted.org/packages/a6/dd/2215fe4262689ddf745329ea1ac5bfd0f9a36c83393a22f9b3f88a83c736/cryptography-42.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:be14b31eb3a293fc6e6aa2807c8a3224c71426f7c4e3639ccf1a2f3ffd6df8c3"}, + {url = "https://files.pythonhosted.org/packages/ab/ce/b3d3690be81e580861ba8d327ccd138fb6d132865f2d57110f373ec41f60/cryptography-42.0.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:678cfa0d1e72ef41d48993a7be75a76b0725d29b820ff3cfd606a5b2b33fda01"}, + {url = "https://files.pythonhosted.org/packages/af/99/a75191ea7f2bcfc30c21265d02693409393142b8f48589e8650756dc4fc0/cryptography-42.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9515ea7f596c8092fdc9902627e51b23a75daa2c7815ed5aa8cf4f07469212ec"}, + {url = "https://files.pythonhosted.org/packages/b8/01/d98f0563c34b50d65ba3ee732f4b80d4242a61d8f445184e4088ba26ebe5/cryptography-42.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:0a68bfcf57a6887818307600c3c0ebc3f62fbb6ccad2240aa21887cda1f8df1b"}, + {url = "https://files.pythonhosted.org/packages/bb/a0/001701ed3c1af3764209586325cdabf9cc108f85046aca76bb468c136bb9/cryptography-42.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:206aaf42e031b93f86ad60f9f5d9da1b09164f25488238ac1dc488334eb5e221"}, + {url = "https://files.pythonhosted.org/packages/c7/44/a9f709e81e85556f3397e49d6c9bf978a92b43a825a9a3ab160745e4fa47/cryptography-42.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:85f759ed59ffd1d0baad296e72780aa62ff8a71f94dc1ab340386a1207d0ea81"}, + {url = "https://files.pythonhosted.org/packages/ec/74/d83327b88177157e5c7d35c232bcbe1571172871ca4e6181a94c9d8dd174/cryptography-42.0.0-cp39-abi3-win32.whl", hash = "sha256:74f18a4c8ca04134d2052a140322002fef535c99cdbc2a6afc18a8024d5c9d5b"}, + {url = "https://files.pythonhosted.org/packages/ed/aa/82230dc50c543fc4d9c1035dc163bdb2db8127f7569500d3587c69c6e80f/cryptography-42.0.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:33588310b5c886dfb87dba5f013b8d27df7ffd31dc753775342a1e5ab139e59d"}, + {url = "https://files.pythonhosted.org/packages/ef/2e/53f1c6af9f8f1d61692d544f487102bcec7a6433bbf0212220dd31a1be5c/cryptography-42.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:69fd009a325cad6fbfd5b04c711a4da563c6c4854fc4c9544bff3088387c77c0"}, + {url = "https://files.pythonhosted.org/packages/fd/90/ceedb243089bd9900e9aa056e33439642fcfc16f1e61ee9096b7317d2ab2/cryptography-42.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:988b738f56c665366b1e4bfd9045c3efae89ee366ca3839cd5af53eaa1401bce"}, + {url = "https://files.pythonhosted.org/packages/fe/3d/9851b8398591fe6da5ac64a27fc06f8e243416cb46da10452d9b1281fa8c/cryptography-42.0.0-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:c640b0ef54138fde761ec99a6c7dc4ce05e80420262c20fa239e694ca371d434"}, + {url = "https://files.pythonhosted.org/packages/fe/77/b94c51dd91db91816edf1887b8213b6efcfaabf6c29db75498e4006159da/cryptography-42.0.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:d97aae66b7de41cdf5b12087b5509e4e9805ed6f562406dfcf60e8481a9a28f8"}, +] +"daphne 4.0.0" = [ + {url = "https://files.pythonhosted.org/packages/04/f6/86145f59db1b19e2d1c6a1a4981c7923b7fb3136f2461d4378c9047f2efa/daphne-4.0.0-py3-none-any.whl", hash = "sha256:a288ece46012b6b719c37150be67c69ebfca0793a8521bf821533bad983179b2"}, + {url = "https://files.pythonhosted.org/packages/d7/77/57b19d5caabf8537879aa4cf3a017b99d0b727f2521ffca7fd9140573509/daphne-4.0.0.tar.gz", hash = "sha256:cce9afc8f49a4f15d4270b8cfb0e0fe811b770a5cc795474e97e4da287497666"}, ] "databind-core 4.4.0" = [ {url = "https://files.pythonhosted.org/packages/2c/85/616a86f0c667e57ea1ebe1159f77b60fba88431a44d0a5ca9096ae5957fb/databind.core-4.4.0-py3-none-any.whl", hash = "sha256:3c8a4d9abc93e158af9931d8cec389ddfc0514e02aec03b397948d243db11881"}, @@ -1676,6 +1984,10 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/9a/bb/48aa3e0850923096dff2766d21a6004d6e1a3317f0bd400ba81f586754e1/Django-4.2.tar.gz", hash = "sha256:c36e2ab12824e2ac36afa8b2515a70c53c7742f0d6eaefa7311ec379558db997"}, {url = "https://files.pythonhosted.org/packages/d9/40/6012f98b14b64b4d3dc47b0c2f116fccbd0795ab35515d0c40dac73b81b8/Django-4.2-py3-none-any.whl", hash = "sha256:ad33ed68db9398f5dfb33282704925bce044bef4261cd4fb59e4e7f9ae505a78"}, ] +"django-channels-graphql-ws 1.0.0rc6" = [ + {url = "https://files.pythonhosted.org/packages/37/1e/4b85e9297d2aa6bc79c398b59db23d43ddbaefe05629dde3a964f288b1c1/django_channels_graphql_ws-1.0.0rc6-py3-none-any.whl", hash = "sha256:ebaf1ddb2527a5a5e69a368fbf28a8c978f84ce33803c1d4dde7d0265c15f77f"}, + {url = "https://files.pythonhosted.org/packages/8d/16/ef75dc90835fdc59fe68a3600cbfa37b0e80fdb97dd1caa5c2719ce75fe9/django_channels_graphql_ws-1.0.0rc6.tar.gz", hash = "sha256:36d848f404e5d616060cfc9eddb7e60a69ca54ff24ab1d8939b3d51144e747fc"}, +] "django-environ 0.9.0" = [ {url = "https://files.pythonhosted.org/packages/60/5a/f231f5d3e15217cdf0164019cff5c4a7e5ba6bb5fd502759f94972786e17/django_environ-0.9.0-py2.py3-none-any.whl", hash = "sha256:f21a5ef8cc603da1870bbf9a09b7e5577ab5f6da451b843dbcc721a7bca6b3d9"}, {url = "https://files.pythonhosted.org/packages/bf/5a/0325376b74279c89cfbdfd134d044094dfce91c1e8f21ea4088f43f56f68/django-environ-0.9.0.tar.gz", hash = "sha256:bff5381533056328c9ac02f71790bd5bf1cea81b1beeb648f28b81c9e83e0a21"}, @@ -1696,6 +2008,10 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/03/54/0501698e9d4f5205213eff5290b489912b149ce2dde7b250ab000c08f81a/django_ratelimit-4.0.0-py2.py3-none-any.whl", hash = "sha256:a610b5fd052c843a589084f6934bc6d827ec6242d5965110ebd436ca5a59ef39"}, {url = "https://files.pythonhosted.org/packages/4b/9c/b33cd585e1e4352c2f12d18cf099b18de4df5d26fb015127438300795da2/django-ratelimit-4.0.0.tar.gz", hash = "sha256:19cba9e8101277f28c7a974c54c997067341ab30175431d3739e8ffb63cdd2b2"}, ] +"django-redis 5.4.0" = [ + {url = "https://files.pythonhosted.org/packages/83/9d/2272742fdd9d0a9f0b28cd995b0539430c9467a2192e4de2cea9ea6ad38c/django-redis-5.4.0.tar.gz", hash = "sha256:6a02abaa34b0fea8bf9b707d2c363ab6adc7409950b2db93602e6cb292818c42"}, + {url = "https://files.pythonhosted.org/packages/b7/f1/63caad7c9222c26a62082f4f777de26389233b7574629996098bf6d25a4d/django_redis-5.4.0-py3-none-any.whl", hash = "sha256:ebc88df7da810732e2af9987f7f426c96204bf89319df4c6da6ca9a2942edd5b"}, +] "django-storages 1.13.2" = [ {url = "https://files.pythonhosted.org/packages/06/ed/6eef8d009138d4c58c63026bf24e946a7e09caac77aca33ab46a5e5bc51f/django_storages-1.13.2-py3-none-any.whl", hash = "sha256:31dc5a992520be571908c4c40d55d292660ece3a55b8141462b4e719aa38eab3"}, {url = "https://files.pythonhosted.org/packages/cb/8a/3872af7e3d61a8eb7616872549cd74f7f1090de41792a059adb7ce6854dc/django-storages-1.13.2.tar.gz", hash = "sha256:cbadd15c909ceb7247d4ffc503f12a9bec36999df8d0bef7c31e57177d512688"}, @@ -1962,14 +2278,64 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/06/89/acd9879fa6a5309b4bf16a5a8855f1e58f26d38e0c18ede9b3a70996b021/gunicorn-21.2.0.tar.gz", hash = "sha256:88ec8bff1d634f98e61b9f65bc4bf3cd918a90806c6f5c48bc5603849ec81033"}, {url = "https://files.pythonhosted.org/packages/0e/2a/c3a878eccb100ccddf45c50b6b8db8cf3301a6adede6e31d48e8531cab13/gunicorn-21.2.0-py3-none-any.whl", hash = "sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0"}, ] +"h11 0.14.0" = [ + {url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] "hashids 1.3.1" = [ {url = "https://files.pythonhosted.org/packages/26/a2/6f38b1de47b41ad0420047ad03b0b8cd5d6572271a3e9c2ab70e373fe63a/hashids-1.3.1.tar.gz", hash = "sha256:6c3dc775e65efc2ce2c157a65acb776d634cb814598f406469abef00ae3f635c"}, {url = "https://files.pythonhosted.org/packages/6e/46/ffdf25b1f6dbb1ce588ccb818e983df9e3d30594679f5a08c865a59cead7/hashids-1.3.1-py2.py3-none-any.whl", hash = "sha256:8bddd1acba501bfc9306e7e5a99a1667f4f2cacdc20cbd70bcc5ddfa5147c94c"}, ] +"httptools 0.6.1" = [ + {url = "https://files.pythonhosted.org/packages/02/ba/e7c6040bd3b5e46c17dcf84c8c667e3e2fb4a1ac7bec92d925fc0a35fb96/httptools-0.6.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:95fb92dd3649f9cb139e9c56604cc2d7c7bf0fc2e7c8d7fbd58f96e35eddd2a3"}, + {url = "https://files.pythonhosted.org/packages/0a/0d/ca545a8a2831fc3e326fffecab268a2e7775e5ec4d57afc8f5ddc578cbd7/httptools-0.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ebaec1bf683e4bf5e9fbb49b8cc36da482033596a415b3e4ebab5a4c0d7ec5e"}, + {url = "https://files.pythonhosted.org/packages/14/e4/20d28dfe7f5b5603b6b04c33bb88662ad749de51f0c539a561f235f42666/httptools-0.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3"}, + {url = "https://files.pythonhosted.org/packages/1e/fc/8a26c2adcd3f141e4729897633f03832b71ebea6f4c31cce67a92ded1961/httptools-0.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b"}, + {url = "https://files.pythonhosted.org/packages/42/44/4b9ff8fd96776e775c1d480f6f8ce6d366e96f49b8df0a361cf000643a6e/httptools-0.6.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8e216a038d2d52ea13fdd9b9c9c7459fb80d78302b257828285eca1c773b99b3"}, + {url = "https://files.pythonhosted.org/packages/4c/b8/9494a21832eea0d7429fb1d5948fdf3ea490d7b3fe32fc3d6e63f54b9aed/httptools-0.6.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3c3b214ce057c54675b00108ac42bacf2ab8f85c58e3f324a4e963bbc46424f4"}, + {url = "https://files.pythonhosted.org/packages/4e/74/6348ce41fb5c1484f35184c172efb8854a288e6090bb54e2210598268369/httptools-0.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58"}, + {url = "https://files.pythonhosted.org/packages/53/d3/968ab0568634f226ed20d82131c0304550fa2d60088a3699281ea8f4b34d/httptools-0.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dcbab042cc3ef272adc11220517278519adf8f53fd3056d0e68f0a6f891ba94e"}, + {url = "https://files.pythonhosted.org/packages/56/a9/bb66e122917639ea3b419d64e4ab5ec1f9353c3a56cc3dee063260375d47/httptools-0.6.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8ae5b97f690badd2ca27cbf668494ee1b6d34cf1c464271ef7bfa9ca6b83ffaf"}, + {url = "https://files.pythonhosted.org/packages/59/13/9c253d23e62539922032a967ae06ce16e53c3bba592d4ff63920058f0bbb/httptools-0.6.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e0b281cf5a125c35f7f6722b65d8542d2e57331be573e9e88bc8b0115c4a7a81"}, + {url = "https://files.pythonhosted.org/packages/59/23/047a89e66045232fb82c50ae57699e40f70e073ae5ccd53f54e532fbd2a2/httptools-0.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d9ceb2c957320def533671fc9c715a80c47025139c8d1f3797477decbc6edd2"}, + {url = "https://files.pythonhosted.org/packages/5e/cc/6dbced1d801ce1370d04117510b6d3f824f63392cfa6585077caec55ee16/httptools-0.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:405784577ba6540fa7d6ff49e37daf104e04f4b4ff2d1ac0469eaa6a20fde084"}, + {url = "https://files.pythonhosted.org/packages/60/13/b62e086b650752adf9094b7e62dab97f4cb7701005664544494b7956a51e/httptools-0.6.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0"}, + {url = "https://files.pythonhosted.org/packages/65/e7/dd5ba95c84047118a363f0755ad78e639e0529be92424bb020496578aa3b/httptools-0.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185"}, + {url = "https://files.pythonhosted.org/packages/67/1d/d77686502fced061b3ead1c35a2d70f6b281b5f723c4eff7a2277c04e4a2/httptools-0.6.1.tar.gz", hash = "sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a"}, + {url = "https://files.pythonhosted.org/packages/69/45/0f5014fa50f923599fead11e001e23fb210a1f82dddc1afbf00db20ff4ff/httptools-0.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cf2372e98406efb42e93bfe10f2948e467edfd792b015f1b4ecd897903d3e8d"}, + {url = "https://files.pythonhosted.org/packages/76/7a/45c5a9a2e9d21f7381866eb7b6ead5a84d8fe7e54e35208eeb18320a29b4/httptools-0.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc"}, + {url = "https://files.pythonhosted.org/packages/7c/58/d3728a369eaacd125918469c767e4af00326255db29e5e070433d9f40165/httptools-0.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:678fcbae74477a17d103b7cae78b74800d795d702083867ce160fc202104d0da"}, + {url = "https://files.pythonhosted.org/packages/80/01/379f6466d8e2edb861c1f44ccac255ed1f8a0d4c5c666a1ceb34caad7555/httptools-0.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb"}, + {url = "https://files.pythonhosted.org/packages/80/dd/cebc9d4b1d4b70e9f3d40d1db0829a28d57ca139d0b04197713816a11996/httptools-0.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0"}, + {url = "https://files.pythonhosted.org/packages/82/f5/50708abc7965d7d93c0ee14a148ccc6d078a508f47fe9357c79d5360f252/httptools-0.6.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837"}, + {url = "https://files.pythonhosted.org/packages/8c/0f/ac82bdc14f5e4bff59a3c3c35fa7a9b7a2f8d983c4d5a33b20e4848b3f14/httptools-0.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:95658c342529bba4e1d3d2b1a874db16c7cca435e8827422154c9da76ac4e13a"}, + {url = "https://files.pythonhosted.org/packages/99/c9/53ed7176583ec4b4364d941a08624288f2ae55b4ff58b392cdb68db1e1ed/httptools-0.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658"}, + {url = "https://files.pythonhosted.org/packages/a0/f8/199e857258b4310b439431ec0c34515846dab092e13f945d8852919ac636/httptools-0.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bd3e488b447046e386a30f07af05f9b38d3d368d1f7b4d8f7e10af85393db97"}, + {url = "https://files.pythonhosted.org/packages/a2/9a/aa406864f3108e06f7320425a528ff8267124dead1fd72a3e9da2067f893/httptools-0.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93ad80d7176aa5788902f207a4e79885f0576134695dfb0fefc15b7a4648d503"}, + {url = "https://files.pythonhosted.org/packages/a9/6a/80bce0216b63babf51cdc34814c3f0f10489e13ab89fb6bc91202736a8a2/httptools-0.6.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f"}, + {url = "https://files.pythonhosted.org/packages/bd/7d/4cd75356dfe0ed0b40ca6873646bf9ff7b5138236c72338dc569dc57d509/httptools-0.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563"}, + {url = "https://files.pythonhosted.org/packages/c8/4d/1e14e818a086ce800a57c5025707ecbc66083921754b77f5e41879e132cd/httptools-0.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe467eb086d80217b7584e61313ebadc8d187a4d95bb62031b7bab4b205c3ba3"}, + {url = "https://files.pythonhosted.org/packages/cf/3a/3fd8dfb987c4247651baf2ac6f28e8e9f889d484ca1a41a9ad0f04dfe300/httptools-0.6.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84"}, + {url = "https://files.pythonhosted.org/packages/d0/a4/b503851c40f20bcbd453db24ed35d961f62abdae0dccc8f672cd5d350d87/httptools-0.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90"}, + {url = "https://files.pythonhosted.org/packages/d3/97/60860e9ee87a7d4712b98f7e1411730520053b9d69e9e42b0b9751809c17/httptools-0.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949"}, + {url = "https://files.pythonhosted.org/packages/d8/97/b37d596bc32be291477a8912bf9d1508d7e8553aa11a30cd871fd89cbae4/httptools-0.6.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142"}, + {url = "https://files.pythonhosted.org/packages/e3/1e/9823ca7aab323c0e0e9dd82ce835a6e93b69f69aedffbc94d31e327f4283/httptools-0.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d"}, + {url = "https://files.pythonhosted.org/packages/e8/f5/ec2d069be4f76c63d942e4e35eeebedc3239b6528da17b2dd73d8e076a35/httptools-0.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3e802e0b2378ade99cd666b5bffb8b2a7cc8f3d28988685dc300469ea8dd86cb"}, + {url = "https://files.pythonhosted.org/packages/f5/d1/53283b96ed823d5e4d89ee9aa0f29df5a1bdf67f148e061549a595d534e4/httptools-0.6.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1"}, + {url = "https://files.pythonhosted.org/packages/f8/5d/9ad32b79b6c24524087e78aa3f0a2dfcf58c11c90e090e4593b35def8a86/httptools-0.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2"}, +] +"hyperlink 21.0.0" = [ + {url = "https://files.pythonhosted.org/packages/3a/51/1947bd81d75af87e3bb9e34593a4cf118115a8feb451ce7a69044ef1412e/hyperlink-21.0.0.tar.gz", hash = "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b"}, + {url = "https://files.pythonhosted.org/packages/6e/aa/8caf6a0a3e62863cbb9dab27135660acba46903b703e224f14f447e57934/hyperlink-21.0.0-py2.py3-none-any.whl", hash = "sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4"}, +] "idna 3.3" = [ {url = "https://files.pythonhosted.org/packages/04/a2/d918dcd22354d8958fe113e1a3630137e0fc8b44859ade3063982eacd2a4/idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, {url = "https://files.pythonhosted.org/packages/62/08/e3fc7c8161090f742f504f40b1bccbfc544d4a4e09eb774bf40aafce5436/idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, ] +"incremental 22.10.0" = [ + {url = "https://files.pythonhosted.org/packages/77/51/8073577012492fcd15628e811db585f447c500fa407e944ab3a18ec55fb7/incremental-22.10.0-py2.py3-none-any.whl", hash = "sha256:b864a1f30885ee72c5ac2835a761b8fe8aa9c28b9395cacf27286602688d3e51"}, + {url = "https://files.pythonhosted.org/packages/86/42/9e87f04fa2cd40e3016f27a4b4572290e95899c6dce317e2cdb580f3ff09/incremental-22.10.0.tar.gz", hash = "sha256:912feeb5e0f7e0188e6f42241d2f450002e11bbc0937c65865045854c24c0bd0"}, +] "inflection 0.5.1" = [ {url = "https://files.pythonhosted.org/packages/59/91/aa6bde563e0085a02a435aa99b49ef75b0a4b062635e606dab23ce18d720/inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"}, {url = "https://files.pythonhosted.org/packages/e1/7e/691d061b7329bc8d54edbf0ec22fbfb2afe61facb681f9aaa9bff7a27d04/inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"}, @@ -2068,6 +2434,64 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/90/28/9bca5de096abcb2f3dbc33aae389c66aa8ca9e72282b4ff846feecd59df5/moto-4.1.1.tar.gz", hash = "sha256:6c45755e541a85e5382f809c75255d0b6335de334e7e8eb717f8fdc755830a8c"}, {url = "https://files.pythonhosted.org/packages/aa/19/37b2d52c0088ac13ec221e5e37d473b3f3f76ec270b359e21d73de35c89f/moto-4.1.1-py2.py3-none-any.whl", hash = "sha256:c4df7ae86f7cdd8ffcb2fcf55a45a7ab9f854ec631f1b9c82b1f47ae8c033326"}, ] +"msgpack 1.0.7" = [ + {url = "https://files.pythonhosted.org/packages/00/3f/6fcd74c85b7fa96dacbada96796ca81308e856f2a12458f6ebc3a1f2faa9/msgpack-1.0.7-cp39-cp39-win32.whl", hash = "sha256:f26a07a6e877c76a88e3cecac8531908d980d3d5067ff69213653649ec0f60ad"}, + {url = "https://files.pythonhosted.org/packages/09/00/83d7cd67ec05772799b264ea3070a55b58b3351b01fe8cd3b00a759383b1/msgpack-1.0.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38949d30b11ae5f95c3c91917ee7a6b239f5ec276f271f28638dec9156f82cfc"}, + {url = "https://files.pythonhosted.org/packages/0a/7a/73a184ed27c974f18cd7c8f571e99fe22faef643fd7c34feee515dc60e36/msgpack-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3967e4ad1aa9da62fd53e346ed17d7b2e922cba5ab93bdd46febcac39be636fc"}, + {url = "https://files.pythonhosted.org/packages/0c/ac/66625b05091b97ca2c7418eb2d2af152f033d969519f9315556a4ed800fe/msgpack-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1"}, + {url = "https://files.pythonhosted.org/packages/0e/bf/e5318f60000d14912da75088662c308d4335dd13bb5b7707cf472b746343/msgpack-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfef2bb6ef068827bbd021017a107194956918ab43ce4d6dc945ffa13efbc25f"}, + {url = "https://files.pythonhosted.org/packages/10/b6/e8123361c50859c510cf03f5fbe7d8c1fff16689e4a7dddd619f7287b286/msgpack-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd178c4c80706546702c59529ffc005681bd6dc2ea234c450661b205445a34d"}, + {url = "https://files.pythonhosted.org/packages/15/56/a677cd761a2cefb2e3ffe7e684633294dccb161d78e8ea6da9277e45b4a2/msgpack-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93"}, + {url = "https://files.pythonhosted.org/packages/1a/c7/2d31e1819b5c8619deff40ca4ca31cb9e48662f4ab2b0a35942007986b3f/msgpack-1.0.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:822ea70dc4018c7e6223f13affd1c5c30c0f5c12ac1f96cd8e9949acddb48a61"}, + {url = "https://files.pythonhosted.org/packages/1d/f3/44968c303d70a9d1c5cd68180319851e3bb7396580a4c9f6c58b841b4409/msgpack-1.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36e17c4592231a7dbd2ed09027823ab295d2791b3b1efb2aee874b10548b7524"}, + {url = "https://files.pythonhosted.org/packages/26/84/93e3cee53a1c32cfa672c65adcfb725e6a2b29f7cf710f62e0cbff6bcfaa/msgpack-1.0.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:235a31ec7db685f5c82233bddf9858748b89b8119bf4538d514536c485c15fe0"}, + {url = "https://files.pythonhosted.org/packages/26/a5/78a7d87f5f8ffe4c32167afa15d4957db649bab4822f909d8d765339bbab/msgpack-1.0.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e"}, + {url = "https://files.pythonhosted.org/packages/40/3f/d7e9327123445429a166a86b4f3b27b161b2bba1fe0710210bd8a0a46325/msgpack-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:1dc93e8e4653bdb5910aed79f11e165c85732067614f180f70534f056da97db3"}, + {url = "https://files.pythonhosted.org/packages/41/3a/2e2e902afcd751738e38d88af976fc4010b16e8e821945f4cbf32f75f9c3/msgpack-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862"}, + {url = "https://files.pythonhosted.org/packages/46/4f/6119d222e1a5ee107820abcc188b41b248a2f520d4c2f6a9f8a1bca519e8/msgpack-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:484ae3240666ad34cfa31eea7b8c6cd2f1fdaae21d73ce2974211df099a95d81"}, + {url = "https://files.pythonhosted.org/packages/46/95/d0440400485eab1bf50f1efe5118967b539f3191d994c3dfc220657594cd/msgpack-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee"}, + {url = "https://files.pythonhosted.org/packages/4b/14/c62fbc8dff118f1558e43b9469d56a1f37bbb35febadc3163efaedd01500/msgpack-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415"}, + {url = "https://files.pythonhosted.org/packages/4c/bc/dc184d943692671149848438fb3bed3a3de288ce7998cb91bc98f40f201b/msgpack-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e"}, + {url = "https://files.pythonhosted.org/packages/4c/f6/386ba279d3f1dd3f5e1036f8689dd1ae25c95d292df44c0f11038a12d135/msgpack-1.0.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dd632777ff3beaaf629f1ab4396caf7ba0bdd075d948a69460d13d44357aca4c"}, + {url = "https://files.pythonhosted.org/packages/58/99/2b2e64b7195f62b88be01c13ed0244055498d9cd1454f2aafa1a2df24dd3/msgpack-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ffbc252eb0d229aeb2f9ad051200668fc3a9aaa8994e49f0cb2ffe2b7867e7"}, + {url = "https://files.pythonhosted.org/packages/5d/4d/d98592099d4f18945f89cf3e634dc0cb128bb33b1b93f85a84173d35e181/msgpack-1.0.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5"}, + {url = "https://files.pythonhosted.org/packages/5e/44/6556ffe169bf2c0e974e2ea25fb82a7e55ebcf52a81b03a5e01820de5f84/msgpack-1.0.7-cp312-cp312-win32.whl", hash = "sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9"}, + {url = "https://files.pythonhosted.org/packages/68/8e/46e5e1b863030a9b6ba116d5b2f101b1523180bbbca55f6f9ad6a9839a7a/msgpack-1.0.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cab3db8bab4b7e635c1c97270d7a4b2a90c070b33cbc00c99ef3f9be03d3e1f7"}, + {url = "https://files.pythonhosted.org/packages/6d/74/bd02044eb628c7361ad2bd8c1a6147af5c6c2bbceb77b3b1da20f4a8a9c5/msgpack-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46"}, + {url = "https://files.pythonhosted.org/packages/6f/8a/34f1726d2c9feccec3d946776e9bce8f20ae09d8b91899fc20b296c942af/msgpack-1.0.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4"}, + {url = "https://files.pythonhosted.org/packages/74/dc/19d6194e9f31bb67b6735e1ebd93eb6cdb9f24792cf7689aeab63e35ed05/msgpack-1.0.7-cp38-cp38-win32.whl", hash = "sha256:4e71bc4416de195d6e9b4ee93ad3f2f6b2ce11d042b4d7a7ee00bbe0358bd0c2"}, + {url = "https://files.pythonhosted.org/packages/76/33/35df717bc095c6e938b3c65ed117b95048abc24d1614427685123fb2f0af/msgpack-1.0.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d"}, + {url = "https://files.pythonhosted.org/packages/77/24/045045a06521bc5bcbf5917a1467a92b8d3b9dd047c2e4d1e8ca6ec560ee/msgpack-1.0.7-cp38-cp38-win_amd64.whl", hash = "sha256:8f5b234f567cf76ee489502ceb7165c2a5cecec081db2b37e35332b537f8157c"}, + {url = "https://files.pythonhosted.org/packages/78/61/91bae9474def032f6c333d62889bbeda9e1554c6b123375ceeb1767efd78/msgpack-1.0.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c"}, + {url = "https://files.pythonhosted.org/packages/86/a6/490792a524a82e855bdf3885ecb73d7b3a0b17744b3cf4a40aea13ceca38/msgpack-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329"}, + {url = "https://files.pythonhosted.org/packages/89/75/1ed3a96e12941873fd957e016cc40c0c178861a872bd45e75b9a188eb422/msgpack-1.0.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5"}, + {url = "https://files.pythonhosted.org/packages/95/9f/c1feee104ad1fb58f75ce32a02d4a0f05ffcdfeb7459d172b9eaf8fa1d27/msgpack-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:384d779f0d6f1b110eae74cb0659d9aa6ff35aaf547b3955abf2ab4c901c4819"}, + {url = "https://files.pythonhosted.org/packages/9b/07/0b3f089684ca330602b2994248eda2898a7232e4b63882b9271164ef672e/msgpack-1.0.7-cp310-cp310-win32.whl", hash = "sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9"}, + {url = "https://files.pythonhosted.org/packages/9c/7e/dc0dc8de2bf27743b31691149258f9b1bd4bf3c44c105df3df9b97081cd1/msgpack-1.0.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba"}, + {url = "https://files.pythonhosted.org/packages/9c/f6/e64c72577d6953789c3cb051b059a4b56317056b3c65013952338ed8a34e/msgpack-1.0.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee"}, + {url = "https://files.pythonhosted.org/packages/a2/90/2d769e693654f036acfb462b54dacb3ae345699999897ca34f6bd9534fe9/msgpack-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6"}, + {url = "https://files.pythonhosted.org/packages/a5/74/99f6077754665613ea1f37b3d91c10129f6976b7721ab4d0973023808e5a/msgpack-1.0.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075"}, + {url = "https://files.pythonhosted.org/packages/a6/3c/66220419738efe82ef88ac3ddf840cb8b35b3fd94bced232dd7113f8b2a8/msgpack-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ed82f5a7af3697b1c4786053736f24a0efd0a1b8a130d4c7bfee4b9ded0f08f"}, + {url = "https://files.pythonhosted.org/packages/ad/72/d39ed43bfb2ec6968d768318477adb90c474bdc59b2437170c6697ee4115/msgpack-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b"}, + {url = "https://files.pythonhosted.org/packages/af/d1/abbdd58a43827fbec5d98427a7a535c620890289b9d927154465313d6967/msgpack-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d"}, + {url = "https://files.pythonhosted.org/packages/b4/3d/c8dd23050eefa3d9b9c5b8329ed3308c2f2f80f65825e9ea4b7fa621cdab/msgpack-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82"}, + {url = "https://files.pythonhosted.org/packages/c2/d5/5662032db1571110b5b51647aed4b56dfbd01bfae789fa566a2be1f385d1/msgpack-1.0.7.tar.gz", hash = "sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87"}, + {url = "https://files.pythonhosted.org/packages/cf/7b/1bc69d4a56c8d2f4f2dfbe4722d40344af9a85b6fb3b09cfb350ba6a42f6/msgpack-1.0.7-cp311-cp311-win32.whl", hash = "sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1"}, + {url = "https://files.pythonhosted.org/packages/d4/53/698c10913947f97f6fe7faad86a34e6aa1b66cea2df6f99105856bd346d9/msgpack-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002"}, + {url = "https://files.pythonhosted.org/packages/d7/47/20dff6b4512cf3575550c8801bc53fe7d540f4efef9c5c37af51760fcdcf/msgpack-1.0.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b"}, + {url = "https://files.pythonhosted.org/packages/d9/fe/4ce9fe50b4cf1fc0f26df810db6dfedac39ef683a7a8deae4ab4934ec459/msgpack-1.0.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ff1d0899f104f3921d94579a5638847f783c9b04f2d5f229392ca77fba5b82fc"}, + {url = "https://files.pythonhosted.org/packages/dc/c1/63903f30d51d165e132e5221a2a4a1bbfab7508b68131c871d70bffac78a/msgpack-1.0.7-cp312-cp312-win_amd64.whl", hash = "sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf"}, + {url = "https://files.pythonhosted.org/packages/de/4e/a0e8611f94bac32d2c1c4ad05bb1c0ae61132e3398e0b44a93e6d7830968/msgpack-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681"}, + {url = "https://files.pythonhosted.org/packages/df/09/dee50913ba5cc047f7fd7162f09453a676e7935c84b3bf3a398e12108677/msgpack-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b"}, + {url = "https://files.pythonhosted.org/packages/e2/f8/8680a48febe63b8c3313e3240c3de17942aeeb2a0e3af33542f47e0a4eed/msgpack-1.0.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5b6ccc0c85916998d788b295765ea0e9cb9aac7e4a8ed71d12e7d8ac31c23c95"}, + {url = "https://files.pythonhosted.org/packages/e3/1e/7e1375fb92a1f0ae6bb6b6b94425f89e4e352974355f0ded60dad1aed71a/msgpack-1.0.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dc43f1ec66eb8440567186ae2f8c447d91e0372d793dfe8c222aec857b81a8cf"}, + {url = "https://files.pythonhosted.org/packages/e5/0a/c6a1390f9c6a31da0fecbbfdb86b1cb39ad302d9e24f9cca3d9e14c364f0/msgpack-1.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672"}, + {url = "https://files.pythonhosted.org/packages/e5/57/d181484eb77bc726154ff73c057a744fcef2f3b9721b25dc951e9f2bffa3/msgpack-1.0.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bfdd914e55e0d2c9e1526de210f6fe8ffe9705f2b1dfcc4aecc92a4cb4b533d"}, + {url = "https://files.pythonhosted.org/packages/ef/a2/589139caa054b5c242a5682fa6b6f119e16e9d1aefc49c4412e57eb7549c/msgpack-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f64e376cd20d3f030190e8c32e1c64582eba56ac6dc7d5b0b49a9d44021b52fd"}, + {url = "https://files.pythonhosted.org/packages/f5/3f/9730c6cb574b15d349b80cd8523a7df4b82058528339f952ea1c32ac8a10/msgpack-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c"}, + {url = "https://files.pythonhosted.org/packages/f5/4e/1ab4a982cbd90f988e49f849fc1212f2c04a59870c59daabf8950617e2aa/msgpack-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8"}, + {url = "https://files.pythonhosted.org/packages/f9/b3/309de40dc7406b7f3492332c5ee2b492a593c2a9bb97ea48ebf2f5279999/msgpack-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84"}, +] "multidict 6.0.4" = [ {url = "https://files.pythonhosted.org/packages/00/bb/1cdffe9b1ab01830bc9255a64524c34b71c20a4affe5d1000b223a41698d/multidict-6.0.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d"}, {url = "https://files.pythonhosted.org/packages/0a/a1/a0446805d76fd6ada6de501c90520c963f8b5bf1f5a7a75ad80ba076897d/multidict-6.0.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87"}, @@ -2363,6 +2787,10 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/62/1e/a94a8d635fa3ce4cfc7f506003548d0a2447ae76fd5ca53932970fe3053f/pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"}, {url = "https://files.pythonhosted.org/packages/a4/db/fffec68299e6d7bad3d504147f9094830b704527a7fc098b721d38cc7fa7/pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"}, ] +"pyasn1-modules 0.3.0" = [ + {url = "https://files.pythonhosted.org/packages/3b/e4/7dec823b1b5603c5b3c51e942d5d9e65efd6ff946e713a325ed4146d070f/pyasn1_modules-0.3.0.tar.gz", hash = "sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c"}, + {url = "https://files.pythonhosted.org/packages/cd/8e/bea464350e1b8c6ed0da3a312659cb648804a08af6cacc6435867f74f8bd/pyasn1_modules-0.3.0-py2.py3-none-any.whl", hash = "sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d"}, +] "pycparser 2.21" = [ {url = "https://files.pythonhosted.org/packages/5e/0b/95d387f5f4433cb0f53ff7ad859bd2c6051051cebbb564f139a999ab46de/pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, {url = "https://files.pythonhosted.org/packages/62/d5/5f610ebe421e85889f2e55e33b7f9a6795bd982198517d912eb1c76e1a53/pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, @@ -2413,6 +2841,10 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/1c/fb/b82e9601b00d88cf8bbee1f39b855ae773f9d5bcbcedb3801b2f72460696/PyJWT-2.4.0-py3-none-any.whl", hash = "sha256:72d1d253f32dbd4f5c88eaf1fdc62f3a19f676ccbadb9dbc5d07e951b2b26daf"}, {url = "https://files.pythonhosted.org/packages/d8/6b/6287745054dbcccf75903630346be77d4715c594402cec7c2518032416c2/PyJWT-2.4.0.tar.gz", hash = "sha256:d42908208c699b3b973cbeb01a969ba6a96c821eefb1c5bfe4c390c01d67abba"}, ] +"pyopenssl 24.0.0" = [ + {url = "https://files.pythonhosted.org/packages/3f/0e/c6656e62d9424d9c9f14b27be27220602f4af1e64b77f2c86340b671d439/pyOpenSSL-24.0.0-py3-none-any.whl", hash = "sha256:ba07553fb6fd6a7a2259adb9b84e12302a9a8a75c44046e8bb5d3e5ee887e3c3"}, + {url = "https://files.pythonhosted.org/packages/eb/81/022190e5d21344f6110064f6f52bf0c3b9da86e9e5a64fc4a884856a577d/pyOpenSSL-24.0.0.tar.gz", hash = "sha256:6aa33039a93fffa4563e655b61d11364d01264be8ccb49906101e02a334530bf"}, +] "pyotp 2.8.0" = [ {url = "https://files.pythonhosted.org/packages/69/90/90c2b94fb8951ea3dce39dc43fdc62b328f6f665e6684b5149488e13d99b/pyotp-2.8.0-py3-none-any.whl", hash = "sha256:889d037fdde6accad28531fc62a790f089e5dfd5b638773e9ee004cce074a2e5"}, {url = "https://files.pythonhosted.org/packages/7e/f9/4c2ec78572a2d25f669220b8b9700c1133905ff6af9bf93c010778e82c65/pyotp-2.8.0.tar.gz", hash = "sha256:c2f5e17d9da92d8ec1f7de6331ab08116b9115adbabcba6e208d46fc49a98c5a"}, @@ -2511,8 +2943,11 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 ] "pyyaml 6.0.1" = [ {url = "https://files.pythonhosted.org/packages/02/74/b2320ebe006b6a521cf929c78f12a220b9db319b38165023623ed195654b/PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {url = "https://files.pythonhosted.org/packages/03/5c/c4671451b2f1d76ebe352c0945d4cd13500adb5d05f5a51ee296d80152f7/PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {url = "https://files.pythonhosted.org/packages/03/f7/4f8b71f3ce8cfb2c06e814aeda5b26ecc62ecb5cf85f5c8898be34e6eb6a/PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {url = "https://files.pythonhosted.org/packages/06/92/e0224aa6ebf9dc54a06a4609da37da40bb08d126f5535d81bff6b417b2ae/PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {url = "https://files.pythonhosted.org/packages/07/91/45dfd0ef821a7f41d9d0136ea3608bb5b1653e42fd56a7970532cb5c003f/PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {url = "https://files.pythonhosted.org/packages/0d/46/62ae77677e532c0af6c81ddd6f3dbc16bdcc1208b077457354442d220bfb/PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {url = "https://files.pythonhosted.org/packages/0e/88/21b2f16cb2123c1e9375f2c93486e35fdc86e63f02e274f0e99c589ef153/PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, {url = "https://files.pythonhosted.org/packages/1e/ae/964ccb88a938f20ece5754878f182cfbd846924930d02d29d06af8d4c69e/PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, {url = "https://files.pythonhosted.org/packages/24/62/7fcc372442ec8ea331da18c24b13710e010c5073ab851ef36bf9dacb283f/PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, @@ -2521,9 +2956,13 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/28/09/55f715ddbf95a054b764b547f617e22f1d5e45d83905660e9a088078fe67/PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, {url = "https://files.pythonhosted.org/packages/29/0f/9782fa5b10152abf033aec56a601177ead85ee03b57781f2d9fced09eefc/PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {url = "https://files.pythonhosted.org/packages/29/61/bf33c6c85c55bc45a29eee3195848ff2d518d84735eb0e2d8cb42e0d285e/PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {url = "https://files.pythonhosted.org/packages/2b/9f/fbade56564ad486809c27b322d0f7e6a89c01f6b4fe208402e90d4443a99/PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {url = "https://files.pythonhosted.org/packages/2e/97/3e0e089ee85e840f4b15bfa00e4e63d84a3691ababbfea92d6f820ea6f21/PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {url = "https://files.pythonhosted.org/packages/40/da/a175a35cf5583580e90ac3e2a3dbca90e43011593ae62ce63f79d7b28d92/PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {url = "https://files.pythonhosted.org/packages/41/9a/1c4c51f1a0d2b6fd805973701ab0ec84d5e622c5aaa573b0e1157f132809/PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, {url = "https://files.pythonhosted.org/packages/4a/4b/c71ef18ef83c82f99e6da8332910692af78ea32bd1d1d76c9787dfa36aea/PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {url = "https://files.pythonhosted.org/packages/4d/f1/08f06159739254c8947899c9fc901241614195db15ba8802ff142237664c/PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {url = "https://files.pythonhosted.org/packages/4f/78/77b40157b6cb5f2d3d31a3d9b2efd1ba3505371f76730d267e8b32cf4b7f/PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {url = "https://files.pythonhosted.org/packages/57/c5/5d09b66b41d549914802f482a2118d925d876dc2a35b2d127694c1345c34/PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, {url = "https://files.pythonhosted.org/packages/5b/07/10033a403b23405a8fc48975444463d3d10a5c2736b7eb2550b07b367429/PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, {url = "https://files.pythonhosted.org/packages/5e/94/7d5ee059dfb92ca9e62f4057dcdec9ac08a9e42679644854dc01177f8145/PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, @@ -2532,13 +2971,17 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/7b/5e/efd033ab7199a0b2044dab3b9f7a4f6670e6a52c089de572e928d2873b06/PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, {url = "https://files.pythonhosted.org/packages/7d/39/472f2554a0f1e825bd7c5afc11c817cd7a2f3657460f7159f691fbb37c51/PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, {url = "https://files.pythonhosted.org/packages/7f/5d/2779ea035ba1e533c32ed4a249b4e0448f583ba10830b21a3cddafe11a4e/PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {url = "https://files.pythonhosted.org/packages/84/02/404de95ced348b73dd84f70e15a41843d817ff8c1744516bf78358f2ffd2/PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, {url = "https://files.pythonhosted.org/packages/84/4d/82704d1ab9290b03da94e6425f5e87396b999fd7eb8e08f3a92c158402bf/PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {url = "https://files.pythonhosted.org/packages/96/06/4beb652c0fe16834032e54f0956443d4cc797fe645527acee59e7deaa0a2/PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, {url = "https://files.pythonhosted.org/packages/ac/6c/967d91a8edf98d2b2b01d149bd9e51b8f9fb527c98d80ebb60c6b21d60c4/PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {url = "https://files.pythonhosted.org/packages/b3/34/65bb4b2d7908044963ebf614fe0fdb080773fc7030d7e39c8d3eddcd4257/PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {url = "https://files.pythonhosted.org/packages/b4/33/720548182ffa8344418126017aa1d4ab4aeec9a2275f04ce3f3573d8ace8/PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {url = "https://files.pythonhosted.org/packages/b6/a0/b6700da5d49e9fed49dc3243d3771b598dad07abb37cc32e524607f96adc/PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {url = "https://files.pythonhosted.org/packages/ba/91/090818dfa62e85181f3ae23dd1e8b7ea7f09684864a900cab72d29c57346/PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {url = "https://files.pythonhosted.org/packages/bc/06/1b305bf6aa704343be85444c9d011f626c763abb40c0edc1cad13bfd7f86/PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {url = "https://files.pythonhosted.org/packages/c1/39/47ed4d65beec9ce07267b014be85ed9c204fa373515355d3efa62d19d892/PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {url = "https://files.pythonhosted.org/packages/c7/4c/4a2908632fc980da6d918b9de9c1d9d7d7e70b2672b1ad5166ed27841ef7/PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {url = "https://files.pythonhosted.org/packages/c7/d1/02baa09d39b1bb1ebaf0d850d106d1bdcb47c91958557f471153c49dc03b/PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, {url = "https://files.pythonhosted.org/packages/c8/6b/6600ac24725c7388255b2f5add93f91e58a5d7efaf4af244fdbcc11a541b/PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, {url = "https://files.pythonhosted.org/packages/cc/5c/fcabd17918348c7db2eeeb0575705aaf3f7ab1657f6ce29b2e31737dd5d1/PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, @@ -2551,6 +2994,10 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/f1/26/55e4f21db1f72eaef092015d9017c11510e7e6301c62a6cfee91295d13c6/PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {url = "https://files.pythonhosted.org/packages/fe/88/def2e57fe740544f2eefb1645f1d6e0094f56c00f4eade708140b6137ead/PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, ] +"redis 5.0.1" = [ + {url = "https://files.pythonhosted.org/packages/0b/34/a01250ac1fc9bf9161e07956d2d580413106ce02d5591470130a25c599e3/redis-5.0.1-py3-none-any.whl", hash = "sha256:ed4802971884ae19d640775ba3b03aa2e7bd5e8fb8dfaed2decce4d0fc48391f"}, + {url = "https://files.pythonhosted.org/packages/4a/4c/3c3b766f4ecbb3f0bec91ef342ee98d179e040c25b6ecc99e510c2570f2a/redis-5.0.1.tar.gz", hash = "sha256:0dab495cd5753069d3bc650a0dde8a8f9edde16fc5691b689a566eda58100d0f"}, +] "requests 2.28.2" = [ {url = "https://files.pythonhosted.org/packages/9d/ee/391076f5937f0a8cdf5e53b701ffc91753e87b07d66bae4a09aa671897bf/requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"}, {url = "https://files.pythonhosted.org/packages/d2/f4/274d1dbe96b41cf4e0efb70cbced278ffd61b5c7bb70338b62af94ccb25b/requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"}, @@ -2602,6 +3049,10 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/06/fa/cfc43276f3221006d861bf7e66d7361a47106121df65947fd3225793d845/sentry_sdk-1.14.0-py2.py3-none-any.whl", hash = "sha256:72c00322217d813cf493fe76590b23a757e063ff62fec59299f4af7201dd4448"}, {url = "https://files.pythonhosted.org/packages/d3/64/a5e0b77e834bec753927853accef256f86e0c2695ed5d16a2048fe790679/sentry-sdk-1.14.0.tar.gz", hash = "sha256:273fe05adf052b40fd19f6d4b9a5556316807246bd817e5e3482930730726bb0"}, ] +"service-identity 24.1.0" = [ + {url = "https://files.pythonhosted.org/packages/38/d2/2ac20fd05f1b6fce31986536da4caeac51ed2e1bb25d4a7d73ca4eccdfab/service_identity-24.1.0.tar.gz", hash = "sha256:6829c9d62fb832c2e1c435629b0a8c476e1929881f28bee4d20bc24161009221"}, + {url = "https://files.pythonhosted.org/packages/3b/92/44669afe6354a7bed9968013862118c401690d8b5a805bab75ac1764845f/service_identity-24.1.0-py3-none-any.whl", hash = "sha256:a28caf8130c8a5c1c7a6f5293faaf239bbfb7751e4862436920ee6f2616f568a"}, +] "setuptools 63.2.0" = [ {url = "https://files.pythonhosted.org/packages/0a/ba/52611dc8278828eb9ec339e6914a0f865f9e2af967214905927835dfac0a/setuptools-63.2.0.tar.gz", hash = "sha256:c04b44a57a6265fe34a4a444e965884716d34bae963119a76353434d6f18e450"}, {url = "https://files.pythonhosted.org/packages/a4/53/bfc6409447ca024558b8b19d055de94c813c3e32c0296c48a0873a161cf5/setuptools-63.2.0-py3-none-any.whl", hash = "sha256:0d33c374d41c7863419fc8f6c10bfe25b7b498aa34164d135c622e52580c6b16"}, @@ -2610,6 +3061,10 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, {url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, ] +"sniffio 1.3.0" = [ + {url = "https://files.pythonhosted.org/packages/c3/a0/5dba8ed157b0136607c7f2151db695885606968d1fae123dc3391e0cfdbf/sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, + {url = "https://files.pythonhosted.org/packages/cd/50/d49c388cae4ec10e8109b1b833fd265511840706808576df3ada99ecb0ac/sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, +] "social-auth-app-django 5.0.0" = [ {url = "https://files.pythonhosted.org/packages/08/00/fe5049b9fdcb8cd829eba30b068a311590722a91a576304b267e084aaeca/social_auth_app_django-5.0.0-py3-none-any.whl", hash = "sha256:52241a25445a010ab1c108bafff21fc5522d5c8cd0d48a92c39c7371824b065d"}, {url = "https://files.pythonhosted.org/packages/27/3f/3bf9e031e43874def4f8bf3576c8b27e314aef493425741c35786fb9f07f/social-auth-app-django-5.0.0.tar.gz", hash = "sha256:b6e3132ce087cdd6e1707aeb1b588be41d318408fcf6395435da0bc6fe9a9795"}, @@ -2649,6 +3104,35 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/3d/78/81191f56abb7d3d56963337dbdff6aa4f55805c8afd8bad64b0a34199e9b/tqdm-4.65.0.tar.gz", hash = "sha256:1871fb68a86b8fb3b59ca4cdd3dcccbc7e6d613eeed31f4c332531977b89beb5"}, {url = "https://files.pythonhosted.org/packages/e6/02/a2cff6306177ae6bc73bc0665065de51dfb3b9db7373e122e2735faf0d97/tqdm-4.65.0-py3-none-any.whl", hash = "sha256:c4f53a17fe37e132815abceec022631be8ffe1b9381c2e6e30aa70edc99e9671"}, ] +"twisted 23.10.0" = [ + {url = "https://files.pythonhosted.org/packages/24/83/8d34d264c72d5450cd3d3ef31c885bb36b94635aa8e9e223581793d9d6c8/twisted-23.10.0-py3-none-any.whl", hash = "sha256:4ae8bce12999a35f7fe6443e7f1893e6fe09588c8d2bed9c35cdce8ff2d5b444"}, + {url = "https://files.pythonhosted.org/packages/6e/d3/077ece8f12cd82419bd68bb34cf4538c4df5bb9202835e7a18358223e537/twisted-23.10.0.tar.gz", hash = "sha256:987847a0790a2c597197613686e2784fd54167df3a55d0fb17c8412305d76ce5"}, +] +"twisted-iocpsupport 1.0.4" = [ + {url = "https://files.pythonhosted.org/packages/0f/ae/f424359008c20466be4a9ea10c05bfd9a025f3b368c520d7832d21ee85f6/twisted_iocpsupport-1.0.4-cp36-cp36m-win_amd64.whl", hash = "sha256:391ac4d6002a80e15f35adc4ad6056f4fe1c17ceb0d1f98ba01b0f4f917adfd7"}, + {url = "https://files.pythonhosted.org/packages/32/e9/809380cfe345228c44509a81044939eb293c92a51aa39cdf2c5b6b1e10cd/twisted_iocpsupport-1.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7c66fa0aa4236b27b3c61cb488662d85dae746a6d1c7b0d91cf7aae118445adf"}, + {url = "https://files.pythonhosted.org/packages/37/f9/0a3a11c53ad9ca9742ae16aa0d1a80b13279fc4cba8cc977caa10e0acc6b/twisted_iocpsupport-1.0.4-cp37-cp37m-win32.whl", hash = "sha256:0c1b5cf37f0b2d96cc3c9bc86fff16613b9f5d0ca565c96cf1f1fb8cfca4b81c"}, + {url = "https://files.pythonhosted.org/packages/3e/8a/93c4da574f12ebce19dec4e8afa8b5a3e65ad468e45272dc8882b1d78f4d/twisted_iocpsupport-1.0.4-cp38-cp38-win32.whl", hash = "sha256:cc86c2ef598c15d824a243c2541c29459881c67fc3c0adb6efe2242f8f0ec3af"}, + {url = "https://files.pythonhosted.org/packages/3e/8c/e1a5a5a4f2362bdb21cb13d86aae86ecd0dbbdd14c3b65fc722e0f71db26/twisted_iocpsupport-1.0.4-cp36-cp36m-win32.whl", hash = "sha256:3d306fc4d88a6bcf61ce9d572c738b918578121bfd72891625fab314549024b5"}, + {url = "https://files.pythonhosted.org/packages/5b/e4/54819582c7852295188427c49526da79c9b884253ac7ce9d74b51b6be181/twisted_iocpsupport-1.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:4e5f97bcbabdd79cbaa969b63439b89801ea560f11d42b0a387634275c633623"}, + {url = "https://files.pythonhosted.org/packages/61/00/d6a930ffb3e163f030d71474aa04623e780e18a00578b302dfbf92270b9c/twisted_iocpsupport-1.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:300437af17396a945a58dcfffd77863303a8b6d9e65c6e81f1d2eed55b50d444"}, + {url = "https://files.pythonhosted.org/packages/ac/fd/172697cff2cd365e8dd716c28b4fe81dbdb667c3d3a1d9f21c84db1fea2e/twisted_iocpsupport-1.0.4-cp310-cp310-win32.whl", hash = "sha256:afa2b630797f9ed2f27f3d9f55e3f72b4244911e45a8c82756f44babbf0b243e"}, + {url = "https://files.pythonhosted.org/packages/b1/2e/d99419d50e883efe30f8d17c0851307671058561643ba2d73f4f2873af97/twisted_iocpsupport-1.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:0058c963c8957bcd3deda62122e89953c9de1e867a274facc9b15dde1a9f31e8"}, + {url = "https://files.pythonhosted.org/packages/cb/73/7276c607641343b3be15021a388a9378ac579a3508169f7a52c0942ea6e8/twisted_iocpsupport-1.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:4574eef1f3bb81501fb02f911298af3c02fe8179c31a33b361dd49180c3e644d"}, + {url = "https://files.pythonhosted.org/packages/cc/ad/a88250f2933c5ad8170d4ee3688a8b6ac4d8c097ff136be8db790ae2b920/twisted_iocpsupport-1.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:c27985e949b9b1a1fb4c20c71d315c10ea0f93fdf3ccdd4a8c158b5926edd8c8"}, + {url = "https://files.pythonhosted.org/packages/d4/17/959577f760914d97d5039dbca28aa9041c6231ab50b1f9682987739a7d58/twisted_iocpsupport-1.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:3c5dc11d72519e55f727320e3cee535feedfaee09c0f0765ed1ca7badff1ab3c"}, + {url = "https://files.pythonhosted.org/packages/d8/2e/18667b59a33dbe1075922aefcf669ce6ffeab161ed985a4a62fd4457de99/twisted_iocpsupport-1.0.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:872747a3b64e2909aee59c803ccd0bceb9b75bf27915520ebd32d69687040fa2"}, + {url = "https://files.pythonhosted.org/packages/e1/9d/b223c791d14a502d8d4c4405add78c6189f68506fdc43f3c2a6183efb7b4/twisted_iocpsupport-1.0.4-cp312-cp312-win32.whl", hash = "sha256:6081bd7c2f4fcf9b383dcdb3b3385d75a26a7c9d2be25b6950c3d8ea652d2d2d"}, + {url = "https://files.pythonhosted.org/packages/e3/76/8fcee4cb913b9d085a32679d7712258fe6601d8e786728a72b2f83999fef/twisted_iocpsupport-1.0.4-cp39-cp39-win32.whl", hash = "sha256:e311dfcb470696e3c077249615893cada598e62fa7c4e4ca090167bd2b7d331f"}, + {url = "https://files.pythonhosted.org/packages/e3/92/06be6fe2600d63bd268b3b6a3f4f4b9e5ff9ee8169b426adb906dabf3fb1/twisted_iocpsupport-1.0.4-cp311-cp311-win32.whl", hash = "sha256:196f7c7ccad4ba4d1783b1c4e1d1b22d93c04275cd780bf7498d16c77319ad6e"}, + {url = "https://files.pythonhosted.org/packages/f3/35/f18bd75e29f7d887e918a9401e0aa66c10634861561fc085d197a738759f/twisted-iocpsupport-1.0.4.tar.gz", hash = "sha256:858096c0d15e33f15ac157f455d8f86f2f2cdd223963e58c0f682a3af8362d89"}, + {url = "https://files.pythonhosted.org/packages/f3/9d/3813cd573dff68426e0ab0f9f47c7876dd9d98238e55aefa019c89c400b9/twisted_iocpsupport-1.0.4-cp312-cp312-win_amd64.whl", hash = "sha256:76f7e67cec1f1d097d1f4ed7de41be3d74546e1a4ede0c7d56e775c4dce5dfb0"}, + {url = "https://files.pythonhosted.org/packages/ff/dc/4aeb36689fc78987b85352033ebd425f023dc92108b58cc0cb12c161f377/twisted_iocpsupport-1.0.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:c2712b778bacf1db434e3e065adfed3db300754186a29aecac1efae9ef4bcaff"}, +] +"txaio 23.1.1" = [ + {url = "https://files.pythonhosted.org/packages/51/91/bc9fd5aa84703f874dea27313b11fde505d343f3ef3ad702bddbe20bfd6e/txaio-23.1.1.tar.gz", hash = "sha256:f9a9216e976e5e3246dfd112ad7ad55ca915606b60b84a757ac769bd404ff704"}, + {url = "https://files.pythonhosted.org/packages/7d/6c/a53cc9a97c2da76d9cd83c03f377468599a28f2d4ad9fc71c3b99640e71e/txaio-23.1.1-py2.py3-none-any.whl", hash = "sha256:aaea42f8aad50e0ecfb976130ada140797e9dcb85fad2cf72b0f37f8cefcb490"}, +] "typeapi 2.1.1" = [ {url = "https://files.pythonhosted.org/packages/2c/91/344b3fc06748f88a41f81e3a479b36835cd510649de53d69327358654cc7/typeapi-2.1.1-py3-none-any.whl", hash = "sha256:ef41577f316bfd362572e727ba349dab80a7362318a80fc72e6a807017d04c5c"}, {url = "https://files.pythonhosted.org/packages/58/e9/134b4338178e734d896344519b305c86f6bddefc5dedcc221523e94884fc/typeapi-2.1.1.tar.gz", hash = "sha256:49b3c1d3382e27dccbb59132a3a823c61954f679a0c61f119fd6d8470073a298"}, @@ -2669,6 +3153,43 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/c5/52/fe421fb7364aa738b3506a2d99e4f3a56e079c0a798e9f4fa5e14c60922f/urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"}, {url = "https://files.pythonhosted.org/packages/fe/ca/466766e20b767ddb9b951202542310cba37ea5f2d792dae7589f1741af58/urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"}, ] +"uvicorn 0.27.1" = [ + {url = "https://files.pythonhosted.org/packages/09/d8/8aa69c76585035ca81851d99c3b00fd6be050aefd478a5376ff9fc5feb69/uvicorn-0.27.1.tar.gz", hash = "sha256:3d9a267296243532db80c83a959a3400502165ade2c1338dea4e67915fd4745a"}, + {url = "https://files.pythonhosted.org/packages/d9/fd/bac111726b6c651f1fa5563145ecba5ff70d36fb140a55e0d79b60b9d65e/uvicorn-0.27.1-py3-none-any.whl", hash = "sha256:5c89da2f3895767472a35556e539fd59f7edbe9b1e9c0e1c99eebeadc61838e4"}, +] +"uvloop 0.19.0" = [ + {url = "https://files.pythonhosted.org/packages/04/58/4d12d24220f2bf2c3125c74431035ddd7a461f9732a01cd5bd12f177370e/uvloop-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256"}, + {url = "https://files.pythonhosted.org/packages/0f/7f/6497008441376686f962a57de57897654ebd9c80f993b619ab57bc4ae61d/uvloop-0.19.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e3d4e85ac060e2342ff85e90d0c04157acb210b9ce508e784a944f852a40e67"}, + {url = "https://files.pythonhosted.org/packages/12/9d/f1d263d49f1909914bcec5d5608d2f819c109b08bf06e67a2ff072e82d81/uvloop-0.19.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2df95fca285a9f5bfe730e51945ffe2fa71ccbfdde3b0da5772b4ee4f2e770d5"}, + {url = "https://files.pythonhosted.org/packages/13/00/d0923d66d80c8717983493a4d7af747ce47f1c2147d82df057a846ba6bff/uvloop-0.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2"}, + {url = "https://files.pythonhosted.org/packages/13/b6/a5cb14acb1417c1660d722c554757e134462f09eb917e6c49907d990d63a/uvloop-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271718e26b3e17906b28b67314c45d19106112067205119dddbd834c2b7ce797"}, + {url = "https://files.pythonhosted.org/packages/1b/4e/fe0b1d09648eebe7dec5c7de66631b814ef442ce896cce63ded5c1e8c275/uvloop-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45bf4c24c19fb8a50902ae37c5de50da81de4922af65baf760f7c0c42e1088be"}, + {url = "https://files.pythonhosted.org/packages/1e/f9/8de4d58175c7a5cf3731fcfc43e7fb93e0972a098bffdc926507f02cd655/uvloop-0.19.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13dfdf492af0aa0a0edf66807d2b465607d11c4fa48f4a1fd41cbea5b18e8e8b"}, + {url = "https://files.pythonhosted.org/packages/1f/c7/e494c367b0c6e6453f9bed5a78548f5b2ff49add36302cd915a91d347d88/uvloop-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1"}, + {url = "https://files.pythonhosted.org/packages/36/c2/27bf858a576b1fa35b5c2c2029c8cec424a8789e87545ed2f25466d1f21d/uvloop-0.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e"}, + {url = "https://files.pythonhosted.org/packages/41/2a/608ad69f27f51280098abee440c33e921d3ad203e2c86f7262e241e49c99/uvloop-0.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef"}, + {url = "https://files.pythonhosted.org/packages/49/54/c653529077d7dd2455e9af44b621ad1f8bb2f0bcd232f8a599017e84fc54/uvloop-0.19.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:78ab247f0b5671cc887c31d33f9b3abfb88d2614b84e4303f1a63b46c046c8bd"}, + {url = "https://files.pythonhosted.org/packages/4d/81/67afeb6da202313e1a5368e36bffdedb7939acf22d969d83183d4f43c4ff/uvloop-0.19.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:472d61143059c84947aa8bb74eabbace30d577a03a1805b77933d6bd13ddebbd"}, + {url = "https://files.pythonhosted.org/packages/4e/35/05b6064b93f4113412d1fd92bdcb6018607e78ae94d1712e63e533f9b2fa/uvloop-0.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428"}, + {url = "https://files.pythonhosted.org/packages/6b/23/1ee41a15e1ad15182e2bd12cbfd37bcb6802f01d6bbcaddf6ca136cbb308/uvloop-0.19.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd"}, + {url = "https://files.pythonhosted.org/packages/71/bc/092068ae7fc16dcf20f3e389126ba7800cee75ffba83f78bf1d167aee3cd/uvloop-0.19.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593"}, + {url = "https://files.pythonhosted.org/packages/7a/4c/ca87e8f5a30629ffa2038c20907c8ab455c5859ff10e810227b76e60d927/uvloop-0.19.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533"}, + {url = "https://files.pythonhosted.org/packages/81/a1/7383219c1855a65b988d16e2b8dc0ac8a646ee7429e358a78ab9074c9ddf/uvloop-0.19.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7"}, + {url = "https://files.pythonhosted.org/packages/84/8d/3e23cb85cc2c12918a6d7585fdf50a05c69191a4969881e22e0eebcbf686/uvloop-0.19.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:492e2c32c2af3f971473bc22f086513cedfc66a130756145a931a90c3958cb17"}, + {url = "https://files.pythonhosted.org/packages/85/57/6736733bb0e86a4b5380d04082463b289c0baecaa205934ba81e8a1d5ea4/uvloop-0.19.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650"}, + {url = "https://files.pythonhosted.org/packages/86/cc/1829b3f740e4cb1baefff8240a1c6fc8db9e3caac7b93169aec7d4386069/uvloop-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24"}, + {url = "https://files.pythonhosted.org/packages/9c/16/728cc5dde368e6eddb299c5aec4d10eaf25335a5af04e8c0abd68e2e9d32/uvloop-0.19.0.tar.gz", hash = "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd"}, + {url = "https://files.pythonhosted.org/packages/a2/23/80381a2d728d2a0c36e2eef202f5b77428990004d8fbdd3865558ff49fa5/uvloop-0.19.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957"}, + {url = "https://files.pythonhosted.org/packages/a6/f2/6ce1e73933eb038c89f929e26042e64b2cb8d4453410153eed14918ca9a8/uvloop-0.19.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3"}, + {url = "https://files.pythonhosted.org/packages/aa/56/b62ab4e10458ce96bb30c98d327c127f989d3bb4ef899e4c410c739f7ef6/uvloop-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8"}, + {url = "https://files.pythonhosted.org/packages/ab/ed/12729fba5e3b7e02ee70b3ea230b88e60a50375cf63300db22607694d2f0/uvloop-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849"}, + {url = "https://files.pythonhosted.org/packages/d2/a9/f947a00c47b1c87c937cac2423243a41ba08f0fb76d04eb0d1d170606e0a/uvloop-0.19.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12"}, + {url = "https://files.pythonhosted.org/packages/e1/90/6dfe0ef6bc9a5cb72eff6f6bf77f613b27648229f7ad7f7f27b118dde973/uvloop-0.19.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:34175c9fd2a4bc3adc1380e1261f60306344e3407c20a4d684fd5f3be010fa3d"}, + {url = "https://files.pythonhosted.org/packages/e6/fc/f0daaf19f5b2116a2d26eb9f98c4a45084aea87bf03c33bcca7aa1ff36e5/uvloop-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc"}, + {url = "https://files.pythonhosted.org/packages/eb/0c/51339463da912ed34b48d470538d98a91660749b2db56902f23db9b42fdd/uvloop-0.19.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec"}, + {url = "https://files.pythonhosted.org/packages/fd/96/fdc318ffe82ae567592b213ec2fcd8ecedd927b5da068cf84d56b28c51a4/uvloop-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6"}, + {url = "https://files.pythonhosted.org/packages/fe/4d/199e8c6e4a810b60cc012f9dc34fcf4df0e93d927de75ce4ed54a4d36274/uvloop-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ca4956c9ab567d87d59d49fa3704cf29e37109ad348f2d5223c9bf761a332e7"}, +] "watchdog 2.3.1" = [ {url = "https://files.pythonhosted.org/packages/05/72/b7d506e9a67ade08cc9f5b79f6191e8c2ef8eafcae20b8f6d1f84c65ce8d/watchdog-2.3.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ea5d86d1bcf4a9d24610aa2f6f25492f441960cf04aed2bd9a97db439b643a7b"}, {url = "https://files.pythonhosted.org/packages/15/ab/8fe9a2d0aab954b6669e1c500131782704b2653ece48c9dacb982cc601fe/watchdog-2.3.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:03f342a9432fe08107defbe8e405a2cb922c5d00c4c6c168c68b633c64ce6190"}, @@ -2699,10 +3220,161 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/f4/e4/a6270a3c28872d46e53cbae034715ff80c18856167091f548aa93ad2d92b/watchdog-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:964fd236cd443933268ae49b59706569c8b741073dbfd7ca705492bae9d39aab"}, {url = "https://files.pythonhosted.org/packages/fb/3a/ad9bf1927f344bbd161359d22771020748c4c82ea4dd45abcfe46e084655/watchdog-2.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1f1200d4ec53b88bf04ab636f9133cb703eb19768a39351cee649de21a33697"}, ] +"watchfiles 0.21.0" = [ + {url = "https://files.pythonhosted.org/packages/02/94/49ccb19250533099792bed3f08849dbf37d1762655b873d4b444dd3bdb51/watchfiles-0.21.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3ad692bc7792be8c32918c699638b660c0de078a6cbe464c46e1340dadb94c19"}, + {url = "https://files.pythonhosted.org/packages/03/27/9386a4dff4fc415dd072c1d15f2cb995845aaa15029196c36f2449bd7e12/watchfiles-0.21.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43babacef21c519bc6631c5fce2a61eccdfc011b4bcb9047255e9620732c8097"}, + {url = "https://files.pythonhosted.org/packages/04/ea/682d7ce1bdab35908355bf71f7c30d8dbf8fc1cf2259bc4bd4b9917869ee/watchfiles-0.21.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c6ed10c2497e5fedadf61e465b3ca12a19f96004c15dcffe4bd442ebadc2d85"}, + {url = "https://files.pythonhosted.org/packages/05/4f/afb1de71928d550c714d5e204e4de542501c3e427c8ec3d7284c0b255c58/watchfiles-0.21.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c889025f59884423428c261f212e04d438de865beda0b1e1babab85ef4c0f01"}, + {url = "https://files.pythonhosted.org/packages/0b/13/f3d06bb94c13d9cf8e49cc4a9ee50953cdd84053b58049091ff618b6c6bb/watchfiles-0.21.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:853853cbf7bf9408b404754b92512ebe3e3a83587503d766d23e6bf83d092ee6"}, + {url = "https://files.pythonhosted.org/packages/0d/67/ceaec64dfb20b39b8e70bc99334fe384d5fd60605ad892efe0d210b43f42/watchfiles-0.21.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06247538e8253975bdb328e7683f8515ff5ff041f43be6c40bff62d989b7d0b0"}, + {url = "https://files.pythonhosted.org/packages/0e/cf/126f0a8683f326d190c3539a769e45e747a80a5fcbf797de82e738c946ae/watchfiles-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11cd0c3100e2233e9c53106265da31d574355c288e15259c0d40a4405cbae317"}, + {url = "https://files.pythonhosted.org/packages/14/d0/662800e778ca20e7664dd5df57751aa79ef18b6abb92224b03c8c2e852a6/watchfiles-0.21.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d0f32ebfaa9c6011f8454994f86108c2eb9c79b8b7de00b36d558cadcedaa3d"}, + {url = "https://files.pythonhosted.org/packages/18/c4/ad5ad16cad900a29aaa792e0ed121ff70d76f74062b051661090d88c6dfd/watchfiles-0.21.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5eb86c6acb498208e7663ca22dbe68ca2cf42ab5bf1c776670a50919a56e64ab"}, + {url = "https://files.pythonhosted.org/packages/1b/36/6de490cc56af5a0e24f3d7ccf3c05a7a8624cdf5e163ae290fe09cbc0fc5/watchfiles-0.21.0-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:4ea10a29aa5de67de02256a28d1bf53d21322295cb00bd2d57fcd19b850ebd99"}, + {url = "https://files.pythonhosted.org/packages/1b/a1/9c5e36d5df5c2b7371c03f46d244ef9c4b4ca3ab2df4c9ffdc41bbc4904e/watchfiles-0.21.0-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:7f762a1a85a12cc3484f77eee7be87b10f8c50b0b787bb02f4e357403cad0c0e"}, + {url = "https://files.pythonhosted.org/packages/1c/3a/4e38518c4dff58090c01fc8cc051fa08ac9ae00b361c855075809b0058ce/watchfiles-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b8d1eae0f65441963d805f766c7e9cd092f91e0c600c820c764a4ff71a0764c"}, + {url = "https://files.pythonhosted.org/packages/20/6e/6cffd795ec65dbc82f15d95b73d3042c1ddaffc4dd25f6c8240bfcf0640f/watchfiles-0.21.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78f30cbe8b2ce770160d3c08cff01b2ae9306fe66ce899b73f0409dc1846c1b"}, + {url = "https://files.pythonhosted.org/packages/22/15/e4085181cf0210a6ec6eb29fee0c6088de867ee33d81555076a4a2726e8b/watchfiles-0.21.0-cp311-none-win_arm64.whl", hash = "sha256:c550a56bf209a3d987d5a975cdf2063b3389a5d16caf29db4bdddeae49f22078"}, + {url = "https://files.pythonhosted.org/packages/26/b2/37a838aecc760f8fd219b053a0c6b2bbe536aa2b5a7795206d7e2d16fa3f/watchfiles-0.21.0-cp38-none-win_amd64.whl", hash = "sha256:8d5f400326840934e3507701f9f7269247f7c026d1b6cfd49477d2be0933cfca"}, + {url = "https://files.pythonhosted.org/packages/2c/c8/d9cc95f365019b21d0500bc38805d9789017c441feba823d52490a8b0b3a/watchfiles-0.21.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:08dca260e85ffae975448e344834d765983237ad6dc308231aa16e7933db763e"}, + {url = "https://files.pythonhosted.org/packages/2d/ba/a3f83f19be619ebaef5bb2da934b66e6e3d376adfaa7117dce77d7ef1119/watchfiles-0.21.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:66fac0c238ab9a2e72d026b5fb91cb902c146202bbd29a9a1a44e8db7b710b6f"}, + {url = "https://files.pythonhosted.org/packages/31/b0/7994140859df017a00b63330299e2e48b472dbc721052bb243884a65ac79/watchfiles-0.21.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d353c4cfda586db2a176ce42c88f2fc31ec25e50212650c89fdd0f560ee507b"}, + {url = "https://files.pythonhosted.org/packages/35/e0/e8a9c1fe30e98c5b3507ad381abc4d9ee2c3b9c0ae62ffe9c164a5838186/watchfiles-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c873345680c1b87f1e09e0eaf8cf6c891b9851d8b4d3645e7efe2ec20a20cc7"}, + {url = "https://files.pythonhosted.org/packages/36/2a/6e91ce9b251e615cd672d35ede3a67a3ccd3734beaf3c1706134b2cc98e3/watchfiles-0.21.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b3cab0e06143768499384a8a5efb9c4dc53e19382952859e4802f294214f36ec"}, + {url = "https://files.pythonhosted.org/packages/37/17/4825999346f15d650f4c69093efa64fb040fbff4f706a20e8c4745f64070/watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd467213195e76f838caf2c28cd65e58302d0254e636e7c0fca81efa4a2e62c"}, + {url = "https://files.pythonhosted.org/packages/41/0e/3333b986b1889bb71f0e44b3fac0591824a679619b8b8ddd70ff8858edc4/watchfiles-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d9ac347653ebd95839a7c607608703b20bc07e577e870d824fa4801bc1cb124"}, + {url = "https://files.pythonhosted.org/packages/4b/ea/80527adf1ad51488a96fc201715730af5879f4dfeccb5e2069ff82d890d4/watchfiles-0.21.0-cp310-none-win_amd64.whl", hash = "sha256:1ad7247d79f9f55bb25ab1778fd47f32d70cf36053941f07de0b7c4e96b5d235"}, + {url = "https://files.pythonhosted.org/packages/4e/d2/769254ff04ba88ceb179a6e892606ac4da17338eb010e85ca7a9c3339234/watchfiles-0.21.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f564bf68404144ea6b87a78a3f910cc8de216c6b12a4cf0b27718bf4ec38d303"}, + {url = "https://files.pythonhosted.org/packages/57/b9/2667286003dd305b81d3a3aa824d3dfc63dacbf2a96faae09e72d953c430/watchfiles-0.21.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:668c265d90de8ae914f860d3eeb164534ba2e836811f91fecc7050416ee70aa7"}, + {url = "https://files.pythonhosted.org/packages/5a/a5/7aba9435beb863c2490bae3173a45f42044ac7a48155d3dd42ab49cfae45/watchfiles-0.21.0-cp312-none-win_arm64.whl", hash = "sha256:a3b9bec9579a15fb3ca2d9878deae789df72f2b0fdaf90ad49ee389cad5edab6"}, + {url = "https://files.pythonhosted.org/packages/5a/da/a90cce0c50af00cf7c09a3ccfe92406d3222745ab3c4da6a110a27216d4e/watchfiles-0.21.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d5b1dc0e708fad9f92c296ab2f948af403bf201db8fb2eb4c8179db143732e49"}, + {url = "https://files.pythonhosted.org/packages/5b/79/ecd0dfb04443a1900cd3952d7ea6493bf655c2db9a0d3736a5d98a15da39/watchfiles-0.21.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6c107ea3cf2bd07199d66f156e3ea756d1b84dfd43b542b2d870b77868c98c03"}, + {url = "https://files.pythonhosted.org/packages/5d/12/e1d1d220c5b99196eea38c9a878964f30a2b55ec9d72fd713191725b35e8/watchfiles-0.21.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e7941bbcfdded9c26b0bf720cb7e6fd803d95a55d2c14b4bd1f6a2772230c586"}, + {url = "https://files.pythonhosted.org/packages/5d/f4/84841ee14a1717e58674a77d4098ccfc18f76a10f4ec7700062de7ac89ee/watchfiles-0.21.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f57c4461cd24fda22493109c45b3980863c58a25b8bec885ca8bea6b8d4b28"}, + {url = "https://files.pythonhosted.org/packages/5f/f1/22139d0c79e6b95e64ea3beb554de3b4a4b5028e91a1e444fbb8ea2b73b7/watchfiles-0.21.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:83a696da8922314ff2aec02987eefb03784f473281d740bf9170181829133765"}, + {url = "https://files.pythonhosted.org/packages/62/66/7463ceb43eabc6deaa795c7969ff4d4fd938de54e655035483dfd1e97c84/watchfiles-0.21.0-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ab03a90b305d2588e8352168e8c5a1520b721d2d367f31e9332c4235b30b8994"}, + {url = "https://files.pythonhosted.org/packages/66/79/0ee412e1228aaf6f9568aa180b43cb482472de52560fbd7c283c786534af/watchfiles-0.21.0.tar.gz", hash = "sha256:c76c635fabf542bb78524905718c39f736a98e5ab25b23ec6d4abede1a85a6a3"}, + {url = "https://files.pythonhosted.org/packages/69/0e/29f158fa22eb2cc1f188b5ec20fb5c0a64eb801e3901ad5b7ad546cbaed0/watchfiles-0.21.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cfb92d49dbb95ec7a07511bc9efb0faff8fe24ef3805662b8d6808ba8409a71a"}, + {url = "https://files.pythonhosted.org/packages/69/b6/ccf285a6f82daf072717d7aaef71e7ec7f2b6ed858bedf332c06f86cec02/watchfiles-0.21.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:be6dd5d52b73018b21adc1c5d28ac0c68184a64769052dfeb0c5d9998e7f56a2"}, + {url = "https://files.pythonhosted.org/packages/6b/4c/b741eb38f2c408ae9c5a25235f6506b1dda43486ae0fdb4c462ef75bce11/watchfiles-0.21.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a1e3014a625bcf107fbf38eece0e47fa0190e52e45dc6eee5a8265ddc6dc5ea7"}, + {url = "https://files.pythonhosted.org/packages/6e/85/ea2a035b7d86bf0a29ee1c32bc2df8ad4da77e6602806e679d9735ff28cb/watchfiles-0.21.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:27b4035013f1ea49c6c0b42d983133b136637a527e48c132d368eb19bf1ac6aa"}, + {url = "https://files.pythonhosted.org/packages/70/76/8d124e14cf51af4d6bba926c7473f253c6efd1539ba62577f079a2d71537/watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02b73130687bc3f6bb79d8a170959042eb56eb3a42df3671c79b428cd73f17cc"}, + {url = "https://files.pythonhosted.org/packages/77/e4/8d2b3c67364671b0e1c0ce383895a5415f45ecb3e8586982deff4a8e85c9/watchfiles-0.21.0-cp312-none-win32.whl", hash = "sha256:9d09869f2c5a6f2d9df50ce3064b3391d3ecb6dced708ad64467b9e4f2c9bef3"}, + {url = "https://files.pythonhosted.org/packages/79/24/eb297bfe2c4909f861f637e5a6daeb6d7d0f5d5a0379e18a53403823556e/watchfiles-0.21.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ad3fe0a3567c2f0f629d800409cd528cb6251da12e81a1f765e5c5345fd0137"}, + {url = "https://files.pythonhosted.org/packages/83/94/5be4f7c3ef32cd5869fb6f18ed44fc7250d81b306ece869573f856fa39e4/watchfiles-0.21.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9b37a7ba223b2f26122c148bb8d09a9ff312afca998c48c725ff5a0a632145f7"}, + {url = "https://files.pythonhosted.org/packages/8c/28/14934a760698d493cc2065481639445fac172bda894d4727f4678b9d016f/watchfiles-0.21.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:40bca549fdc929b470dd1dbfcb47b3295cb46a6d2c90e50588b0a1b3bd98f429"}, + {url = "https://files.pythonhosted.org/packages/8c/8f/1ac72ff562a51adae43ef312ed8938adb488405a8639d00fe3d982137c3b/watchfiles-0.21.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:3ccceb50c611c433145502735e0370877cced72a6c70fd2410238bcbc7fe51d8"}, + {url = "https://files.pythonhosted.org/packages/92/ff/75cc1b30c5abcad13a2a72e75625ec619c7a393028a111d7d24dba578d5e/watchfiles-0.21.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:aff06b2cac3ef4616e26ba17a9c250c1fe9dd8a5d907d0193f84c499b1b6e6a9"}, + {url = "https://files.pythonhosted.org/packages/93/60/c35694cf2e894796b65afba9b93555f9adbcc02e251fd8fb1703848cf691/watchfiles-0.21.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dd5fad9b9c0dd89904bbdea978ce89a2b692a7ee8a0ce19b940e538c88a809c"}, + {url = "https://files.pythonhosted.org/packages/9a/65/12cbeb363bf220482a559c48107edfd87f09248f55e1ac315a36c2098a0f/watchfiles-0.21.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d9792dff410f266051025ecfaa927078b94cc7478954b06796a9756ccc7e14a9"}, + {url = "https://files.pythonhosted.org/packages/9e/8f/d93a72e531fa3c94227acb68932acda6401a45a9f76e92e848eec3499676/watchfiles-0.21.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57d430f5fb63fea141ab71ca9c064e80de3a20b427ca2febcbfcef70ff0ce895"}, + {url = "https://files.pythonhosted.org/packages/9f/b7/783097f8137a710d5cd9ccbfcd92e4b453d38dab05cfcb5dbd2c587752e5/watchfiles-0.21.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1fd9a5205139f3c6bb60d11f6072e0552f0a20b712c85f43d42342d162be1235"}, + {url = "https://files.pythonhosted.org/packages/a1/fd/2f009eb17809afd32a143b442856628585c9ce3a9c6d5c1841e44e35a16c/watchfiles-0.21.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:51ddac60b96a42c15d24fbdc7a4bfcd02b5a29c047b7f8bf63d3f6f5a860949a"}, + {url = "https://files.pythonhosted.org/packages/a3/87/6793ac60d2e20c9c1883aec7431c2e7b501ee44a839f6da1b747c13baa23/watchfiles-0.21.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a23092a992e61c3a6a70f350a56db7197242f3490da9c87b500f389b2d01eef"}, + {url = "https://files.pythonhosted.org/packages/ab/7e/61681016131d06d9827dfdf70c77817af67f3e785860175e1a2b552ae423/watchfiles-0.21.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4a21f71885aa2744719459951819e7bf5a906a6448a6b2bbce8e9cc9f2c8128"}, + {url = "https://files.pythonhosted.org/packages/b0/ba/a0d1c1c55f75e7e47c8f79f2314f7ec670b5177596f6d27764aecc7048cd/watchfiles-0.21.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18d5b4da8cf3e41895b34e8c37d13c9ed294954907929aacd95153508d5d89d7"}, + {url = "https://files.pythonhosted.org/packages/b5/e5/240e5eb3ff0ee3da3b028ac5be2019c407bdd0f3fdb02bd75fdf3bd10aff/watchfiles-0.21.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c81818595eff6e92535ff32825f31c116f867f64ff8cdf6562cd1d6b2e1e8f3e"}, + {url = "https://files.pythonhosted.org/packages/ba/66/873739dd7defdfaee4b880114de9463fae18ba13ae2ddd784806b0ee33b6/watchfiles-0.21.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49f56e6ecc2503e7dbe233fa328b2be1a7797d31548e7a193237dcdf1ad0eee0"}, + {url = "https://files.pythonhosted.org/packages/bd/51/d7539aa258d8f0e5d7b870af8b9b8964b4f88a1e4517eeb8a2efb838e9b3/watchfiles-0.21.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:02d91cbac553a3ad141db016e3350b03184deaafeba09b9d6439826ee594b365"}, + {url = "https://files.pythonhosted.org/packages/bf/5c/6b22d5469d9654a5992111227c487af3d85f528ed1296320c2a99384e2ec/watchfiles-0.21.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6e9be3ef84e2bb9710f3f777accce25556f4a71e15d2b73223788d528fcc2052"}, + {url = "https://files.pythonhosted.org/packages/c8/27/e534e4b3fe739f4bf8bd5dc4c26cbc5d3baa427125d8ef78a6556acd6ff4/watchfiles-0.21.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d23bcd6c8eaa6324fe109d8cac01b41fe9a54b8c498af9ce464c1aeeb99903d6"}, + {url = "https://files.pythonhosted.org/packages/ca/64/92b462b894cee2ba4df52e571b3b2104fd11fd6ab08a59e2d3493bcab4d2/watchfiles-0.21.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4c48a10d17571d1275701e14a601e36959ffada3add8cdbc9e5061a6e3579a5d"}, + {url = "https://files.pythonhosted.org/packages/d3/18/4b7f189b72b5d76e0f7a3ef602c47eebb44826ad2e3dd360c6fb856111d7/watchfiles-0.21.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec8c8900dc5c83650a63dd48c4d1d245343f904c4b64b48798c67a3767d7e165"}, + {url = "https://files.pythonhosted.org/packages/d5/2a/f9633279d8937ad84c532997405dd106fa6100e8d2b83e364f1c87561f96/watchfiles-0.21.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6674b00b9756b0af620aa2a3346b01f8e2a3dc729d25617e1b89cf6af4a54eb1"}, + {url = "https://files.pythonhosted.org/packages/d7/49/9b2199bbf3c89e7c8dd795fced9dac29f201be8a28a5df0c8ff625737df6/watchfiles-0.21.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd7ac678b92b29ba630d8c842d8ad6c555abda1b9ef044d6cc092dacbfc9719d"}, + {url = "https://files.pythonhosted.org/packages/d7/eb/b6f1184d1c7b9670f5bd1e184e4c221ecf25fd817cf2fcac6adc387882b5/watchfiles-0.21.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:642d66b75eda909fd1112d35c53816d59789a4b38c141a96d62f50a3ef9b3360"}, + {url = "https://files.pythonhosted.org/packages/da/42/90669adbc6293b6543a77ea104c84d8db56a0021cdd51274c8404f10e7d0/watchfiles-0.21.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a03651352fc20975ee2a707cd2d74a386cd303cc688f407296064ad1e6d1562"}, + {url = "https://files.pythonhosted.org/packages/da/f2/6b1de38aeb21eb9dac1ae6a1ee4521566e79690117032036c737cfab52fa/watchfiles-0.21.0-cp312-none-win_amd64.whl", hash = "sha256:18722b50783b5e30a18a8a5db3006bab146d2b705c92eb9a94f78c72beb94094"}, + {url = "https://files.pythonhosted.org/packages/e0/62/a2605f212a136e06f2d056ee7491ede9935ba0f1d5ceafd1f7da2a0c8625/watchfiles-0.21.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:511f0b034120cd1989932bf1e9081aa9fb00f1f949fbd2d9cab6264916ae89b1"}, + {url = "https://files.pythonhosted.org/packages/e1/4c/da6cfbb501bd3a07d9955cf0b7e8e226f99835d86412bc07de6108a64b59/watchfiles-0.21.0-cp38-none-win32.whl", hash = "sha256:9a0aa47f94ea9a0b39dd30850b0adf2e1cd32a8b4f9c7aa443d852aacf9ca214"}, + {url = "https://files.pythonhosted.org/packages/e8/f3/c67865cb5a174201c52d34e870cc7956b8408ee83ce9a02909d6a2a93a14/watchfiles-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f92944efc564867bbf841c823c8b71bb0be75e06b8ce45c084b46411475a915"}, + {url = "https://files.pythonhosted.org/packages/ee/92/219c539a2a93b6870fa7b84eace946983126b20a7e15c6c034d8d0472682/watchfiles-0.21.0-cp311-none-win32.whl", hash = "sha256:ebe684d7d26239e23d102a2bad2a358dedf18e462e8808778703427d1f584400"}, + {url = "https://files.pythonhosted.org/packages/ef/c0/737ddb4c97efd7e4c98852973ca80d7fab65811d6c4d3a64182333d455b0/watchfiles-0.21.0-cp39-none-win_amd64.whl", hash = "sha256:6cb8fdc044909e2078c248986f2fc76f911f72b51ea4a4fbbf472e01d14faa58"}, + {url = "https://files.pythonhosted.org/packages/f2/08/92e28867c66f0d9638bb131feca739057efc48dbcd391fd7f0a55507e470/watchfiles-0.21.0-cp310-none-win32.whl", hash = "sha256:214cee7f9e09150d4fb42e24919a1e74d8c9b8a9306ed1474ecaddcd5479c293"}, + {url = "https://files.pythonhosted.org/packages/f3/dc/2a8a447b783f5059c4bf7a6bad8fe59375a5a9ce872774763b25c21c2860/watchfiles-0.21.0-cp311-none-win_amd64.whl", hash = "sha256:4566006aa44cb0d21b8ab53baf4b9c667a0ed23efe4aaad8c227bfba0bf15cbe"}, + {url = "https://files.pythonhosted.org/packages/f7/4b/b90dcdc3bbaf3bb2db733e1beea2d01566b601c15fcf8e71dfcc8686c097/watchfiles-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d45d9b699ecbac6c7bd8e0a2609767491540403610962968d258fd6405c17c"}, + {url = "https://files.pythonhosted.org/packages/fc/60/f94029d1beb8b544f6db6828c7ccc29aa748e6bc82d143637cecff998d5c/watchfiles-0.21.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c9198c989f47898b2c22201756f73249de3748e0fc9de44adaf54a8b259cc0c"}, + {url = "https://files.pythonhosted.org/packages/fe/a3/42686af3a089f34aba35c39abac852869661938dae7025c1a0580dfe0fbf/watchfiles-0.21.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:927c589500f9f41e370b0125c12ac9e7d3a2fd166b89e9ee2828b3dda20bfe6f"}, + {url = "https://files.pythonhosted.org/packages/ff/62/2718b99a53b19860b754d7d9e26cf66b458dcbe5a1c131a889402cb2298d/watchfiles-0.21.0-cp39-none-win32.whl", hash = "sha256:59137c0c6826bd56c710d1d2bda81553b5e6b7c84d5a676747d80caf0409ad94"}, +] "websocket-client 1.3.3" = [ {url = "https://files.pythonhosted.org/packages/0e/e7/e705ead133d21de4be752af4b3a0cb1f02514ff45bf165b3955c1ce22077/websocket-client-1.3.3.tar.gz", hash = "sha256:d58c5f284d6a9bf8379dab423259fe8f85b70d5fa5d2916d5791a84594b122b1"}, {url = "https://files.pythonhosted.org/packages/67/b4/91683d7d5f66393e8877492fe4763304f82dbe308658a8db98f7a9e20baf/websocket_client-1.3.3-py3-none-any.whl", hash = "sha256:5d55652dc1d0b3c734f044337d929aaf83f4f9138816ec680c1aefefb4dc4877"}, ] +"websockets 12.0" = [ + {url = "https://files.pythonhosted.org/packages/01/ae/d48aebf121726d2a26e48170cd7558627b09e0d47186ddfa1be017c81663/websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"}, + {url = "https://files.pythonhosted.org/packages/02/73/9c1e168a2e7fdf26841dc98f5f5502e91dea47428da7690a08101f616169/websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"}, + {url = "https://files.pythonhosted.org/packages/03/72/e4752b208241a606625da8d8757d98c3bfc6c69c0edc47603180c208f857/websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"}, + {url = "https://files.pythonhosted.org/packages/06/dd/e8535f54b4aaded1ed44041ca8eb9de8786ce719ff148b56b4a903ef93e6/websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"}, + {url = "https://files.pythonhosted.org/packages/0a/31/337bf35ae5faeaf364c9cddec66681cdf51dc4414ee7a20f92a18e57880f/websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"}, + {url = "https://files.pythonhosted.org/packages/0b/a5/1a38fb85a456b9dc874ec984f3ff34f6550eafd17a3da28753cd3c1628e8/websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"}, + {url = "https://files.pythonhosted.org/packages/0d/a4/ec1043bc6acf5bc405762ecc1327f3573441185571122ae50fc00c6d3130/websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"}, + {url = "https://files.pythonhosted.org/packages/0e/d8/b468e92e5140ad8550477250310132cc6316412c7e0d2eb9e05661cf1f58/websockets-12.0-cp38-cp38-win_amd64.whl", hash = "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892"}, + {url = "https://files.pythonhosted.org/packages/16/17/f63d9ee6ffd9afbeea021d5950d6e8db84cd4aead306c6c2ca523805699e/websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"}, + {url = "https://files.pythonhosted.org/packages/16/66/4666e53d06fc5a40f9d36394969ac1168f9f27a075a020af1cc04622e075/websockets-12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205"}, + {url = "https://files.pythonhosted.org/packages/1b/9f/84d42c8c3e510f2a9ad09ae178c31cc89cc838b143a04bf41ff0653ca018/websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"}, + {url = "https://files.pythonhosted.org/packages/20/52/8915f51f9aaef4e4361c89dd6cf69f72a0159f14e0d25026c81b6ad22525/websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"}, + {url = "https://files.pythonhosted.org/packages/22/26/df77c4b7538caebb78c9b97f43169ef742a4f445e032a5ea1aaef88f8f46/websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"}, + {url = "https://files.pythonhosted.org/packages/25/a9/a3e03f9f3c4425a914e5875dd09f2c2559d61b44edd52cf1e6b73f938898/websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"}, + {url = "https://files.pythonhosted.org/packages/28/4b/344ec5cfeb6bc417da097f8253607c3aed11d9a305fb58346f506bf556d8/websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"}, + {url = "https://files.pythonhosted.org/packages/2d/73/a337e1275e4c3a9752896fbe467d2c6b5f25e983a2de0992e1dfaca04dbe/websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"}, + {url = "https://files.pythonhosted.org/packages/2e/00/96ae1c9dcb3bc316ef683f2febd8c97dde9f254dc36c3afc65c7645f734c/websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"}, + {url = "https://files.pythonhosted.org/packages/2e/62/7a7874b7285413c954a4cca3c11fd851f11b2fe5b4ae2d9bee4f6d9bdb10/websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"}, + {url = "https://files.pythonhosted.org/packages/33/fd/13ae9a400c662b6d03717e5599d8c88da0e84255c09a404e668568e53f50/websockets-12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137"}, + {url = "https://files.pythonhosted.org/packages/39/34/364f30fdf1a375e4002a26ee3061138d1571dfda6421126127d379d13930/websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"}, + {url = "https://files.pythonhosted.org/packages/3b/f0/a721a6361972aa8649db86672834545d889e9975d769348d26ccfa102e5c/websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"}, + {url = "https://files.pythonhosted.org/packages/3c/98/1261f289dff7e65a38d59d2f591de6ed0a2580b729aebddec033c4d10881/websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"}, + {url = "https://files.pythonhosted.org/packages/41/b0/5ec054cfcf23adfc88d39359b85e81d043af8a141e3ac8ce40f45a5ce5f4/websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"}, + {url = "https://files.pythonhosted.org/packages/43/8b/554a8a8bb6da9dd1ce04c44125e2192af7b7beebf6e3dbfa5d0e285cc20f/websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"}, + {url = "https://files.pythonhosted.org/packages/45/51/1f823a341fc20a880e67ae62f6c38c4880a24a4b60fbe544a38f516f39a1/websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"}, + {url = "https://files.pythonhosted.org/packages/4e/e1/f6c3ecf7f1bfd9209e13949db027d7fdea2faf090c69b5f2d17d1d796d96/websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"}, + {url = "https://files.pythonhosted.org/packages/50/f0/5939fbc9bc1979d79a774ce5b7c4b33c0cefe99af22fb70f7462d0919640/websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"}, + {url = "https://files.pythonhosted.org/packages/61/98/aa856d4b1655162bab77752935da5dbd779f272653b82fb2d2c8acb09a2a/websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"}, + {url = "https://files.pythonhosted.org/packages/62/3b/98ee269712f37d892b93852ce07b3e6d7653160ca4c0d4f8c8663f8021f8/websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"}, + {url = "https://files.pythonhosted.org/packages/67/cc/6fd14e45c5149e6c81c6771550ee5a4911321014e620f69baf1490001a80/websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"}, + {url = "https://files.pythonhosted.org/packages/69/af/c52981023e7afcdfdb50c4697f702659b3dedca54f71e3cc99b8581f5647/websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"}, + {url = "https://files.pythonhosted.org/packages/6e/a4/51a25e591d645df71ee0dc3a2c880b28e5514c00ce752f98a40a87abcd1e/websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"}, + {url = "https://files.pythonhosted.org/packages/74/4d/f88eeceb23cb587c4aeca779e3f356cf54817af2368cb7f2bd41f93c8360/websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"}, + {url = "https://files.pythonhosted.org/packages/79/4d/9cc401e7b07e80532ebc8c8e993f42541534da9e9249c59ee0139dcb0352/websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"}, + {url = "https://files.pythonhosted.org/packages/7b/9f/f5aae5c49b0fc04ca68c723386f0d97f17363384525c6566cd382912a022/websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"}, + {url = "https://files.pythonhosted.org/packages/81/ee/272cb67ace1786ce6d9f39d47b3c55b335e8b75dd1972a7967aad39178b6/websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"}, + {url = "https://files.pythonhosted.org/packages/88/81/a947a715a7108d5bcae01f2a1b19fe6dbab22d7bfec64541ed3d07043aaf/websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"}, + {url = "https://files.pythonhosted.org/packages/91/83/5f8c4cf2a0cf26d8eebed77976a5663d6760e24c6d9e949e90b659d885e6/websockets-12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d"}, + {url = "https://files.pythonhosted.org/packages/94/92/5dc1202332df60422869fdb6c86213ff6987b1b06c329eed329cc49966f7/websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"}, + {url = "https://files.pythonhosted.org/packages/95/aa/1ac767825c96f9d7e43c4c95683757d4ef28cf11fa47a69aca42428d3e3a/websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"}, + {url = "https://files.pythonhosted.org/packages/95/aa/75fa3b893142d6d98a48cb461169bd268141f2da8bfca97392d6462a02eb/websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"}, + {url = "https://files.pythonhosted.org/packages/9a/12/c7a7504f5bf74d6ee0533f6fc7d30d8f4b79420ab179d1df2484b07602eb/websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"}, + {url = "https://files.pythonhosted.org/packages/9c/5b/648db3556d8a441aa9705e1132b3ddae76204b57410952f85cf4a953623a/websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"}, + {url = "https://files.pythonhosted.org/packages/a8/03/387fc902b397729df166763e336f4e5cec09fe7b9d60f442542c94a21be1/websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"}, + {url = "https://files.pythonhosted.org/packages/a9/1c/f68769fba63ccb9c13fe0a25b616bd5aebeef1c7ddebc2ccc32462fb784d/websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"}, + {url = "https://files.pythonhosted.org/packages/a9/6d/23cc898647c8a614a0d9ca703695dd04322fb5135096a20c2684b7c852b6/websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"}, + {url = "https://files.pythonhosted.org/packages/ac/4e/c7361b2d7b964c40fea924d64881145164961fcd6c90b88b7e3ab2c4f431/websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"}, + {url = "https://files.pythonhosted.org/packages/af/32/f443ee05c815fccc4ca2899fe1cdcc7326b73ffb20b75d26b9b779d5d83b/websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"}, + {url = "https://files.pythonhosted.org/packages/af/9c/703ff3cd8109dcdee6152bae055d852ebaa7750117760ded697ab836cbcf/websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"}, + {url = "https://files.pythonhosted.org/packages/af/f1/bba1e64430685dd456c1a1fd6b0c791ae33104967b928aefeff261761e8d/websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"}, + {url = "https://files.pythonhosted.org/packages/b0/8e/58b8812940d746ad74d395fb069497255cb5ef50748dfab1e8b386b1f339/websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"}, + {url = "https://files.pythonhosted.org/packages/b1/b9/360b86ded0920a93bff0db4e4b0aa31370b0208ca240b2e98d62aad8d082/websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"}, + {url = "https://files.pythonhosted.org/packages/ba/0d/c1f43e921cbf0c546898bb54d22863490bb80491be2b24f1d1c9ac23cfd6/websockets-12.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967"}, + {url = "https://files.pythonhosted.org/packages/ba/43/b0dd6921ae0c8e48cdd5140b6745ae45424f4ad0aa3fd2eb06b48be55463/websockets-12.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8"}, + {url = "https://files.pythonhosted.org/packages/bb/07/050a8f6b06eb8a876a51c56f752dd51f59982dda37f2a1788bfd2a26952e/websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"}, + {url = "https://files.pythonhosted.org/packages/bb/d3/1eca0d8fb6f0665c96f0dc7c0d0ec8aa1a425e8c003e0c18e1451f65d177/websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"}, + {url = "https://files.pythonhosted.org/packages/c5/db/2d12649006d6686802308831f4f8a1190105ea34afb68c52f098de689ad8/websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"}, + {url = "https://files.pythonhosted.org/packages/c6/1a/142fa072b2292ca0897c282d12f48d5b18bdda5ac32774e3d6f9bddfd8fe/websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"}, + {url = "https://files.pythonhosted.org/packages/c6/68/ed11b1b1a24fb0fa1a8275f72464e2f1038e25cab0137a09747cd1f40836/websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"}, + {url = "https://files.pythonhosted.org/packages/ca/cc/4dc115e53ef66a03fd13be5a8623947bfb6e17131f9bede444eca090a454/websockets-12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7"}, + {url = "https://files.pythonhosted.org/packages/cd/ea/0ceeea4f5b87398fe2d9f5bcecfa00a1bcd542e2bfcac2f2e5dd612c4e9e/websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"}, + {url = "https://files.pythonhosted.org/packages/d0/f2/f4baa6c9e28c2d06cc787203eea18eb1d875f4fddb8e85c28df91f02bc55/websockets-12.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438"}, + {url = "https://files.pythonhosted.org/packages/d1/40/6b169cd1957476374f51f4486a3e85003149e62a14e6b78a958c2222337a/websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"}, + {url = "https://files.pythonhosted.org/packages/d3/45/bcf3056e7627652aa54bf82cbdeaea1d293d4d78fcd4a8e4ee72080ac511/websockets-12.0-cp38-cp38-win32.whl", hash = "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62"}, + {url = "https://files.pythonhosted.org/packages/e1/16/9e2c741660d541cc239cdc9f04cbc56bad2ac7585782f57ae7f329481f89/websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"}, + {url = "https://files.pythonhosted.org/packages/e3/05/f52a60b66d9faf07a4f7d71dc056bffafe36a7e98c4eb5b78f04fe6e4e85/websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"}, + {url = "https://files.pythonhosted.org/packages/e4/2d/9a683359ad2ed11b2303a7a94800db19c61d33fa3bde271df09e99936022/websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"}, + {url = "https://files.pythonhosted.org/packages/e4/6a/3600c7771eb31116d2e77383d7345618b37bb93709d041e328c08e2a8eb3/websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"}, + {url = "https://files.pythonhosted.org/packages/e4/9e/5c565ca57c2b72b26057df3fd8ea62533cbc1bf4b166249c6107a71f9e80/websockets-12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2"}, + {url = "https://files.pythonhosted.org/packages/e5/18/18ce9a4a08203c8d0d3d561e3ea4f453daf32f099601fc831e60c8a9b0f2/websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"}, + {url = "https://files.pythonhosted.org/packages/e9/bc/646bfbd9badbf59efb48db7265b097e9f626c3530c9d1329a826ef4db6a0/websockets-12.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def"}, + {url = "https://files.pythonhosted.org/packages/f1/00/d6f01ca2b191f8b0808e4132ccd2e7691f0453cbd7d0f72330eb97453c3a/websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"}, +] "werkzeug 2.1.2" = [ {url = "https://files.pythonhosted.org/packages/10/cf/97eb1a3847c01ae53e8376bc21145555ac95279523a935963dc8ff96c50b/Werkzeug-2.1.2.tar.gz", hash = "sha256:1ce08e8093ed67d638d63879fd1ba3735817f7a80de3674d293f5984f25fb6e6"}, {url = "https://files.pythonhosted.org/packages/c4/44/f50f2d22cdfb6d56c03d1b4cc3cfa03ebee2f21b59a7768f151e43415ba5/Werkzeug-2.1.2-py3-none-any.whl", hash = "sha256:72a4b735692dd3135217911cbeaa1be5fa3f62bffb8745c5215420a03dc55255"}, @@ -2735,13 +3407,16 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/4b/5b/3cf79a5fce7a91c0c10275835199fafdf30c1b8c7008fa671af3c4e8046c/wrapt-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28"}, {url = "https://files.pythonhosted.org/packages/4f/83/2669bf2cb4cc2b346c40799478d29749ccd17078cb4f69b4a9f95921ff6d/wrapt-1.14.1-cp310-cp310-win32.whl", hash = "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8"}, {url = "https://files.pythonhosted.org/packages/50/d5/bf619c4d204fe8888460f65222b465c7ecfa43590fdb31864fe0e266da29/wrapt-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4"}, + {url = "https://files.pythonhosted.org/packages/5a/27/604d6ad71fe5935446df1b7512d491b47fe2aef8c95e9813d03d78024a28/wrapt-1.14.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:240b1686f38ae665d1b15475966fe0472f78e71b1b4903c143a842659c8e4cb9"}, {url = "https://files.pythonhosted.org/packages/5b/02/5ac7ea3b6722c84a2882d349ac581a9711b4047fe7a58475903832caa295/wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"}, {url = "https://files.pythonhosted.org/packages/5c/46/b91791db2ac7cc4c186408b7aed37b994463970f2397d0548f38b2b47aca/wrapt-1.14.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569"}, {url = "https://files.pythonhosted.org/packages/5e/d3/bd44864e0274b7e162e2a68c71fffbd8b3a7b620efd23320fd0f70333cff/wrapt-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f"}, {url = "https://files.pythonhosted.org/packages/67/b4/b5504dddcb2ff9486f8569953938591e0013cca09c912b28747d1d9cb04f/wrapt-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1"}, {url = "https://files.pythonhosted.org/packages/6a/12/76bbe26dc39d05f1a7be8d570d91c87bb79297e08e885148ed670ed17b7b/wrapt-1.14.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3"}, + {url = "https://files.pythonhosted.org/packages/6e/79/aec8185eefe20e8f49e5adeb0c2e20e016d5916d10872c17705ddac41be2/wrapt-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2020f391008ef874c6d9e208b24f28e31bcb85ccff4f335f15a3251d222b92d9"}, {url = "https://files.pythonhosted.org/packages/72/24/490a0bbc67135f737d2eb4b270bfc91e54cc3f0b5e97b4ceec91a44bb898/wrapt-1.14.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1"}, {url = "https://files.pythonhosted.org/packages/79/9c/f5d1209c8e4e091e250eb3ed099056e7e1ad0ec1e9ca46f6d88389e2d6d4/wrapt-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b"}, + {url = "https://files.pythonhosted.org/packages/7f/1b/e0439eec0db6520968c751bc7e12480bb80bb8d939190e0e55ed762f3c7a/wrapt-1.14.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9008dad07d71f68487c91e96579c8567c98ca4c3881b9b113bc7b33e9fd78b8"}, {url = "https://files.pythonhosted.org/packages/82/27/1eac9e63b9ef0e0929e00e17872d45de9d7d965c7f49b933e2daa22c7896/wrapt-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed"}, {url = "https://files.pythonhosted.org/packages/88/ef/05655df7648752ae0a57fe2b9820e340ff025cecec9341aad7936c589a2f/wrapt-1.14.1-cp38-cp38-win32.whl", hash = "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5"}, {url = "https://files.pythonhosted.org/packages/92/b5/788b92550804405424e0d0b1a95250137cbf0e050bb5c461e8ad0fefdc86/wrapt-1.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462"}, @@ -2752,15 +3427,20 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/94/56/fd707fb8e1ea86e72503d823549fb002a0f16cb4909619748996daeb3a82/wrapt-1.14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069"}, {url = "https://files.pythonhosted.org/packages/94/59/60b2fe919ffb190cf8cae0307bafdaf1695eac8655921f59768ce3bf1084/wrapt-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248"}, {url = "https://files.pythonhosted.org/packages/98/0f/3db7e01896b726e68fa2ba918ed0d79f3cc2da2ce928799282264d14c6f6/wrapt-1.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87"}, + {url = "https://files.pythonhosted.org/packages/9a/aa/ab46fb18072b86e87e0965a402f8723217e8c0312d1b3e2a91308df924ab/wrapt-1.14.1-cp311-cp311-win32.whl", hash = "sha256:358fe87cc899c6bb0ddc185bf3dbfa4ba646f05b1b0b9b5a27c2cb92c2cea204"}, {url = "https://files.pythonhosted.org/packages/a2/a7/dd6e91c68d76328d09dd61a7aadac19d49ec509a07e853173036dc05fb79/wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"}, {url = "https://files.pythonhosted.org/packages/a7/0d/a52a0268c98a687785c5452324e10f9462d289e850066e281aa327505aa7/wrapt-1.14.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68"}, + {url = "https://files.pythonhosted.org/packages/ad/b7/332692b8d0387922da0f1323ad36a14e365911def3c78ea0d102f83ac592/wrapt-1.14.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:acae32e13a4153809db37405f5eba5bac5fbe2e2ba61ab227926a22901051c0a"}, {url = "https://files.pythonhosted.org/packages/b1/ca/ec539e402932bb64814a039f471d327d0deb4612199506094ca60821b94c/wrapt-1.14.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3"}, + {url = "https://files.pythonhosted.org/packages/b9/45/2cc612ff64061d4416baf8d0daf27bea7f79f0097638ddc2af51a3e647f3/wrapt-1.14.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6447e9f3ba72f8e2b985a1da758767698efa72723d5b59accefd716e9e8272bf"}, + {url = "https://files.pythonhosted.org/packages/ba/7e/14113996bc6ee68eb987773b4139c87afd3ceff60e27e37648aa5eb2798a/wrapt-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:26046cd03936ae745a502abf44dac702a5e6880b2b01c29aea8ddf3353b68224"}, {url = "https://files.pythonhosted.org/packages/bb/70/73c54e24ea69a8b06ae9649e61d5e64f2b4bdfc6f202fc7794abeac1ed20/wrapt-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7"}, {url = "https://files.pythonhosted.org/packages/c0/1e/e5a5ac09e92fd112d50e1793e5b9982dc9e510311ed89dacd2e801f82967/wrapt-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164"}, {url = "https://files.pythonhosted.org/packages/c7/1b/0cdff572d22600fcf47353e8eb1077d83cab3f161ebfb4843565c6e07e66/wrapt-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d"}, {url = "https://files.pythonhosted.org/packages/c8/03/b36a48dcb6f6332d754017b2dd617757687984a6c433e44ca59bb7fefd4c/wrapt-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853"}, {url = "https://files.pythonhosted.org/packages/ca/16/e79e786d930b69a20481174c7bc97e989fb67d2a181a5043e1d3c70c9b21/wrapt-1.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59"}, {url = "https://files.pythonhosted.org/packages/cd/ec/383d9552df0641e9915454b03139571e0c6e055f5d414d8f3d04f3892f38/wrapt-1.14.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656"}, + {url = "https://files.pythonhosted.org/packages/d1/71/8d68004e5d5a676177342a56808af51e1df3b0e54b203e3295a8cd96b53b/wrapt-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2feecf86e1f7a86517cab34ae6c2f081fd2d0dac860cb0c0ded96d799d20b335"}, {url = "https://files.pythonhosted.org/packages/d9/3b/f6b760bf04d13e5ddb70d019779466c22952637cf0f606a26d5f784f27ff/wrapt-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907"}, {url = "https://files.pythonhosted.org/packages/d9/ab/3ba5816dd466ffd7242913708771d258569825ab76fd29d7fd85b9361311/wrapt-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383"}, {url = "https://files.pythonhosted.org/packages/da/f4/7af9e01b6c1126b2daef72d5ba2cbf59a7229fd57c5b23166f694d758a8f/wrapt-1.14.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57"}, @@ -2769,9 +3449,11 @@ content_hash = "sha256:e692dc0dad8e5a6b7c9aaeb8e45dc5af0280549eeb6e80e7ee3071115 {url = "https://files.pythonhosted.org/packages/e0/80/af9da7379ee6df583875d0aeb80f9d5f0bd5f081dd1ee5ce06587d8bfec7/wrapt-1.14.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff"}, {url = "https://files.pythonhosted.org/packages/e6/57/d5673f5201ccbc287e70a574868319267735de3041e496e1e26b48d8f653/wrapt-1.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1"}, {url = "https://files.pythonhosted.org/packages/e7/a1/a9596c5858c4a58be8cdd5e8b0e5f53f9c1c17f0616b47edde8de1a356fe/wrapt-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c"}, + {url = "https://files.pythonhosted.org/packages/e7/f9/8c078b4973604cd968b23eb3dff52028b5c48f2a02c4f1f975f4d5e344d1/wrapt-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ecee4132c6cd2ce5308e21672015ddfed1ff975ad0ac8d27168ea82e71413f55"}, {url = "https://files.pythonhosted.org/packages/e8/f6/7e30a8c53d27ef8c1ff872dc4fb75247c99eb73d834c91a49a55d046c127/wrapt-1.14.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0"}, {url = "https://files.pythonhosted.org/packages/f0/db/2a9ea49cd8bdde87a85262e517563d42b9e5b760473597b9da511fcbd54d/wrapt-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471"}, {url = "https://files.pythonhosted.org/packages/f1/96/d22461ba08d61a859c45cda5064b878f2baa61f142d3acfa8adabd82bf07/wrapt-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4"}, + {url = "https://files.pythonhosted.org/packages/f2/31/cbce966b6760e62d005c237961e839a755bf0c907199248394e2ee03ab05/wrapt-1.14.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49ef582b7a1152ae2766557f0550a9fcbf7bbd76f43fbdc94dd3bf07cc7168be"}, {url = "https://files.pythonhosted.org/packages/f7/92/121147bb2f9ed1aa35a8780c636d5da9c167545f97737f0860b4c6c92086/wrapt-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320"}, {url = "https://files.pythonhosted.org/packages/f8/c4/3f8130d646bfc89382966adfb3d6428f26d0f752543a7e2fd92c1e493be6/wrapt-1.14.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d"}, {url = "https://files.pythonhosted.org/packages/f9/3c/110e52b9da396a4ef3a0521552a1af9c7875a762361f48678c1ac272fd7e/wrapt-1.14.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe"}, diff --git a/packages/backend/pyproject.toml b/packages/backend/pyproject.toml index c74a21542..a7f74fe48 100644 --- a/packages/backend/pyproject.toml +++ b/packages/backend/pyproject.toml @@ -94,6 +94,7 @@ dependencies = [ "django-extensions~=3.2", "django-hashid-field~=3.3", "django-hosts~=5.2", + "django-redis~=5.4", "drf-access-policy~=1.1", "dj-stripe==2.8.1", "psycopg2-binary~=2.9", @@ -115,6 +116,10 @@ dependencies = [ "pydantic>=1.10.7", "pyyaml>=6.0.0", "gunicorn==21.2.0", + "uvicorn[standard]==0.27.1", + "channels[daphne]>=4.0.0", + "django-channels-graphql-ws==1.0.0rc6", + "channels-redis>=4.2.0", ] requires-python = "~=3.11.0" license = {text = "MIT"} diff --git a/packages/backend/scripts/runtime/run.sh b/packages/backend/scripts/runtime/run.sh index 6515516a3..916d2833a 100755 --- a/packages/backend/scripts/runtime/run.sh +++ b/packages/backend/scripts/runtime/run.sh @@ -3,4 +3,4 @@ set -e echo Starting app server... -pdm run gunicorn -c gunicorn.py config.wsgi:application +pdm run gunicorn -c python:config.gunicorn config.asgi:application diff --git a/packages/backend/sonar-project.properties b/packages/backend/sonar-project.properties index 73620d5be..b56a12e6d 100644 --- a/packages/backend/sonar-project.properties +++ b/packages/backend/sonar-project.properties @@ -2,4 +2,4 @@ sonar.organization=${env.SONAR_ORGANIZATION} sonar.projectKey=${env.SONAR_BACKEND_PROJECT_KEY} sonar.python.version=3.11 sonar.python.coverage.reportPaths=cov/coverage.xml -sonar.exclusions=**/migrations/*, **/tests/**/* \ No newline at end of file +sonar.exclusions=**/migrations/*, **/tests/**/*, config/** diff --git a/packages/infra/infra-shared/src/index.ts b/packages/infra/infra-shared/src/index.ts index f8706d57c..c0da811dc 100644 --- a/packages/infra/infra-shared/src/index.ts +++ b/packages/infra/infra-shared/src/index.ts @@ -4,6 +4,7 @@ import { EnvComponentsStack } from './stacks/components'; import { MainDatabase } from './stacks/db/mainDatabase'; import { MainECSCluster } from './stacks/main/mainEcsCluster'; import { MainKmsKey } from './stacks/main/mainKmsKey'; +import { MainRedisCluster } from './stacks/main/mainRedisCluster'; import { UsEastResourcesStack } from './stacks/usEastResources'; export * from './lib/names'; @@ -16,4 +17,5 @@ export { FargateServiceResources, UsEastResourcesStack, WebAppCloudFrontDistribution, + MainRedisCluster, }; diff --git a/packages/infra/infra-shared/src/patterns/webAppCloudFrontDistribution.ts b/packages/infra/infra-shared/src/patterns/webAppCloudFrontDistribution.ts index 716d22042..71312e92c 100644 --- a/packages/infra/infra-shared/src/patterns/webAppCloudFrontDistribution.ts +++ b/packages/infra/infra-shared/src/patterns/webAppCloudFrontDistribution.ts @@ -36,7 +36,7 @@ export class WebAppCloudFrontDistribution extends Construct { constructor( scope: Construct, id: string, - props: WebAppCloudFrontDistributionProps + props: WebAppCloudFrontDistributionProps, ) { super(scope, id); @@ -44,7 +44,7 @@ export class WebAppCloudFrontDistribution extends Construct { this.distribution = this.createCloudFrontDistribution( staticFilesBucket, - props + props, ); this.createDnsRecord(this.distribution, props); this.createDeployment(staticFilesBucket, this.distribution, props); @@ -53,7 +53,7 @@ export class WebAppCloudFrontDistribution extends Construct { private createDeployment( staticFilesBucket: Bucket, distribution: cloudfront.Distribution, - props: WebAppCloudFrontDistributionProps + props: WebAppCloudFrontDistributionProps, ) { new s3Deploy.BucketDeployment(this, 'DeployWebsite', { distribution, @@ -76,13 +76,13 @@ export class WebAppCloudFrontDistribution extends Construct { private createCloudFrontDistribution( staticFilesBucket: Bucket, - props: WebAppCloudFrontDistributionProps + props: WebAppCloudFrontDistributionProps, ) { const indexFile = '/index.html'; const defaultBehavior = this.createStaticFilesSourceConfig( staticFilesBucket, - props + props, ); let additionalBehaviors: Record = {}; const apiBehaviorConfig = this.createApiProxyBehaviorConfig(props); @@ -113,7 +113,7 @@ export class WebAppCloudFrontDistribution extends Construct { certificate: acm.Certificate.fromCertificateArn( this, 'CloudFrontDistributionCertificate', - props.certificateArn + props.certificateArn, ), sslSupportMethod: cloudfront.SSLMethod.SNI, }); @@ -121,7 +121,7 @@ export class WebAppCloudFrontDistribution extends Construct { private createStaticFilesSourceConfig( staticFilesBucket: Bucket, - props: WebAppCloudFrontDistributionProps + props: WebAppCloudFrontDistributionProps, ): cloudfront.BehaviorOptions { const edgeLambdas: cloudfront.EdgeLambda[] = []; const customHeaders: { [key: string]: string } = {}; @@ -145,11 +145,11 @@ export class WebAppCloudFrontDistribution extends Construct { functionVersion: lambda.Version.fromVersionArn( this, 'AuthLambdaFunction', - authLambdaParam.getResponseField('Parameter.Value') + authLambdaParam.getResponseField('Parameter.Value'), ), }); customHeaders['X-Auth-String'] = Buffer.from(props.basicAuth).toString( - 'base64' + 'base64', ); } @@ -157,13 +157,13 @@ export class WebAppCloudFrontDistribution extends Construct { queryStringBehavior: cloudfront.CacheQueryStringBehavior.all(), headerBehavior: cloudfront.CacheHeaderBehavior.allowList( 'Authorization', - 'CloudFront-Viewer-Country' + 'CloudFront-Viewer-Country', ), }); const originAccessIdentity = new cloudfront.OriginAccessIdentity( this, - 'StaticFilesOAI' + 'StaticFilesOAI', ); const origin = new cfOrigins.S3Origin(staticFilesBucket, { @@ -182,7 +182,7 @@ export class WebAppCloudFrontDistribution extends Construct { } private createApiProxyBehaviorConfig( - props: WebAppCloudFrontDistributionProps + props: WebAppCloudFrontDistributionProps, ): Record | null { if (!props.apiDomainName) { return null; @@ -194,9 +194,15 @@ export class WebAppCloudFrontDistribution extends Construct { { queryStringBehavior: cloudfront.OriginRequestQueryStringBehavior.all(), cookieBehavior: cloudfront.OriginRequestCookieBehavior.all(), - headerBehavior: - cloudfront.OriginRequestHeaderBehavior.allowList('Host'), - } + headerBehavior: cloudfront.OriginRequestHeaderBehavior.allowList( + 'Host', + 'Sec-WebSocket-Key', + 'Sec-WebSocket-Version', + 'Sec-WebSocket-Protocol', + 'Sec-WebSocket-Accept', + 'Sec-WebSocket-Extensions', + ), + }, ); return { @@ -213,14 +219,14 @@ export class WebAppCloudFrontDistribution extends Construct { } private createWebSocketApiProxyBehaviorConfig( - props: WebAppCloudFrontDistributionProps + props: WebAppCloudFrontDistributionProps, ): Record | null { if (!props.envSettings) { return null; } const stack = Stack.of(this); const webSocketApiId = Fn.importValue( - EnvComponentsStack.getWebSocketApiIdOutputExportName(props.envSettings) + EnvComponentsStack.getWebSocketApiIdOutputExportName(props.envSettings), ); const cfFunction = new cloudfront.Function(this, 'Function', { code: cloudfront.FunctionCode.fromInline(` @@ -238,15 +244,15 @@ export class WebAppCloudFrontDistribution extends Construct { `${webSocketApiId}.execute-api.${stack.region}.amazonaws.com`, { protocolPolicy: cloudfront.OriginProtocolPolicy.HTTPS_ONLY, - } + }, ), allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL, cachePolicy: cloudfront.CachePolicy.CACHING_DISABLED, originRequestPolicy: { /* - AllViewerExceptHostHeader - TODO: use cloudfront.OriginRequestPolicy. after CDK version is updated - */ + AllViewerExceptHostHeader + TODO: use cloudfront.OriginRequestPolicy. after CDK version is updated + */ originRequestPolicyId: 'b689b0a8-53d0-40ab-baf2-68738e2966ac', }, functionAssociations: [ @@ -262,7 +268,7 @@ export class WebAppCloudFrontDistribution extends Construct { private createDnsRecord( distribution: cloudfront.Distribution, - props: WebAppCloudFrontDistributionProps + props: WebAppCloudFrontDistributionProps, ) { if (!props.domainZone) { return null; @@ -272,7 +278,7 @@ export class WebAppCloudFrontDistribution extends Construct { zone: props.domainZone, recordName: props.domainName, target: route53.RecordTarget.fromAlias( - new route53Targets.CloudFrontTarget(distribution) + new route53Targets.CloudFrontTarget(distribution), ), }); } diff --git a/packages/infra/infra-shared/src/stacks/main/mainRedisCluster.ts b/packages/infra/infra-shared/src/stacks/main/mainRedisCluster.ts new file mode 100644 index 000000000..7f3b3439d --- /dev/null +++ b/packages/infra/infra-shared/src/stacks/main/mainRedisCluster.ts @@ -0,0 +1,75 @@ +import { Construct } from 'constructs'; +import * as elasticache from 'aws-cdk-lib/aws-elasticache'; +import * as ec2 from 'aws-cdk-lib/aws-ec2'; +import { SecurityGroup, SubnetType, Vpc } from 'aws-cdk-lib/aws-ec2'; +import { EnvironmentSettings } from '@sb/infra-core'; +import { CfnOutput } from 'aws-cdk-lib'; + +type MainRedisClusterProps = { + envSettings: EnvironmentSettings; + vpc: Vpc; + fargateContainerSecurityGroup: SecurityGroup; +}; + +export class MainRedisCluster extends Construct { + private readonly envSettings: EnvironmentSettings; + private cluster: elasticache.CfnCacheCluster; + + static getMainRedisClusterAddressExportName( + envSettings: EnvironmentSettings, + ) { + return `${envSettings.projectEnvName}-mainRedisClusterAddress`; + } + + constructor(scope: Construct, id: string, props: MainRedisClusterProps) { + super(scope, id); + + this.envSettings = props.envSettings; + const securityGroup = this.createSecurityGroup(props); + const subnetGroup = this.createSubnetGroup(props); + + this.cluster = new elasticache.CfnCacheCluster(this, 'CacheCluster', { + clusterName: `${props.envSettings.projectEnvName}-main`, + autoMinorVersionUpgrade: true, + engine: 'redis', + cacheNodeType: 'cache.t2.micro', + numCacheNodes: 1, + cacheSubnetGroupName: subnetGroup.cacheSubnetGroupName, + vpcSecurityGroupIds: [securityGroup.securityGroupId], + }); + + new CfnOutput(this, 'MainRedisClusterAddress', { + exportName: MainRedisCluster.getMainRedisClusterAddressExportName( + this.envSettings, + ), + value: this.cluster.attrRedisEndpointAddress, + }); + } + + private createSubnetGroup(props: MainRedisClusterProps) { + return new elasticache.CfnSubnetGroup(this, 'SubnetGroup', { + cacheSubnetGroupName: `${props.envSettings.projectEnvName}-main-redis`, + description: `Subnet group for private subnets of a ${props.envSettings.projectEnvName} main redis cluster`, + subnetIds: props.vpc.selectSubnets({ + subnetType: SubnetType.PRIVATE_WITH_EGRESS, + }).subnetIds, + }); + } + + private createSecurityGroup(props: MainRedisClusterProps) { + const sg = new ec2.SecurityGroup(this, 'RedisSecurityGroup', { + vpc: props.vpc, + }); + + const clusterPort = new ec2.Port({ + fromPort: 6379, + toPort: 6379, + protocol: ec2.Protocol.TCP, + stringRepresentation: '', + }); + + sg.addIngressRule(props.fargateContainerSecurityGroup, clusterPort); + + return sg; + } +} diff --git a/packages/infra/infra-shared/src/stacks/main/stack.ts b/packages/infra/infra-shared/src/stacks/main/stack.ts index cc68d7417..96003f71c 100644 --- a/packages/infra/infra-shared/src/stacks/main/stack.ts +++ b/packages/infra/infra-shared/src/stacks/main/stack.ts @@ -1,4 +1,5 @@ import { App, Stack, StackProps } from 'aws-cdk-lib'; +import * as iam from 'aws-cdk-lib/aws-iam'; import { EnvConstructProps, EnvironmentSettings } from '@sb/infra-core'; import { MainVpc } from './mainVpc'; @@ -6,7 +7,7 @@ import { MainECSCluster } from './mainEcsCluster'; import { MainKmsKey } from './mainKmsKey'; import { MainLambdaConfig } from './mainLambdaConfig'; import { MainCertificates } from './mainCertificates'; -import * as iam from 'aws-cdk-lib/aws-iam'; +import { MainRedisCluster } from './mainRedisCluster'; export interface EnvMainStackProps extends StackProps, EnvConstructProps {} @@ -44,12 +45,18 @@ export class EnvMainStack extends Stack { envSettings, mainVpc: this.mainVpc, }); + new MainRedisCluster(this, 'MainRedisCluster', { + envSettings, + vpc: this.mainVpc.vpc, + fargateContainerSecurityGroup: + this.mainEcsCluster.fargateContainerSecurityGroup, + }); } static getIamPolicyStatementsForEnvParameters( envSettings: EnvironmentSettings, region = '*', - account = '*' + account = '*', ) { const alias = MainKmsKey.getKeyAlias(envSettings); return [ diff --git a/packages/internal/core/project.json b/packages/internal/core/project.json index 1c0db1cba..44004819e 100644 --- a/packages/internal/core/project.json +++ b/packages/internal/core/project.json @@ -34,7 +34,7 @@ "parallel": false, "commands": [ "nx run-many --target=setup", - "nx run-many --target=compose-build-image --projects=backend,workers,localwsserver", + "nx run-many --target=compose-build-image --projects=backend,workers", "docker-compose up --force-recreate -d backend workers" ] }, diff --git a/packages/internal/docs/docs/shared/partials/env-vars/_webapp.mdx b/packages/internal/docs/docs/shared/partials/env-vars/_webapp.mdx index 8678c19fd..9c93a2da1 100644 --- a/packages/internal/docs/docs/shared/partials/env-vars/_webapp.mdx +++ b/packages/internal/docs/docs/shared/partials/env-vars/_webapp.mdx @@ -4,7 +4,7 @@ |------------------------|----------------------------------------------------------------------------------|--------------------------------------------------| | VITE_BASE_API_URL | Path to access backend API | `/api` | | VITE_WEB_APP_URL | Absolute URL to application | `https://app.demo.saas.apptoku.com` | -| VITE_SUBSCRIPTIONS_URL | Websockets subscription URL | `wss://app.demo.saas.apptoku.com/ws` | +| VITE_EMAIL_ASSETS_URL | Absolute URL to email assets. By default it's `${VITE_WEB_APP_URL}/email-assets` | `https://app.demo.saas.apptoku.com/email-assets` | import OptionalVars from './_webapp_optional.mdx'; diff --git a/packages/internal/local-ws-server/.dockerignore b/packages/internal/local-ws-server/.dockerignore deleted file mode 100644 index b512c09d4..000000000 --- a/packages/internal/local-ws-server/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -node_modules \ No newline at end of file diff --git a/packages/internal/local-ws-server/.gitignore b/packages/internal/local-ws-server/.gitignore deleted file mode 100644 index 8e6e8a930..000000000 --- a/packages/internal/local-ws-server/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Node directories -node_modules diff --git a/packages/internal/local-ws-server/Dockerfile b/packages/internal/local-ws-server/Dockerfile deleted file mode 100644 index bf6d38d9f..000000000 --- a/packages/internal/local-ws-server/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM node:20-alpine - -WORKDIR /app -COPY package.json yarn.lock /app/ -RUN yarn - -COPY . /app/ - -ENTRYPOINT ["/bin/sh", "scripts/run.sh"] diff --git a/packages/internal/local-ws-server/api.js b/packages/internal/local-ws-server/api.js deleted file mode 100644 index 09745371c..000000000 --- a/packages/internal/local-ws-server/api.js +++ /dev/null @@ -1,32 +0,0 @@ -import axios from "axios"; - -const BE_ENDPOINT_URL = process.env.BE_ENDPOINT_URL; - -export class Api { - static #connectEndpoint() { - return `${BE_ENDPOINT_URL}debug/ws/connect/`; - } - - static #disconnectEndpoint(connectionId) { - return `${BE_ENDPOINT_URL}debug/ws/disconnect/${connectionId}/`; - } - - static #messageEndpoint(connectionId) { - return `${BE_ENDPOINT_URL}debug/ws/message/${connectionId}/`; - } - - static connect(userId, connectionId) { - return axios.post(this.#connectEndpoint(), { - user_pk: userId, - connection_id: connectionId, - }); - } - - static disconnect(connectionId) { - return axios.delete(this.#disconnectEndpoint(connectionId)); - } - - static message(connectionId, payload) { - return axios.post(this.#messageEndpoint(connectionId), JSON.parse(payload)); - } -} diff --git a/packages/internal/local-ws-server/index.js b/packages/internal/local-ws-server/index.js deleted file mode 100644 index a14459715..000000000 --- a/packages/internal/local-ws-server/index.js +++ /dev/null @@ -1,84 +0,0 @@ -import fastify from 'fastify'; -import { WebSocketServer } from 'ws'; -import Cookies from 'cookies'; -import { jwtDecode } from 'jwt-decode'; -import { nanoid } from 'nanoid'; - -import { Api } from './api.js'; - -const connectionsMap = {}; - -const wss = new WebSocketServer({ clientTracking: true, noServer: true }); -const app = fastify({ - logger: { - transport: { - target: 'pino-pretty', - options: { - colorize: true, - }, - }, - }, -}); - -app.server.on('upgrade', async (request, socket, head) => { - app.log.info('Upgrade connection'); - const cookies = new Cookies(request, null); - const token = cookies.get('token'); - let userId = null; - try { - const userData = jwtDecode(token); - userId = userData?.['user_id'] ?? null; - } catch (e) { - app.log.error('Unable to get user id from upgrade request'); - } - if (!userId) { - socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n'); - socket.destroy(); - } else { - try { - const connectionId = nanoid(32); - await Api.connect(userId, connectionId); - wss.handleUpgrade(request, socket, head, (ws) => { - ws.connectionId = connectionId; - connectionsMap[connectionId] = { userId, ws }; - wss.emit('connection', ws, request); - }); - } catch (e) { - app.log.error(e); - socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n'); - socket.destroy(); - } - } -}); - -app.post('/:connectionId', async (request, reply) => { - connectionsMap[request.params.connectionId]?.ws.send( - JSON.stringify(request.body), - ); - return {}; -}); - -wss.on('connection', (ws) => { - ws.on('close', async () => { - try { - delete connectionsMap[ws.connectionId]; - await Api.disconnect(ws.connectionId); - } catch (e) { - app.log.error(e); - } - }); - ws.on('message', async (data) => { - try { - await Api.message(ws.connectionId, data); - } catch (e) { - app.log.error(e); - } - }); -}); - -try { - await app.listen(8080, '0.0.0.0'); -} catch (e) { - app.log.error(e); - process.exit(1); -} diff --git a/packages/internal/local-ws-server/package.json b/packages/internal/local-ws-server/package.json deleted file mode 100644 index 26c623c39..000000000 --- a/packages/internal/local-ws-server/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "local-ws-server", - "version": "2.5.0", - "description": "WebSocket Server for local development", - "main": "index.js", - "license": "MIT", - "type": "module", - "scripts": { - "start": "nodemon index.js" - }, - "dependencies": { - "axios": "^1.6.2", - "cookies": "^0.8.0", - "fastify": "^4.24.3", - "jwt-decode": "^4.0.0", - "nanoid": "^5.0.3", - "pino-pretty": "^10.2.3", - "ws": "^8.14.2" - }, - "devDependencies": { - "nodemon": "^3.0.1" - } -} diff --git a/packages/internal/local-ws-server/project.json b/packages/internal/local-ws-server/project.json deleted file mode 100644 index 6603009b7..000000000 --- a/packages/internal/local-ws-server/project.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "root": "packages/internal/local-ws-server", - "projectType": "application", - "sourceRoot": "packages/workers", - "targets": { - "compose-build-image": { - "executor": "nx:run-commands", - "options": { - "color": true, - "commands": ["docker-compose build localwsserver"], - "parallel": false - } - } - }, - "tags": ["service"] -} diff --git a/packages/internal/local-ws-server/scripts/run.sh b/packages/internal/local-ws-server/scripts/run.sh deleted file mode 100644 index 874815c48..000000000 --- a/packages/internal/local-ws-server/scripts/run.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -yarn - -yarn start diff --git a/packages/internal/local-ws-server/yarn.lock b/packages/internal/local-ws-server/yarn.lock deleted file mode 100644 index 405d6b510..000000000 --- a/packages/internal/local-ws-server/yarn.lock +++ /dev/null @@ -1,898 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@fastify/ajv-compiler@^3.5.0": - version "3.5.0" - resolved "https://registry.yarnpkg.com/@fastify/ajv-compiler/-/ajv-compiler-3.5.0.tgz#459bff00fefbf86c96ec30e62e933d2379e46670" - integrity sha512-ebbEtlI7dxXF5ziNdr05mOY8NnDiPB1XvAlLHctRt/Rc+C3LCOVW5imUVX+mhvUhnNzmPBHewUkOFgGlCxgdAA== - dependencies: - ajv "^8.11.0" - ajv-formats "^2.1.1" - fast-uri "^2.0.0" - -"@fastify/deepmerge@^1.0.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@fastify/deepmerge/-/deepmerge-1.3.0.tgz#8116858108f0c7d9fd460d05a7d637a13fe3239a" - integrity sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A== - -"@fastify/error@^3.4.0": - version "3.4.1" - resolved "https://registry.yarnpkg.com/@fastify/error/-/error-3.4.1.tgz#b14bb4cac3dd4ec614becbc643d1511331a6425c" - integrity sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ== - -"@fastify/fast-json-stringify-compiler@^4.3.0": - version "4.3.0" - resolved "https://registry.yarnpkg.com/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-4.3.0.tgz#5df89fa4d1592cbb8780f78998355feb471646d5" - integrity sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA== - dependencies: - fast-json-stringify "^5.7.0" - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - -abstract-logging@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/abstract-logging/-/abstract-logging-2.0.1.tgz#6b0c371df212db7129b57d2e7fcf282b8bf1c839" - integrity sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA== - -ajv-formats@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" - integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== - dependencies: - ajv "^8.0.0" - -ajv@^8.0.0, ajv@^8.10.0, ajv@^8.11.0: - version "8.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -archy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -atomic-sleep@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" - integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== - -avvio@^8.2.1: - version "8.2.1" - resolved "https://registry.yarnpkg.com/avvio/-/avvio-8.2.1.tgz#b5a482729847abb84d5aadce06511c04a0a62f82" - integrity sha512-TAlMYvOuwGyLK3PfBb5WKBXZmXz2fVCgv23d6zZFdle/q3gPjmxBaeuC0pY0Dzs5PWMSgfqqEZkrye19GlDTgw== - dependencies: - archy "^1.0.0" - debug "^4.0.0" - fastq "^1.6.1" - -axios@^1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2" - integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A== - dependencies: - follow-redirects "^1.15.0" - form-data "^4.0.0" - proxy-from-env "^1.1.0" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -chokidar@^3.5.2: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -colorette@^2.0.7: - version "2.0.20" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" - integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== - -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -cookie@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== - -cookies@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.8.0.tgz#1293ce4b391740a8406e3c9870e828c4b54f3f90" - integrity sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow== - dependencies: - depd "~2.0.0" - keygrip "~1.1.0" - -dateformat@^4.6.3: - version "4.6.3" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.6.3.tgz#556fa6497e5217fedb78821424f8a1c22fa3f4b5" - integrity sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA== - -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.0.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - -depd@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - -events@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -fast-content-type-parse@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fast-content-type-parse/-/fast-content-type-parse-1.1.0.tgz#4087162bf5af3294d4726ff29b334f72e3a1092c" - integrity sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ== - -fast-copy@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/fast-copy/-/fast-copy-3.0.1.tgz#9e89ef498b8c04c1cd76b33b8e14271658a732aa" - integrity sha512-Knr7NOtK3HWRYGtHoJrjkaWepqT8thIVGAwt0p0aUs1zqkAzXZV4vo9fFNwyb5fcqK1GKYFYxldQdIDVKhUAfA== - -fast-decode-uri-component@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz#46f8b6c22b30ff7a81357d4f59abfae938202543" - integrity sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg== - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "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-json-stringify@^5.7.0: - version "5.7.0" - resolved "https://registry.yarnpkg.com/fast-json-stringify/-/fast-json-stringify-5.7.0.tgz#b0a04c848fdeb6ecd83440c71a4db35067023bed" - integrity sha512-sBVPTgnAZseLu1Qgj6lUbQ0HfjFhZWXAmpZ5AaSGkyLh5gAXBga/uPJjQPHpDFjC9adWIpdOcCLSDTgrZ7snoQ== - dependencies: - "@fastify/deepmerge" "^1.0.0" - ajv "^8.10.0" - ajv-formats "^2.1.1" - fast-deep-equal "^3.1.3" - fast-uri "^2.1.0" - rfdc "^1.2.0" - -fast-json-stringify@^5.8.0: - version "5.9.1" - resolved "https://registry.yarnpkg.com/fast-json-stringify/-/fast-json-stringify-5.9.1.tgz#c304b9dd4e5c84a62510246b7ba9f99ac4656ea5" - integrity sha512-NMrf+uU9UJnTzfxaumMDXK1NWqtPCfGoM9DYIE+ESlaTQqjlANFBy0VAbsm6FB88Mx0nceyi18zTo5kIEUlzxg== - dependencies: - "@fastify/deepmerge" "^1.0.0" - ajv "^8.10.0" - ajv-formats "^2.1.1" - fast-deep-equal "^3.1.3" - fast-uri "^2.1.0" - json-schema-ref-resolver "^1.0.1" - rfdc "^1.2.0" - -fast-querystring@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/fast-querystring/-/fast-querystring-1.1.2.tgz#a6d24937b4fc6f791b4ee31dcb6f53aeafb89f53" - integrity sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg== - dependencies: - fast-decode-uri-component "^1.0.1" - -fast-redact@^3.1.1: - version "3.2.0" - resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.2.0.tgz#b1e2d39bc731376d28bde844454fa23e26919987" - integrity sha512-zaTadChr+NekyzallAMXATXLOR8MNx3zqpZ0MUF2aGf4EathnG0f32VLODNlY8IuGY3HoRO2L6/6fSzNsLaHIw== - -fast-safe-stringify@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" - integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== - -fast-uri@^2.0.0, fast-uri@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-2.2.0.tgz#519a0f849bef714aad10e9753d69d8f758f7445a" - integrity sha512-cIusKBIt/R/oI6z/1nyfe2FvGKVTohVRfvkOhvx0nCEW+xf5NoCXjAHcWp93uOUBchzYcsvPlrapAdX1uW+YGg== - -fastify@^4.24.3: - version "4.24.3" - resolved "https://registry.yarnpkg.com/fastify/-/fastify-4.24.3.tgz#bf97a3f5158ff7f78af949d483cac4e6115fb651" - integrity sha512-6HHJ+R2x2LS3y1PqxnwEIjOTZxFl+8h4kSC/TuDPXtA+v2JnV9yEtOsNSKK1RMD7sIR2y1ZsA4BEFaid/cK5pg== - dependencies: - "@fastify/ajv-compiler" "^3.5.0" - "@fastify/error" "^3.4.0" - "@fastify/fast-json-stringify-compiler" "^4.3.0" - abstract-logging "^2.0.1" - avvio "^8.2.1" - fast-content-type-parse "^1.1.0" - fast-json-stringify "^5.8.0" - find-my-way "^7.7.0" - light-my-request "^5.11.0" - pino "^8.16.0" - process-warning "^2.2.0" - proxy-addr "^2.0.7" - rfdc "^1.3.0" - secure-json-parse "^2.7.0" - semver "^7.5.4" - toad-cache "^3.3.0" - -fastq@^1.6.1: - version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-my-way@^7.7.0: - version "7.7.0" - resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-7.7.0.tgz#d7b51ca6046782bcddd5a8435e99ad057e5a8876" - integrity sha512-+SrHpvQ52Q6W9f3wJoJBbAQULJuNEEQwBvlvYwACDhBTLOTMiQ0HYWh4+vC3OivGP2ENcTI1oKlFA2OepJNjhQ== - dependencies: - fast-deep-equal "^3.1.3" - fast-querystring "^1.0.0" - safe-regex2 "^2.0.0" - -follow-redirects@^1.15.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== - -form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@^8.0.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" - integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -help-me@^4.0.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/help-me/-/help-me-4.2.0.tgz#50712bfd799ff1854ae1d312c36eafcea85b0563" - integrity sha512-TAOnTB8Tz5Dw8penUuzHVrKNKlCIbwwbHnXraNJxPwf8LRtE2HlM84RYuezMFcwOJmoYOCWVDyJ8TQGxn9PgxA== - dependencies: - glob "^8.0.0" - readable-stream "^3.6.0" - -ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore-by-default@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" - integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.3" - 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-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -joycon@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03" - integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== - -json-schema-ref-resolver@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-schema-ref-resolver/-/json-schema-ref-resolver-1.0.1.tgz#6586f483b76254784fc1d2120f717bdc9f0a99bf" - integrity sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw== - dependencies: - fast-deep-equal "^3.1.3" - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -jwt-decode@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-4.0.0.tgz#2270352425fd413785b2faf11f6e755c5151bd4b" - integrity sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA== - -keygrip@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226" - integrity sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ== - dependencies: - tsscmp "1.0.6" - -light-my-request@^5.11.0: - version "5.11.0" - resolved "https://registry.yarnpkg.com/light-my-request/-/light-my-request-5.11.0.tgz#90e446c303b3a47b59df38406d5f5c2cf224f2d1" - integrity sha512-qkFCeloXCOMpmEdZ/MV91P8AT4fjwFXWaAFz3lUeStM8RcoM1ks4J/F8r1b3r6y/H4u3ACEJ1T+Gv5bopj7oDA== - dependencies: - cookie "^0.5.0" - process-warning "^2.0.0" - set-cookie-parser "^2.4.1" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^5.0.1: - version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== - dependencies: - brace-expansion "^2.0.1" - -minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -nanoid@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-5.0.3.tgz#6c97f53d793a7a1de6a38ebb46f50f95bf9793c7" - integrity sha512-I7X2b22cxA4LIHXPSqbBCEQSL+1wv8TuoefejsX4HFWyC6jc5JG7CEaxOltiKjc1M+YCS2YkrZZcj4+dytw9GA== - -nodemon@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.0.1.tgz#affe822a2c5f21354466b2fc8ae83277d27dadc7" - integrity sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw== - dependencies: - chokidar "^3.5.2" - debug "^3.2.7" - ignore-by-default "^1.0.1" - minimatch "^3.1.2" - pstree.remy "^1.1.8" - semver "^7.5.3" - simple-update-notifier "^2.0.0" - supports-color "^5.5.0" - touch "^3.1.0" - undefsafe "^2.0.5" - -nopt@~1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" - integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== - dependencies: - abbrev "1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -on-exit-leak-free@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz#5c703c968f7e7f851885f6459bf8a8a57edc9cc4" - integrity sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w== - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -picomatch@^2.0.4, picomatch@^2.2.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pino-abstract-transport@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz#cc0d6955fffcadb91b7b49ef220a6cc111d48bb3" - integrity sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA== - dependencies: - readable-stream "^4.0.0" - split2 "^4.0.0" - -pino-abstract-transport@v1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-1.1.0.tgz#083d98f966262164504afb989bccd05f665937a8" - integrity sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA== - dependencies: - readable-stream "^4.0.0" - split2 "^4.0.0" - -pino-pretty@^10.2.3: - version "10.2.3" - resolved "https://registry.yarnpkg.com/pino-pretty/-/pino-pretty-10.2.3.tgz#db539c796a1421fd4d130734fa994f5a26027783" - integrity sha512-4jfIUc8TC1GPUfDyMSlW1STeORqkoxec71yhxIpLDQapUu8WOuoz2TTCoidrIssyz78LZC69whBMPIKCMbi3cw== - dependencies: - colorette "^2.0.7" - dateformat "^4.6.3" - fast-copy "^3.0.0" - fast-safe-stringify "^2.1.1" - help-me "^4.0.1" - joycon "^3.1.1" - minimist "^1.2.6" - on-exit-leak-free "^2.1.0" - pino-abstract-transport "^1.0.0" - pump "^3.0.0" - readable-stream "^4.0.0" - secure-json-parse "^2.4.0" - sonic-boom "^3.0.0" - strip-json-comments "^3.1.1" - -pino-std-serializers@^6.0.0: - version "6.2.2" - resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz#d9a9b5f2b9a402486a5fc4db0a737570a860aab3" - integrity sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA== - -pino@^8.16.0: - version "8.16.2" - resolved "https://registry.yarnpkg.com/pino/-/pino-8.16.2.tgz#7a906f2d9a8c5b4c57412c9ca95d6820bd2090cd" - integrity sha512-2advCDGVEvkKu9TTVSa/kWW7Z3htI/sBKEZpqiHk6ive0i/7f5b1rsU8jn0aimxqfnSz5bj/nOYkwhBUn5xxvg== - dependencies: - atomic-sleep "^1.0.0" - fast-redact "^3.1.1" - on-exit-leak-free "^2.1.0" - pino-abstract-transport v1.1.0 - pino-std-serializers "^6.0.0" - process-warning "^2.0.0" - quick-format-unescaped "^4.0.3" - real-require "^0.2.0" - safe-stable-stringify "^2.3.1" - sonic-boom "^3.7.0" - thread-stream "^2.0.0" - -process-warning@^2.0.0, process-warning@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-2.2.0.tgz#008ec76b579820a8e5c35d81960525ca64feb626" - integrity sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg== - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== - -proxy-addr@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -proxy-from-env@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== - -pstree.remy@^1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" - integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -quick-format-unescaped@^4.0.3: - version "4.0.4" - resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" - integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== - -readable-stream@^3.6.0: - version "3.6.0" - 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" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@^4.0.0: - version "4.4.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.4.2.tgz#e6aced27ad3b9d726d8308515b9a1b98dc1b9d13" - integrity sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA== - dependencies: - abort-controller "^3.0.0" - buffer "^6.0.3" - events "^3.3.0" - process "^0.11.10" - string_decoder "^1.3.0" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -real-require@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.2.0.tgz#209632dea1810be2ae063a6ac084fee7e33fba78" - integrity sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg== - -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -ret@~0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.2.2.tgz#b6861782a1f4762dce43402a71eb7a283f44573c" - integrity sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rfdc@^1.2.0, 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== - -safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-regex2@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/safe-regex2/-/safe-regex2-2.0.0.tgz#b287524c397c7a2994470367e0185e1916b1f5b9" - integrity sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ== - dependencies: - ret "~0.2.0" - -safe-stable-stringify@^2.3.1: - version "2.4.3" - resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" - integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== - -secure-json-parse@^2.4.0, secure-json-parse@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862" - integrity sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw== - -semver@^7.5.3, semver@^7.5.4: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -set-cookie-parser@^2.4.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.5.1.tgz#ddd3e9a566b0e8e0862aca974a6ac0e01349430b" - integrity sha512-1jeBGaKNGdEq4FgIrORu/N570dwoPYio8lSoYLWmX7sQ//0JY08Xh9o5pBcgmHQ/MbsYp/aZnOe1s1lIsbLprQ== - -simple-update-notifier@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz#d70b92bdab7d6d90dfd73931195a30b6e3d7cebb" - integrity sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w== - dependencies: - semver "^7.5.3" - -sonic-boom@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-3.3.0.tgz#cffab6dafee3b2bcb88d08d589394198bee1838c" - integrity sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g== - dependencies: - atomic-sleep "^1.0.0" - -sonic-boom@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-3.7.0.tgz#b4b7b8049a912986f4a92c51d4660b721b11f2f2" - integrity sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg== - dependencies: - atomic-sleep "^1.0.0" - -split2@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" - integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== - -string_decoder@^1.1.1, string_decoder@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -thread-stream@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-2.3.0.tgz#4fc07fb39eff32ae7bad803cb7dd9598349fed33" - integrity sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA== - dependencies: - real-require "^0.2.0" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toad-cache@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/toad-cache/-/toad-cache-3.3.0.tgz#5b7dc67b36bc8b960567eb77bdf9ac6c26f204a1" - integrity sha512-3oDzcogWGHZdkwrHyvJVpPjA7oNzY6ENOV3PsWJY9XYPZ6INo94Yd47s5may1U+nleBPwDhrRiTPMIvKaa3MQg== - -touch@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" - integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== - dependencies: - nopt "~1.0.10" - -tsscmp@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" - integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== - -undefsafe@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" - integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -ws@^8.14.2: - version "8.16.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" - integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/packages/webapp-libs/webapp-api-client/graphql/schema/api.graphql b/packages/webapp-libs/webapp-api-client/graphql/schema/api.graphql index 849808917..bf98334f5 100644 --- a/packages/webapp-libs/webapp-api-client/graphql/schema/api.graphql +++ b/packages/webapp-libs/webapp-api-client/graphql/schema/api.graphql @@ -926,7 +926,11 @@ type DeleteFavoriteContentfulDemoItemMutationPayload { clientMutationId: String } type ApiSubscription { - notificationCreated(before: String, after: String, first: Int, last: Int): NotificationConnection + notificationCreated: NotificationCreatedSubscription +} +"Simple GraphQL subscription." +type NotificationCreatedSubscription { + notification: NotificationType } "An object with an ID" interface Node { diff --git a/packages/webapp-libs/webapp-api-client/package.json b/packages/webapp-libs/webapp-api-client/package.json index 6cac4f4da..49635d739 100644 --- a/packages/webapp-libs/webapp-api-client/package.json +++ b/packages/webapp-libs/webapp-api-client/package.json @@ -27,6 +27,7 @@ "@types/apollo-upload-client": "^17.0.5", "fs-extra": "^11.2.0", "graphql-ws": "^5.14.2", - "msw": "^1.3.2" + "msw": "^1.3.2", + "subscriptions-transport-ws": "^0.11.0" } } diff --git a/packages/webapp-libs/webapp-api-client/src/graphql/__generated/gql/gql.ts b/packages/webapp-libs/webapp-api-client/src/graphql/__generated/gql/gql.ts index 62f2ec11d..63b2f49c6 100644 --- a/packages/webapp-libs/webapp-api-client/src/graphql/__generated/gql/gql.ts +++ b/packages/webapp-libs/webapp-api-client/src/graphql/__generated/gql/gql.ts @@ -58,9 +58,10 @@ const documents = { "\n mutation generateSaasIdeasMutation($input: GenerateSaasIdeasMutationInput!) {\n generateSaasIdeas(input: $input) {\n ideas\n }\n }\n": types.GenerateSaasIdeasMutationDocument, "\n mutation notificationMutation($input: UpdateNotificationMutationInput!) {\n updateNotification(input: $input) {\n hasUnreadNotifications\n notificationEdge {\n node {\n id\n readAt\n }\n }\n }\n }\n": types.NotificationMutationDocument, "\n query notificationsListQuery($count: Int = 20, $cursor: String) {\n ...notificationsListContentFragment\n ...notificationsButtonContent\n }\n": types.NotificationsListQueryDocument, - "\n subscription notificationsListSubscription {\n notificationCreated {\n edges {\n node {\n id\n type\n createdAt\n readAt\n data\n issuer {\n id\n avatar\n email\n }\n }\n }\n }\n }\n": types.NotificationsListSubscriptionDocument, + "\n subscription NotificationCreatedSubscription {\n notificationCreated {\n notification {\n ...notificationsListItemFragment\n }\n }\n }\n": types.NotificationCreatedSubscriptionDocument, "\n fragment notificationsButtonContent on Query {\n hasUnreadNotifications\n }\n": types.NotificationsButtonContentFragmentDoc, - "\n fragment notificationsListContentFragment on Query {\n hasUnreadNotifications\n allNotifications(first: $count, after: $cursor) {\n edges {\n node {\n id\n data\n createdAt\n readAt\n type\n issuer {\n id\n avatar\n email\n }\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n": types.NotificationsListContentFragmentFragmentDoc, + "\n fragment notificationsListContentFragment on Query {\n hasUnreadNotifications\n allNotifications(first: $count, after: $cursor) {\n edges {\n node {\n id\n ...notificationsListItemFragment\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n": types.NotificationsListContentFragmentFragmentDoc, + "\n fragment notificationsListItemFragment on NotificationType {\n id\n data\n createdAt\n readAt\n type\n issuer {\n id\n avatar\n email\n }\n }\n": types.NotificationsListItemFragmentFragmentDoc, "\n mutation notificationsListMarkAsReadMutation($input: MarkReadAllNotificationsMutationInput!) {\n markReadAllNotifications(input: $input) {\n ok\n }\n }\n": types.NotificationsListMarkAsReadMutationDocument, "\n mutation authConfirmUserEmailMutation($input: ConfirmEmailMutationInput!) {\n confirm(input: $input) {\n ok\n }\n }\n": types.AuthConfirmUserEmailMutationDocument, "\n mutation authChangePasswordMutation($input: ChangePasswordMutationInput!) {\n changePassword(input: $input) {\n access\n refresh\n }\n }\n": types.AuthChangePasswordMutationDocument, @@ -272,7 +273,7 @@ export function gql(source: "\n query notificationsListQuery($count: Int = 20, /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function gql(source: "\n subscription notificationsListSubscription {\n notificationCreated {\n edges {\n node {\n id\n type\n createdAt\n readAt\n data\n issuer {\n id\n avatar\n email\n }\n }\n }\n }\n }\n"): (typeof documents)["\n subscription notificationsListSubscription {\n notificationCreated {\n edges {\n node {\n id\n type\n createdAt\n readAt\n data\n issuer {\n id\n avatar\n email\n }\n }\n }\n }\n }\n"]; +export function gql(source: "\n subscription NotificationCreatedSubscription {\n notificationCreated {\n notification {\n ...notificationsListItemFragment\n }\n }\n }\n"): (typeof documents)["\n subscription NotificationCreatedSubscription {\n notificationCreated {\n notification {\n ...notificationsListItemFragment\n }\n }\n }\n"]; /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -280,7 +281,11 @@ export function gql(source: "\n fragment notificationsButtonContent on Query {\ /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function gql(source: "\n fragment notificationsListContentFragment on Query {\n hasUnreadNotifications\n allNotifications(first: $count, after: $cursor) {\n edges {\n node {\n id\n data\n createdAt\n readAt\n type\n issuer {\n id\n avatar\n email\n }\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n"): (typeof documents)["\n fragment notificationsListContentFragment on Query {\n hasUnreadNotifications\n allNotifications(first: $count, after: $cursor) {\n edges {\n node {\n id\n data\n createdAt\n readAt\n type\n issuer {\n id\n avatar\n email\n }\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n"]; +export function gql(source: "\n fragment notificationsListContentFragment on Query {\n hasUnreadNotifications\n allNotifications(first: $count, after: $cursor) {\n edges {\n node {\n id\n ...notificationsListItemFragment\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n"): (typeof documents)["\n fragment notificationsListContentFragment on Query {\n hasUnreadNotifications\n allNotifications(first: $count, after: $cursor) {\n edges {\n node {\n id\n ...notificationsListItemFragment\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n"]; +/** + * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function gql(source: "\n fragment notificationsListItemFragment on NotificationType {\n id\n data\n createdAt\n readAt\n type\n issuer {\n id\n avatar\n email\n }\n }\n"): (typeof documents)["\n fragment notificationsListItemFragment on NotificationType {\n id\n data\n createdAt\n readAt\n type\n issuer {\n id\n avatar\n email\n }\n }\n"]; /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/packages/webapp-libs/webapp-api-client/src/graphql/__generated/gql/graphql.ts b/packages/webapp-libs/webapp-api-client/src/graphql/__generated/gql/graphql.ts index 61333e7c4..323b2565f 100644 --- a/packages/webapp-libs/webapp-api-client/src/graphql/__generated/gql/graphql.ts +++ b/packages/webapp-libs/webapp-api-client/src/graphql/__generated/gql/graphql.ts @@ -229,15 +229,7 @@ export type ApiMutationVerifyOtpArgs = { export type ApiSubscription = { __typename?: 'ApiSubscription'; - notificationCreated?: Maybe; -}; - - -export type ApiSubscriptionNotificationCreatedArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; + notificationCreated?: Maybe; }; /** [See type definition](https://app.contentful.com/spaces/m7e7pnsr61vp/content_types/appConfig) */ @@ -1593,6 +1585,12 @@ export type NotificationConnection = { pageInfo: PageInfo; }; +/** Simple GraphQL subscription. */ +export type NotificationCreatedSubscription = { + __typename?: 'NotificationCreatedSubscription'; + notification?: Maybe; +}; + /** A Relay edge containing a `Notification` and its cursor. */ export type NotificationEdge = { __typename?: 'NotificationEdge'; @@ -2974,14 +2972,22 @@ export type NotificationsListQueryQuery = ( & { ' $fragmentRefs'?: { 'NotificationsListContentFragmentFragment': NotificationsListContentFragmentFragment;'NotificationsButtonContentFragment': NotificationsButtonContentFragment } } ); -export type NotificationsListSubscriptionSubscriptionVariables = Exact<{ [key: string]: never; }>; +export type NotificationCreatedSubscriptionSubscriptionVariables = Exact<{ [key: string]: never; }>; -export type NotificationsListSubscriptionSubscription = { __typename?: 'ApiSubscription', notificationCreated?: { __typename?: 'NotificationConnection', edges: Array<{ __typename?: 'NotificationEdge', node?: { __typename?: 'NotificationType', id: string, type: string, createdAt: any, readAt?: any | null, data?: any | null, issuer?: { __typename?: 'UserType', id: string, avatar?: string | null, email: string } | null } | null } | null> } | null }; +export type NotificationCreatedSubscriptionSubscription = { __typename?: 'ApiSubscription', notificationCreated?: { __typename?: 'NotificationCreatedSubscription', notification?: ( + { __typename?: 'NotificationType' } + & { ' $fragmentRefs'?: { 'NotificationsListItemFragmentFragment': NotificationsListItemFragmentFragment } } + ) | null } | null }; export type NotificationsButtonContentFragment = { __typename?: 'Query', hasUnreadNotifications?: boolean | null } & { ' $fragmentName'?: 'NotificationsButtonContentFragment' }; -export type NotificationsListContentFragmentFragment = { __typename?: 'Query', hasUnreadNotifications?: boolean | null, allNotifications?: { __typename?: 'NotificationConnection', edges: Array<{ __typename?: 'NotificationEdge', node?: { __typename?: 'NotificationType', id: string, data?: any | null, createdAt: any, readAt?: any | null, type: string, issuer?: { __typename?: 'UserType', id: string, avatar?: string | null, email: string } | null } | null } | null>, pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean } } | null } & { ' $fragmentName'?: 'NotificationsListContentFragmentFragment' }; +export type NotificationsListContentFragmentFragment = { __typename?: 'Query', hasUnreadNotifications?: boolean | null, allNotifications?: { __typename?: 'NotificationConnection', edges: Array<{ __typename?: 'NotificationEdge', node?: ( + { __typename?: 'NotificationType', id: string } + & { ' $fragmentRefs'?: { 'NotificationsListItemFragmentFragment': NotificationsListItemFragmentFragment } } + ) | null } | null>, pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean } } | null } & { ' $fragmentName'?: 'NotificationsListContentFragmentFragment' }; + +export type NotificationsListItemFragmentFragment = { __typename?: 'NotificationType', id: string, data?: any | null, createdAt: any, readAt?: any | null, type: string, issuer?: { __typename?: 'UserType', id: string, avatar?: string | null, email: string } | null } & { ' $fragmentName'?: 'NotificationsListItemFragmentFragment' }; export type NotificationsListMarkAsReadMutationMutationVariables = Exact<{ input: MarkReadAllNotificationsMutationInput; @@ -3085,7 +3091,8 @@ export const StripePaymentMethodFragmentFragmentDoc = {"kind":"Document","defini export const SubscriptionPlanItemFragmentFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"subscriptionPlanItemFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SubscriptionPlanType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"pk"}},{"kind":"Field","name":{"kind":"Name","value":"product"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"amount"}}]}}]} as unknown as DocumentNode; export const StripeChargeFragmentFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"stripeChargeFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"StripeChargeType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"billingDetails"}},{"kind":"Field","name":{"kind":"Name","value":"paymentMethod"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"stripePaymentMethodFragment"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"invoice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"subscription"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"plan"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"subscriptionPlanItemFragment"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"stripePaymentMethodFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"StripePaymentMethodType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"pk"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"card"}},{"kind":"Field","name":{"kind":"Name","value":"billingDetails"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"subscriptionPlanItemFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SubscriptionPlanType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"pk"}},{"kind":"Field","name":{"kind":"Name","value":"product"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"amount"}}]}}]} as unknown as DocumentNode; export const NotificationsButtonContentFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"notificationsButtonContent"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hasUnreadNotifications"}}]}}]} as unknown as DocumentNode; -export const NotificationsListContentFragmentFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"notificationsListContentFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hasUnreadNotifications"}},{"kind":"Field","name":{"kind":"Name","value":"allNotifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"first"},"value":{"kind":"Variable","name":{"kind":"Name","value":"count"}}},{"kind":"Argument","name":{"kind":"Name","value":"after"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"data"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"readAt"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"issuer"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"endCursor"}},{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}}]}}]}}]}}]} as unknown as DocumentNode; +export const NotificationsListItemFragmentFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"notificationsListItemFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"NotificationType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"data"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"readAt"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"issuer"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}}]}}]} as unknown as DocumentNode; +export const NotificationsListContentFragmentFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"notificationsListContentFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hasUnreadNotifications"}},{"kind":"Field","name":{"kind":"Name","value":"allNotifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"first"},"value":{"kind":"Variable","name":{"kind":"Name","value":"count"}}},{"kind":"Argument","name":{"kind":"Name","value":"after"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"notificationsListItemFragment"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"endCursor"}},{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"notificationsListItemFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"NotificationType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"data"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"readAt"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"issuer"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}}]}}]} as unknown as DocumentNode; export const PaginationListTestQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"paginationListTestQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"first"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"after"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"last"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"before"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"allNotifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"first"},"value":{"kind":"Variable","name":{"kind":"Name","value":"first"}}},{"kind":"Argument","name":{"kind":"Name","value":"after"},"value":{"kind":"Variable","name":{"kind":"Name","value":"after"}}},{"kind":"Argument","name":{"kind":"Name","value":"last"},"value":{"kind":"Variable","name":{"kind":"Name","value":"last"}}},{"kind":"Argument","name":{"kind":"Name","value":"before"},"value":{"kind":"Variable","name":{"kind":"Name","value":"before"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"startCursor"}},{"kind":"Field","name":{"kind":"Name","value":"endCursor"}},{"kind":"Field","name":{"kind":"Name","value":"hasPreviousPage"}},{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}}]}}]}}]}}]} as unknown as DocumentNode; export const CommonQueryCurrentUserQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"commonQueryCurrentUserQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"currentUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"commonQueryCurrentUserFragment"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"commonQueryCurrentUserFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CurrentUserType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"roles"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"otpVerified"}},{"kind":"Field","name":{"kind":"Name","value":"otpEnabled"}}]}}]} as unknown as DocumentNode; export const ConfigContentfulAppConfigQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"configContentfulAppConfigQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"appConfigCollection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"1"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"privacyPolicy"}},{"kind":"Field","name":{"kind":"Name","value":"termsAndConditions"}}]}}]}}]}}]} as unknown as DocumentNode; @@ -3118,8 +3125,8 @@ export const SubscriptionPlansAllQueryDocument = {"kind":"Document","definitions export const StripeAllChargesQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"stripeAllChargesQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"allCharges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"stripeChargeFragment"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"stripePaymentMethodFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"StripePaymentMethodType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"pk"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"card"}},{"kind":"Field","name":{"kind":"Name","value":"billingDetails"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"subscriptionPlanItemFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SubscriptionPlanType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"pk"}},{"kind":"Field","name":{"kind":"Name","value":"product"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"amount"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"stripeChargeFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"StripeChargeType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"billingDetails"}},{"kind":"Field","name":{"kind":"Name","value":"paymentMethod"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"stripePaymentMethodFragment"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"invoice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"subscription"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"plan"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"subscriptionPlanItemFragment"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const GenerateSaasIdeasMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"generateSaasIdeasMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GenerateSaasIdeasMutationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"generateSaasIdeas"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"ideas"}}]}}]}}]} as unknown as DocumentNode; export const NotificationMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"notificationMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateNotificationMutationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateNotification"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hasUnreadNotifications"}},{"kind":"Field","name":{"kind":"Name","value":"notificationEdge"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"readAt"}}]}}]}}]}}]}}]} as unknown as DocumentNode; -export const NotificationsListQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"notificationsListQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"count"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}},"defaultValue":{"kind":"IntValue","value":"20"}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"notificationsListContentFragment"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"notificationsButtonContent"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"notificationsListContentFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hasUnreadNotifications"}},{"kind":"Field","name":{"kind":"Name","value":"allNotifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"first"},"value":{"kind":"Variable","name":{"kind":"Name","value":"count"}}},{"kind":"Argument","name":{"kind":"Name","value":"after"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"data"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"readAt"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"issuer"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"endCursor"}},{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"notificationsButtonContent"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hasUnreadNotifications"}}]}}]} as unknown as DocumentNode; -export const NotificationsListSubscriptionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"subscription","name":{"kind":"Name","value":"notificationsListSubscription"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"notificationCreated"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"readAt"}},{"kind":"Field","name":{"kind":"Name","value":"data"}},{"kind":"Field","name":{"kind":"Name","value":"issuer"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; +export const NotificationsListQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"notificationsListQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"count"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}},"defaultValue":{"kind":"IntValue","value":"20"}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"notificationsListContentFragment"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"notificationsButtonContent"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"notificationsListItemFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"NotificationType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"data"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"readAt"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"issuer"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"notificationsListContentFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hasUnreadNotifications"}},{"kind":"Field","name":{"kind":"Name","value":"allNotifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"first"},"value":{"kind":"Variable","name":{"kind":"Name","value":"count"}}},{"kind":"Argument","name":{"kind":"Name","value":"after"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"notificationsListItemFragment"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"endCursor"}},{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"notificationsButtonContent"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Query"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hasUnreadNotifications"}}]}}]} as unknown as DocumentNode; +export const NotificationCreatedSubscriptionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"subscription","name":{"kind":"Name","value":"NotificationCreatedSubscription"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"notificationCreated"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"notification"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"notificationsListItemFragment"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"notificationsListItemFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"NotificationType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"data"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"readAt"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"issuer"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}}]}}]} as unknown as DocumentNode; export const NotificationsListMarkAsReadMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"notificationsListMarkAsReadMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"MarkReadAllNotificationsMutationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"markReadAllNotifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"ok"}}]}}]}}]} as unknown as DocumentNode; export const AuthConfirmUserEmailMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"authConfirmUserEmailMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ConfirmEmailMutationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"confirm"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"ok"}}]}}]}}]} as unknown as DocumentNode; export const AuthChangePasswordMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"authChangePasswordMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ChangePasswordMutationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"changePassword"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"access"}},{"kind":"Field","name":{"kind":"Name","value":"refresh"}}]}}]}}]} as unknown as DocumentNode; diff --git a/packages/webapp-libs/webapp-api-client/src/graphql/apolloClient.ts b/packages/webapp-libs/webapp-api-client/src/graphql/apolloClient.ts index 7259370fb..e54976b4f 100644 --- a/packages/webapp-libs/webapp-api-client/src/graphql/apolloClient.ts +++ b/packages/webapp-libs/webapp-api-client/src/graphql/apolloClient.ts @@ -3,36 +3,21 @@ import { GraphQLErrors, NetworkError } from '@apollo/client/errors'; import { FetchResult } from '@apollo/client/link/core'; import { onError } from '@apollo/client/link/error'; import { RetryLink } from '@apollo/client/link/retry'; -import { GraphQLWsLink } from '@apollo/client/link/subscriptions'; import { getMainDefinition, relayStylePagination } from '@apollo/client/utilities'; import { ENV } from '@sb/webapp-core/config/env'; import { ToastEmitterActions } from '@sb/webapp-core/toast'; import { createUploadLink } from 'apollo-upload-client'; -import { createClient } from 'graphql-ws'; import { Kind, OperationTypeNode } from 'graphql/language'; import { apiURL, auth } from '../api'; import { Emitter } from '../utils/eventEmitter'; import { SchemaType } from './types'; +import { WebSocketLink } from './webSocketLink'; const IS_LOCAL_ENV = ENV.ENVIRONMENT_NAME === 'local'; export const emitter = new Emitter(); -export const subscriptionClient = createClient({ - url: ENV.SUBSCRIPTIONS_URL, - lazy: true, - connectionAckWaitTimeout: 15000, - connectionParams: () => { - return {}; - }, - on: { - error: async () => { - await auth.refreshToken(); - }, - }, -}); - const httpApiLink = createUploadLink({ uri: apiURL('/graphql/'), }); @@ -108,7 +93,7 @@ const splitHttpLink = split( httpContentfulLink ); -const wsLink = new GraphQLWsLink(subscriptionClient); +const wsLink = new WebSocketLink(); const splitLink = split( ({ query }) => { @@ -146,6 +131,7 @@ export const client = new ApolloClient({ }); export const invalidateApolloStore = () => { + wsLink.reconnect(); client.stop(); client.resetStore(); }; diff --git a/packages/webapp-libs/webapp-api-client/src/graphql/webSocketLink.ts b/packages/webapp-libs/webapp-api-client/src/graphql/webSocketLink.ts new file mode 100644 index 000000000..90dcc7858 --- /dev/null +++ b/packages/webapp-libs/webapp-api-client/src/graphql/webSocketLink.ts @@ -0,0 +1,30 @@ +import { ApolloLink, Observable, Operation } from '@apollo/client'; +import { FetchResult } from '@apollo/client/link/core'; +import { SubscriptionClient } from 'subscriptions-transport-ws'; + +export class WebSocketLink extends ApolloLink { + subscriptionClient: SubscriptionClient; + + constructor() { + super(); + this.subscriptionClient = this.createClient(); + } + + private createClient() { + return new SubscriptionClient( + `${window.location.protocol.startsWith('https') ? 'wss' : 'ws'}://${window.location.host}/api/graphql/`, + { + reconnect: true, + } + ); + } + + public reconnect() { + this.subscriptionClient?.close(); + this.subscriptionClient = this.createClient(); + } + + override request(operation: Operation): Observable | null { + return this.subscriptionClient.request(operation) as Observable | null; + } +} diff --git a/packages/webapp-libs/webapp-core/src/config/env.d.ts b/packages/webapp-libs/webapp-core/src/config/env.d.ts index 084317576..216ec0947 100644 --- a/packages/webapp-libs/webapp-core/src/config/env.d.ts +++ b/packages/webapp-libs/webapp-core/src/config/env.d.ts @@ -2,7 +2,6 @@ interface ImportMetaEnv { readonly VITE_BASE_API_URL: string; - readonly VITE_SUBSCRIPTIONS_URL: string; readonly VITE_ENVIRONMENT_NAME: string; readonly VITE_SENTRY_DSN: string; readonly VITE_WEB_APP_URL: string; diff --git a/packages/webapp-libs/webapp-core/src/config/env.ts b/packages/webapp-libs/webapp-core/src/config/env.ts index 29ef84555..951fcac82 100644 --- a/packages/webapp-libs/webapp-core/src/config/env.ts +++ b/packages/webapp-libs/webapp-core/src/config/env.ts @@ -2,7 +2,6 @@ export const ENV = { BASE_API_URL: process.env.VITE_BASE_API_URL ?? '', - SUBSCRIPTIONS_URL: process.env.VITE_SUBSCRIPTIONS_URL ?? '', ENVIRONMENT_NAME: process.env.VITE_ENVIRONMENT_NAME, SENTRY_DSN: process.env.VITE_SENTRY_DSN, WEB_APP_URL: process.env.VITE_WEB_APP_URL ?? '', diff --git a/packages/webapp-libs/webapp-notifications/src/__tests__/notifications.component.spec.tsx b/packages/webapp-libs/webapp-notifications/src/__tests__/notifications.component.spec.tsx index 5d26015ce..6e9483d81 100644 --- a/packages/webapp-libs/webapp-notifications/src/__tests__/notifications.component.spec.tsx +++ b/packages/webapp-libs/webapp-notifications/src/__tests__/notifications.component.spec.tsx @@ -3,9 +3,9 @@ import { screen } from '@testing-library/react'; import { userEvent } from '@testing-library/user-event'; import { ElementType } from 'react'; -import { fillNotificationsSubscriptionQuery, notificationFactory } from '../tests/factories'; import { Notifications } from '../notifications.component'; import { NotificationTypes } from '../notifications.types'; +import { fillNotificationCreatedSubscriptionQuery, notificationFactory } from '../tests/factories'; import { render } from '../tests/utils/rendering'; describe('Notifications: Component', () => { @@ -19,13 +19,10 @@ describe('Notifications: Component', () => { it('Should show trigger button', async () => { const apolloMocks = [ fillCommonQueryWithUser(), - fillNotificationsSubscriptionQuery( - [ - notificationFactory({ - type: 'some_random_type_that_doesnt_exist', - }), - ], - { hasUnreadNotifications: true } + fillNotificationCreatedSubscriptionQuery( + notificationFactory({ + type: 'some_random_type_that_doesnt_exist', + }) ), ]; diff --git a/packages/webapp-libs/webapp-notifications/src/notifications.component.tsx b/packages/webapp-libs/webapp-notifications/src/notifications.component.tsx index 2becef2d7..f6f306a10 100644 --- a/packages/webapp-libs/webapp-notifications/src/notifications.component.tsx +++ b/packages/webapp-libs/webapp-notifications/src/notifications.component.tsx @@ -1,12 +1,16 @@ -import { NetworkStatus, useQuery } from '@apollo/client'; -import { ResultOf } from '@graphql-typed-document-node/core'; +import { NetworkStatus, useQuery, useSubscription } from '@apollo/client'; +import { getFragmentData } from '@sb/webapp-api-client'; import { Popover, PopoverContent, PopoverTrigger } from '@sb/webapp-core/components/popover'; -import { ElementType, FC, useEffect } from 'react'; +import { ElementType, FC } from 'react'; -import { notificationsListQuery, notificationsListSubscription } from './notifications.graphql'; +import { notificationCreatedSubscription, notificationsListQuery } from './notifications.graphql'; import { NotificationTypes } from './notifications.types'; import { NotificationsButton, NotificationsButtonFallback } from './notificationsButton'; -import { NotificationsList, notificationsListContentFragment } from './notificationsList'; +import { + NotificationsList, + notificationsListContentFragment, + notificationsListItemFragment, +} from './notificationsList'; import { NOTIFICATIONS_PER_PAGE } from './notificationsList/notificationsList.constants'; type NotificationsProps = { @@ -14,34 +18,37 @@ type NotificationsProps = { }; export const Notifications: FC = ({ templates }) => { - const { loading, data, fetchMore, networkStatus, subscribeToMore } = useQuery(notificationsListQuery); + const { loading, data, fetchMore, networkStatus } = useQuery(notificationsListQuery); + useSubscription(notificationCreatedSubscription, { + onData: (options) => { + const notificationData = getFragmentData( + notificationsListItemFragment, + options.data?.data?.notificationCreated?.notification + ); + options.client.cache.updateQuery({ query: notificationsListQuery }, (prev) => { + const prevListData = getFragmentData(notificationsListContentFragment, prev); + const alreadyExists = prevListData?.allNotifications?.edges?.find((edge) => { + const nodeData = getFragmentData(notificationsListItemFragment, edge?.node); + return nodeData?.id === notificationData?.id; + }); + if (alreadyExists) { + return prev; + } - useEffect(() => { - subscribeToMore({ - document: notificationsListSubscription, - updateQuery: ( - prev: ResultOf, - { subscriptionData } - ): ResultOf => ({ - ...prev, - allNotifications: { - __typename: 'NotificationConnection', - pageInfo: { - __typename: 'PageInfo', - endCursor: null, - hasNextPage: false, + return { + ...prev, + allNotifications: { + ...(prevListData?.allNotifications ?? {}), + edges: [ + ...(notificationData ? [{ node: notificationData }] : []), + ...(prevListData?.allNotifications?.edges ?? []), + ], }, - ...(prev?.allNotifications ?? {}), - - edges: [ - ...(subscriptionData.data?.notificationCreated?.edges ?? []), - ...(prev.allNotifications?.edges ?? []), - ], - }, - hasUnreadNotifications: true, - }), - }); - }, [subscribeToMore]); + hasUnreadNotifications: true, + }; + }); + }, + }); if (loading && networkStatus === NetworkStatus.loading) { return ; diff --git a/packages/webapp-libs/webapp-notifications/src/notifications.graphql.ts b/packages/webapp-libs/webapp-notifications/src/notifications.graphql.ts index 652a389af..0dac611e6 100644 --- a/packages/webapp-libs/webapp-notifications/src/notifications.graphql.ts +++ b/packages/webapp-libs/webapp-notifications/src/notifications.graphql.ts @@ -7,22 +7,11 @@ export const notificationsListQuery = gql(/* GraphQL */ ` } `); -export const notificationsListSubscription = gql(/* GraphQL */ ` - subscription notificationsListSubscription { +export const notificationCreatedSubscription = gql(/* GraphQL */ ` + subscription NotificationCreatedSubscription { notificationCreated { - edges { - node { - id - type - createdAt - readAt - data - issuer { - id - avatar - email - } - } + notification { + ...notificationsListItemFragment } } } diff --git a/packages/webapp-libs/webapp-notifications/src/notificationsList/__tests__/notificationsList.component.spec.tsx b/packages/webapp-libs/webapp-notifications/src/notificationsList/__tests__/notificationsList.component.spec.tsx index 03a9e7fa9..26b378cb7 100644 --- a/packages/webapp-libs/webapp-notifications/src/notificationsList/__tests__/notificationsList.component.spec.tsx +++ b/packages/webapp-libs/webapp-notifications/src/notificationsList/__tests__/notificationsList.component.spec.tsx @@ -81,7 +81,7 @@ describe('NotificationsList: Component', () => { it('should not render wrong notifications', async () => { const correctNotifications = times(() => notificationFactory(), 3); const malformedNotification = notificationFactory({ - data: null, + type: "malformed-notification", }); renderWithNotifications([...correctNotifications, malformedNotification], { hasUnreadNotifications: false }); diff --git a/packages/webapp-libs/webapp-notifications/src/notificationsList/notificationsList.component.tsx b/packages/webapp-libs/webapp-notifications/src/notificationsList/notificationsList.component.tsx index 7054a0f06..e8ae8bdc1 100644 --- a/packages/webapp-libs/webapp-notifications/src/notificationsList/notificationsList.component.tsx +++ b/packages/webapp-libs/webapp-notifications/src/notificationsList/notificationsList.component.tsx @@ -1,4 +1,4 @@ -import { FragmentType } from '@sb/webapp-api-client/graphql'; +import { FragmentType, getFragmentData } from '@sb/webapp-api-client/graphql'; import { Button, ButtonVariant } from '@sb/webapp-core/components/buttons'; import { EmptyState } from '@sb/webapp-core/components/emptyState'; import { Separator } from '@sb/webapp-core/components/separator'; @@ -13,7 +13,7 @@ import { FormattedMessage, useIntl } from 'react-intl'; import { NotificationTypes } from '../notifications.types'; import { NotificationErrorBoundary } from './notificationErrorBoundary'; import { NOTIFICATIONS_PER_PAGE } from './notificationsList.constants'; -import { notificationsListContentFragment } from './notificationsList.graphql'; +import { notificationsListContentFragment, notificationsListItemFragment } from './notificationsList.graphql'; import { useMarkAllAsRead, useNotificationsListContent } from './notificationsList.hooks'; export type NotificationsListProps = { @@ -93,13 +93,14 @@ const Content = ({ templates, queryResult, loading, onLoadMore }: ContentProps) return ( <> {allNotifications.map((notification) => { - const NotificationComponent = templates[notification.type as NotificationTypes] as ElementType | undefined; - if (!notification.data || !NotificationComponent) { + const notificationData = getFragmentData(notificationsListItemFragment, notification); + const NotificationComponent = templates[notificationData.type as NotificationTypes] as ElementType | undefined; + if (!notificationData || !NotificationComponent) { return null; } return ( - + ); })} diff --git a/packages/webapp-libs/webapp-notifications/src/notificationsList/notificationsList.graphql.ts b/packages/webapp-libs/webapp-notifications/src/notificationsList/notificationsList.graphql.ts index e6aeab1bc..6fbcbab84 100644 --- a/packages/webapp-libs/webapp-notifications/src/notificationsList/notificationsList.graphql.ts +++ b/packages/webapp-libs/webapp-notifications/src/notificationsList/notificationsList.graphql.ts @@ -7,15 +7,7 @@ export const notificationsListContentFragment = gql(/* GraphQL */ ` edges { node { id - data - createdAt - readAt - type - issuer { - id - avatar - email - } + ...notificationsListItemFragment } } pageInfo { @@ -26,6 +18,21 @@ export const notificationsListContentFragment = gql(/* GraphQL */ ` } `); +export const notificationsListItemFragment = gql(/* GraphQL */ ` + fragment notificationsListItemFragment on NotificationType { + id + data + createdAt + readAt + type + issuer { + id + avatar + email + } + } +`); + export const notificationsListMarkAsReadMutation = gql(/* GraphQL */ ` mutation notificationsListMarkAsReadMutation($input: MarkReadAllNotificationsMutationInput!) { markReadAllNotifications(input: $input) { diff --git a/packages/webapp-libs/webapp-notifications/src/tests/factories/notification.ts b/packages/webapp-libs/webapp-notifications/src/tests/factories/notification.ts index 8178f74e4..c9c9cb110 100644 --- a/packages/webapp-libs/webapp-notifications/src/tests/factories/notification.ts +++ b/packages/webapp-libs/webapp-notifications/src/tests/factories/notification.ts @@ -1,7 +1,12 @@ import { NotificationType } from '@sb/webapp-api-client'; -import { composeMockedPaginatedListQueryResult, createFactory, makeId } from '@sb/webapp-api-client/tests/utils'; +import { + composeMockedPaginatedListQueryResult, + composeMockedQueryResult, + createFactory, + makeId, +} from '@sb/webapp-api-client/tests/utils'; -import { notificationsListQuery, notificationsListSubscription } from '../../notifications.graphql'; +import { notificationCreatedSubscription, notificationsListQuery } from '../../notifications.graphql'; export const notificationFactory = createFactory(() => ({ id: makeId(32), @@ -35,18 +40,8 @@ export const fillNotificationsListQuery = ( ); }; -export const fillNotificationsSubscriptionQuery = ( - notifications: Array> = [], - additionalData?: Record -) => { - return composeMockedPaginatedListQueryResult( - notificationsListSubscription, - 'notificationCreated', - 'NotificationType', - { - data: notifications, - additionalData, - }, - { endCursor: 'test', hasNextPage: false, hasPreviousPage: false, startCursor: 'test' } - ); +export const fillNotificationCreatedSubscriptionQuery = (notification: NotificationType) => { + return composeMockedQueryResult(notificationCreatedSubscription, { + data: notification, + }); }; diff --git a/packages/webapp/.env.shared b/packages/webapp/.env.shared index 10f64ea5c..0d964a8a5 100644 --- a/packages/webapp/.env.shared +++ b/packages/webapp/.env.shared @@ -1,6 +1,5 @@ VITE_ENVIRONMENT_NAME=local VITE_BASE_API_URL=/api -VITE_SUBSCRIPTIONS_URL=ws://localhost:8080/ VITE_CONTENTFUL_SPACE= VITE_CONTENTFUL_TOKEN= diff --git a/packages/webapp/.env.test b/packages/webapp/.env.test index 9da9cfbb1..5fd4c625c 100644 --- a/packages/webapp/.env.test +++ b/packages/webapp/.env.test @@ -1,4 +1,3 @@ VITE_BASE_API_URL=http://localhost/api -VITE_SUBSCRIPTIONS_URL=ws://localhost:4000/subscriptions VITE_SENTRY_DSN= diff --git a/packages/webapp/src/shared/components/auth/loginForm/loginForm.hooks.ts b/packages/webapp/src/shared/components/auth/loginForm/loginForm.hooks.ts index 10cb23ca8..063e5848f 100644 --- a/packages/webapp/src/shared/components/auth/loginForm/loginForm.hooks.ts +++ b/packages/webapp/src/shared/components/auth/loginForm/loginForm.hooks.ts @@ -1,4 +1,5 @@ import { useMutation } from '@apollo/client'; +import { invalidateApolloStore } from '@sb/webapp-api-client'; import { useApiForm } from '@sb/webapp-api-client/hooks'; import { useCommonQuery } from '@sb/webapp-api-client/providers'; import { useGenerateLocalePath } from '@sb/webapp-core/hooks'; @@ -49,12 +50,13 @@ export const useLoginForm = () => { }, }); - const handleLogin = handleSubmit((data: LoginFormFields) => { - commitLoginMutation({ + const handleLogin = handleSubmit(async (data: LoginFormFields) => { + await commitLoginMutation({ variables: { input: data, }, }); + invalidateApolloStore(); }); return { ...form, loading, handleLogin }; diff --git a/packages/webapp/src/shared/components/layout/__tests__/layout.component.spec.tsx b/packages/webapp/src/shared/components/layout/__tests__/layout.component.spec.tsx index c437e07c8..76c055158 100644 --- a/packages/webapp/src/shared/components/layout/__tests__/layout.component.spec.tsx +++ b/packages/webapp/src/shared/components/layout/__tests__/layout.component.spec.tsx @@ -2,8 +2,8 @@ import { currentUserFactory, fillCommonQueryWithUser } from '@sb/webapp-api-clie import { media } from '@sb/webapp-core/theme'; import { getLocalePath } from '@sb/webapp-core/utils'; import { + fillNotificationCreatedSubscriptionQuery, fillNotificationsListQuery, - fillNotificationsSubscriptionQuery, notificationFactory, } from '@sb/webapp-notifications/tests/factories'; import { screen } from '@testing-library/react'; @@ -63,7 +63,7 @@ describe('Layout: Component', () => { const authPath = RoutesConfig.login; const routerProps = createMockRouterProps(authPath); const apolloMocks = append( - fillNotificationsSubscriptionQuery([notificationFactory()], { hasUnreadNotifications: true }) + fillNotificationCreatedSubscriptionQuery(notificationFactory()) ); render(, { routerProps, apolloMocks }); @@ -73,9 +73,7 @@ describe('Layout: Component', () => { it('should show content', async () => { const routerProps = createMockRouterProps(homeRoutePath); - const apolloMocks = append( - fillNotificationsSubscriptionQuery([notificationFactory()], { hasUnreadNotifications: true }) - ); + const apolloMocks = append(fillNotificationCreatedSubscriptionQuery(notificationFactory())); render(, { routerProps, apolloMocks }); expect(await screen.findByTestId('content')).toBeVisible(); }); @@ -84,7 +82,7 @@ describe('Layout: Component', () => { it('should show open menu button', async () => { const routerProps = createMockRouterProps(homeRoutePath); const apolloMocks = append( - fillNotificationsSubscriptionQuery([notificationFactory()], { hasUnreadNotifications: true }) + fillNotificationCreatedSubscriptionQuery(notificationFactory()) ); render(, { routerProps, apolloMocks }); expect(await screen.findByLabelText(/open menu/i)).toBeInTheDocument(); @@ -93,7 +91,7 @@ describe('Layout: Component', () => { it('should show privacy menu link', async () => { const routerProps = createMockRouterProps(homeRoutePath); const apolloMocks = append( - fillNotificationsSubscriptionQuery([notificationFactory()], { hasUnreadNotifications: true }) + fillNotificationCreatedSubscriptionQuery(notificationFactory()) ); render(, { routerProps, apolloMocks }); expect(await screen.findByText(/privacy policy/i)).toBeInTheDocument(); @@ -102,7 +100,7 @@ describe('Layout: Component', () => { it('should not show dashboard menu link', async () => { const routerProps = createMockRouterProps(homeRoutePath); const apolloMocks = append( - fillNotificationsSubscriptionQuery([notificationFactory()], { hasUnreadNotifications: true }) + fillNotificationCreatedSubscriptionQuery(notificationFactory()) ); render(, { routerProps, apolloMocks }); @@ -114,7 +112,7 @@ describe('Layout: Component', () => { it('should show open menu button', async () => { const routerProps = createMockRouterProps(homeRoutePath); const apolloMocks = append( - fillNotificationsSubscriptionQuery([notificationFactory()], { hasUnreadNotifications: true }) + fillNotificationCreatedSubscriptionQuery(notificationFactory()) ); render(, { routerProps, apolloMocks }); expect(await screen.findByLabelText(/open menu/i)).toBeVisible(); @@ -123,7 +121,7 @@ describe('Layout: Component', () => { it('should not show menu links', async () => { const routerProps = createMockRouterProps(homeRoutePath); const apolloMocks = append( - fillNotificationsSubscriptionQuery([notificationFactory()], { hasUnreadNotifications: true }) + fillNotificationCreatedSubscriptionQuery(notificationFactory()) ); const { waitForApolloMocks } = render(, { routerProps, apolloMocks }); await waitForApolloMocks(0); @@ -140,9 +138,7 @@ describe('Layout: Component', () => { }) ), fillNotificationsListQuery([], { hasUnreadNotifications: true }), - fillNotificationsSubscriptionQuery([notificationFactory()], { - hasUnreadNotifications: true, - }), + fillNotificationCreatedSubscriptionQuery(notificationFactory()), ]; render(, { apolloMocks, routerProps }); await userEvent.click(await screen.findByLabelText(/open menu/i)); @@ -159,9 +155,7 @@ describe('Layout: Component', () => { }) ), fillNotificationsListQuery([], { hasUnreadNotifications: true }), - fillNotificationsSubscriptionQuery([notificationFactory()], { - hasUnreadNotifications: true, - }), + fillNotificationCreatedSubscriptionQuery(notificationFactory()), ]; render(, { apolloMocks, routerProps }); await userEvent.click(await screen.findByLabelText(/open menu/i)); @@ -180,9 +174,7 @@ describe('Layout: Component', () => { }) ), fillNotificationsListQuery([], { hasUnreadNotifications: true }), - fillNotificationsSubscriptionQuery([notificationFactory()], { - hasUnreadNotifications: true, - }), + fillNotificationCreatedSubscriptionQuery(notificationFactory()), ]; render(, { apolloMocks, routerProps }); await userEvent.click(await screen.findByLabelText(/open menu/i)); @@ -202,7 +194,7 @@ describe('Layout: Component', () => { it('should show content', async () => { const routerProps = createMockRouterProps(homeRoutePath); const apolloMocks = append( - fillNotificationsSubscriptionQuery([notificationFactory()], { hasUnreadNotifications: true }) + fillNotificationCreatedSubscriptionQuery(notificationFactory()) ); render(, { routerProps, apolloMocks }); expect(await screen.findByTestId('content')).toBeVisible(); @@ -213,7 +205,7 @@ describe('Layout: Component', () => { const authPath = RoutesConfig.login; const routerProps = createMockRouterProps(authPath); const apolloMocks = append( - fillNotificationsSubscriptionQuery([notificationFactory()], { hasUnreadNotifications: true }) + fillNotificationCreatedSubscriptionQuery(notificationFactory()) ); render(, { routerProps, apolloMocks }); @@ -225,7 +217,7 @@ describe('Layout: Component', () => { it('should not show open menu button', async () => { const routerProps = createMockRouterProps(homeRoutePath); const apolloMocks = append( - fillNotificationsSubscriptionQuery([notificationFactory()], { hasUnreadNotifications: true }) + fillNotificationCreatedSubscriptionQuery(notificationFactory()) ); render(, { routerProps, apolloMocks }); @@ -235,7 +227,7 @@ describe('Layout: Component', () => { it('should show menu links', async () => { const routerProps = createMockRouterProps(homeRoutePath); const apolloMocks = append( - fillNotificationsSubscriptionQuery([notificationFactory()], { hasUnreadNotifications: true }) + fillNotificationCreatedSubscriptionQuery(notificationFactory()) ); render(, { routerProps, apolloMocks }); expect(await screen.findByText(/privacy policy/i)).toBeInTheDocument(); @@ -246,7 +238,7 @@ describe('Layout: Component', () => { it('should not show open menu button', async () => { const routerProps = createMockRouterProps(homeRoutePath); const apolloMocks = append( - fillNotificationsSubscriptionQuery([notificationFactory()], { hasUnreadNotifications: true }) + fillNotificationCreatedSubscriptionQuery(notificationFactory()) ); render(, { routerProps, apolloMocks }); @@ -261,9 +253,7 @@ describe('Layout: Component', () => { }) ), fillNotificationsListQuery([], { hasUnreadNotifications: true }), - fillNotificationsSubscriptionQuery([notificationFactory()], { - hasUnreadNotifications: true, - }), + fillNotificationCreatedSubscriptionQuery(notificationFactory()), ]; const routerProps = createMockRouterProps(homeRoutePath); render(, { apolloMocks, routerProps }); diff --git a/packages/webapp/src/shared/components/layout/header/__tests__/header.component.spec.tsx b/packages/webapp/src/shared/components/layout/header/__tests__/header.component.spec.tsx index 41b087b65..462892f12 100644 --- a/packages/webapp/src/shared/components/layout/header/__tests__/header.component.spec.tsx +++ b/packages/webapp/src/shared/components/layout/header/__tests__/header.component.spec.tsx @@ -2,7 +2,7 @@ import { currentUserFactory, fillCommonQueryWithUser } from '@sb/webapp-api-clie import { getLocalePath } from '@sb/webapp-core/utils'; import { fillNotificationsListQuery, - fillNotificationsSubscriptionQuery, + fillNotificationCreatedSubscriptionQuery, notificationFactory, } from '@sb/webapp-notifications/tests/factories'; import { screen } from '@testing-library/react'; @@ -16,7 +16,7 @@ import { Header } from '../header.component'; const getApolloMocks = () => [ fillCommonQueryWithUser(currentUserFactory()), fillNotificationsListQuery([], { hasUnreadNotifications: false }), - fillNotificationsSubscriptionQuery([notificationFactory()], { hasUnreadNotifications: false }), + fillNotificationCreatedSubscriptionQuery(notificationFactory()), ]; describe('Header: Component', () => { diff --git a/packages/webapp/src/shared/components/layout/header/header.component.tsx b/packages/webapp/src/shared/components/layout/header/header.component.tsx index b98150614..e68643d44 100644 --- a/packages/webapp/src/shared/components/layout/header/header.component.tsx +++ b/packages/webapp/src/shared/components/layout/header/header.component.tsx @@ -4,7 +4,7 @@ import { useGenerateLocalePath, useOpenState } from '@sb/webapp-core/hooks'; import { useTheme } from '@sb/webapp-core/hooks/useTheme/useTheme'; import { cn } from '@sb/webapp-core/lib/utils'; import { Notifications } from '@sb/webapp-notifications'; -import { Menu, Sun , LogOut, User } from 'lucide-react'; +import { LogOut, Menu, Sun, User } from 'lucide-react'; import { HTMLAttributes, useContext } from 'react'; import { FormattedMessage, useIntl } from 'react-intl'; @@ -18,7 +18,7 @@ export type HeaderProps = HTMLAttributes; export const Header = (props: HeaderProps) => { const intl = useIntl(); - const { isLoggedIn } = useAuth(); + const { isLoggedIn, currentUser } = useAuth(); const { toggleTheme } = useTheme(); const userDropdown = useOpenState(false); const generateLocalePath = useGenerateLocalePath(); @@ -51,7 +51,7 @@ export const Header = (props: HeaderProps) => { {isLoggedIn && ( <> - +
{ '/api': { target: 'http://localhost:5001', changeOrigin: true, + ws: true }, '/static/graphene_django': { target: 'http://localhost:5001', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 116a96939..7181c6833 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -94,7 +94,7 @@ importers: devDependencies: '@apollo/client': specifier: ^3.8.8 - version: 3.8.8(graphql-ws@5.14.2)(graphql@16.8.1)(react-dom@18.2.0)(react@18.2.0) + version: 3.8.8(graphql-ws@5.14.2)(graphql@16.8.1)(react-dom@18.2.0)(react@18.2.0)(subscriptions-transport-ws@0.11.0) '@apollo/rover': specifier: ^0.19.1 version: 0.19.1 @@ -537,34 +537,6 @@ importers: specifier: '*' version: link:../../webapp - packages/internal/local-ws-server: - dependencies: - axios: - specifier: ^1.6.2 - version: 1.6.2 - cookies: - specifier: ^0.8.0 - version: 0.8.0 - fastify: - specifier: ^4.24.3 - version: 4.24.3 - jwt-decode: - specifier: ^4.0.0 - version: 4.0.0 - nanoid: - specifier: ^5.0.3 - version: 5.0.3 - pino-pretty: - specifier: ^10.2.3 - version: 10.2.3 - ws: - specifier: ^8.14.2 - version: 8.14.2 - devDependencies: - nodemon: - specifier: ^3.0.1 - version: 3.0.1 - packages/internal/status-dashboard: dependencies: core-js: @@ -785,7 +757,7 @@ importers: version: 9.0.1(graphql@16.8.1) '@types/apollo-upload-client': specifier: ^17.0.5 - version: 17.0.5(graphql-ws@5.14.2)(react-dom@18.2.0)(react@18.2.0) + version: 17.0.5(graphql-ws@5.14.2)(react-dom@18.2.0)(react@18.2.0)(subscriptions-transport-ws@0.11.0) fs-extra: specifier: ^11.2.0 version: 11.2.0 @@ -795,6 +767,9 @@ importers: msw: specifier: ^1.3.2 version: 1.3.2(typescript@5.2.2) + subscriptions-transport-ws: + specifier: ^0.11.0 + version: 0.11.0(graphql@16.8.1) packages/webapp-libs/webapp-contentful: dependencies: @@ -1220,7 +1195,7 @@ packages: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.20 - /@apollo/client@3.8.8(graphql-ws@5.14.2)(graphql@16.8.1)(react-dom@18.2.0)(react@18.2.0): + /@apollo/client@3.8.8(graphql-ws@5.14.2)(graphql@16.8.1)(react-dom@18.2.0)(react@18.2.0)(subscriptions-transport-ws@0.11.0): resolution: {integrity: sha512-omjd9ryGDkadZrKW6l5ktUAdS4SNaFOccYQ4ZST0HLW83y8kQaSZOCTNlpkoBUK8cv6qP8+AxOKwLm2ho8qQ+Q==} peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 @@ -1250,6 +1225,7 @@ packages: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) response-iterator: 0.2.6 + subscriptions-transport-ws: 0.11.0(graphql@16.8.1) symbol-observable: 4.0.0 ts-invariant: 0.10.3 tslib: 2.6.2 @@ -6801,28 +6777,6 @@ packages: resolution: {integrity: sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==} dev: true - /@fastify/ajv-compiler@3.5.0: - resolution: {integrity: sha512-ebbEtlI7dxXF5ziNdr05mOY8NnDiPB1XvAlLHctRt/Rc+C3LCOVW5imUVX+mhvUhnNzmPBHewUkOFgGlCxgdAA==} - dependencies: - ajv: 8.12.0 - ajv-formats: 2.1.1(ajv@8.12.0) - fast-uri: 2.2.0 - dev: false - - /@fastify/deepmerge@1.3.0: - resolution: {integrity: sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==} - dev: false - - /@fastify/error@3.4.1: - resolution: {integrity: sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==} - dev: false - - /@fastify/fast-json-stringify-compiler@4.3.0: - resolution: {integrity: sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==} - dependencies: - fast-json-stringify: 5.8.0 - dev: false - /@floating-ui/core@1.5.0: resolution: {integrity: sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==} dependencies: @@ -13181,10 +13135,10 @@ packages: minimatch: 9.0.3 dev: true - /@types/apollo-upload-client@17.0.5(graphql-ws@5.14.2)(react-dom@18.2.0)(react@18.2.0): + /@types/apollo-upload-client@17.0.5(graphql-ws@5.14.2)(react-dom@18.2.0)(react@18.2.0)(subscriptions-transport-ws@0.11.0): resolution: {integrity: sha512-rPKHaE4QNd06LNtBgz6hfntVO+pOQMS2yTcynrzBPg9+a/nbtJ2gus5KgzRp2rqfzmnKEc/sRGjLen/9Ot0Z2A==} dependencies: - '@apollo/client': 3.8.8(graphql-ws@5.14.2)(graphql@16.8.1)(react-dom@18.2.0)(react@18.2.0) + '@apollo/client': 3.8.8(graphql-ws@5.14.2)(graphql@16.8.1)(react-dom@18.2.0)(react@18.2.0)(subscriptions-transport-ws@0.11.0) '@types/extract-files': 8.1.1 graphql: 16.8.1 transitivePeerDependencies: @@ -14532,6 +14486,7 @@ packages: engines: {node: '>=6.5'} dependencies: event-target-shim: 5.0.1 + dev: true /abstract-leveldown@0.12.4: resolution: {integrity: sha512-TOod9d5RDExo6STLMGa+04HGkl+TlMfbDnTyN93/ETJ9DpQ0DaYLqcMZlbXvdc4W3vVo1Qrl+WhSp8zvDsJ+jA==} @@ -14539,10 +14494,6 @@ packages: xtend: 3.0.0 dev: true - /abstract-logging@2.0.1: - resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} - dev: false - /accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -14881,7 +14832,7 @@ packages: '@apollo/client': ^3.0.0 graphql: 14 - 16 dependencies: - '@apollo/client': 3.8.8(graphql-ws@5.14.2)(graphql@16.8.1)(react-dom@18.2.0)(react@18.2.0) + '@apollo/client': 3.8.8(graphql-ws@5.14.2)(graphql@16.8.1)(react-dom@18.2.0)(react@18.2.0)(subscriptions-transport-ws@0.11.0) extract-files: 11.0.0 graphql: 16.8.1 dev: false @@ -14946,10 +14897,6 @@ packages: zip-stream: 4.1.1 dev: true - /archy@1.0.0: - resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} - dev: false - /are-we-there-yet@2.0.0: resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} engines: {node: '>=10'} @@ -15209,11 +15156,6 @@ packages: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} - /atomic-sleep@1.0.0: - resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} - engines: {node: '>=8.0.0'} - dev: false - /attr-accept@2.2.2: resolution: {integrity: sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==} engines: {node: '>=4'} @@ -15258,16 +15200,6 @@ packages: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} - /avvio@8.2.1: - resolution: {integrity: sha512-TAlMYvOuwGyLK3PfBb5WKBXZmXz2fVCgv23d6zZFdle/q3gPjmxBaeuC0pY0Dzs5PWMSgfqqEZkrye19GlDTgw==} - dependencies: - archy: 1.0.0 - debug: 4.3.4(supports-color@8.1.1) - fastq: 1.15.0 - transitivePeerDependencies: - - supports-color - dev: false - /aws-cdk-lib@2.111.0(constructs@10.3.0): resolution: {integrity: sha512-E+uBDYRAwl/KFRcpTT2B4Fz50MvVqEIcOUDBo/xK8z5TWorRkqVQry7PCts3hb7dLcGgFVONes8dLuzmarx0mQ==} engines: {node: '>= 14.15.0'} @@ -15788,6 +15720,9 @@ packages: babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.5) dev: true + /backo2@1.0.2: + resolution: {integrity: sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==} + /bail@1.0.5: resolution: {integrity: sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==} dev: false @@ -16206,6 +16141,7 @@ packages: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 + dev: true /bufrw@1.3.0: resolution: {integrity: sha512-jzQnSbdJqhIltU9O5KUiTtljP9ccw2u5ix59McQy4pV2xGhVLhRZIndY8GIrgh5HjXa6+QJ9AQhOd2QWQizJFQ==} @@ -17524,14 +17460,6 @@ packages: resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} dev: true - /cookies@0.8.0: - resolution: {integrity: sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==} - engines: {node: '>= 0.8'} - dependencies: - depd: 2.0.0 - keygrip: 1.1.0 - dev: false - /copy-anything@2.0.6: resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} dependencies: @@ -18225,6 +18153,7 @@ packages: /dateformat@4.6.3: resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + dev: true /dayjs@1.11.10: resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} @@ -18244,7 +18173,7 @@ packages: dependencies: ms: 2.0.0 - /debug@3.2.7(supports-color@5.5.0): + /debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: supports-color: '*' @@ -18253,7 +18182,6 @@ packages: optional: true dependencies: ms: 2.1.3 - supports-color: 5.5.0 /debug@4.3.4(supports-color@8.1.1): resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} @@ -19707,7 +19635,7 @@ packages: /eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} dependencies: - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7 is-core-module: 2.13.0 resolve: 1.22.6 transitivePeerDependencies: @@ -19757,7 +19685,7 @@ packages: optional: true dependencies: '@typescript-eslint/parser': 6.13.1(eslint@8.54.0)(typescript@5.2.2) - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7 eslint: 8.54.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.13.1)(eslint-plugin-import@2.28.1)(eslint@8.54.0) @@ -19786,7 +19714,7 @@ packages: optional: true dependencies: '@typescript-eslint/parser': 6.13.1(eslint@8.54.0)(typescript@5.2.2) - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7 eslint: 8.55.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.13.1)(eslint-plugin-import@2.28.1)(eslint@8.54.0) @@ -19854,7 +19782,7 @@ packages: array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 array.prototype.flatmap: 1.3.2 - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7 doctrine: 2.1.0 eslint: 8.54.0 eslint-import-resolver-node: 0.3.9 @@ -19888,7 +19816,7 @@ packages: array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 array.prototype.flatmap: 1.3.2 - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7 doctrine: 2.1.0 eslint: 8.55.0 eslint-import-resolver-node: 0.3.9 @@ -20364,6 +20292,10 @@ packages: /event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} + dev: true + + /eventemitter3@3.1.2: + resolution: {integrity: sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==} /eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} @@ -20548,10 +20480,6 @@ packages: - supports-color dev: true - /fast-content-type-parse@1.1.0: - resolution: {integrity: sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==} - dev: false - /fast-copy@2.1.7: resolution: {integrity: sha512-ozrGwyuCTAy7YgFCua8rmqmytECYk/JYAMXcswOcm0qvGoE3tPb7ivBeIHTOK2DiapBhDZgacIhzhQIKU5TCfA==} dev: false @@ -20562,6 +20490,7 @@ packages: /fast-decode-uri-component@1.0.1: resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} + dev: true /fast-deep-equal@2.0.1: resolution: {integrity: sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==} @@ -20604,17 +20533,6 @@ packages: /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - /fast-json-stringify@5.8.0: - resolution: {integrity: sha512-VVwK8CFMSALIvt14U8AvrSzQAwN/0vaVRiFFUVlpnXSnDGrSkOAO5MtzyN8oQNjLd5AqTW5OZRgyjoNuAuR3jQ==} - dependencies: - '@fastify/deepmerge': 1.3.0 - ajv: 8.12.0 - ajv-formats: 2.1.1(ajv@8.12.0) - fast-deep-equal: 3.1.3 - fast-uri: 2.2.0 - rfdc: 1.3.0 - dev: false - /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} @@ -20628,18 +20546,11 @@ packages: resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} dependencies: fast-decode-uri-component: 1.0.1 - - /fast-redact@3.3.0: - resolution: {integrity: sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==} - engines: {node: '>=6'} - dev: false + dev: true /fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - - /fast-uri@2.2.0: - resolution: {integrity: sha512-cIusKBIt/R/oI6z/1nyfe2FvGKVTohVRfvkOhvx0nCEW+xf5NoCXjAHcWp93uOUBchzYcsvPlrapAdX1uW+YGg==} - dev: false + dev: true /fast-url-parser@1.1.3: resolution: {integrity: sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==} @@ -20656,29 +20567,6 @@ packages: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} - /fastify@4.24.3: - resolution: {integrity: sha512-6HHJ+R2x2LS3y1PqxnwEIjOTZxFl+8h4kSC/TuDPXtA+v2JnV9yEtOsNSKK1RMD7sIR2y1ZsA4BEFaid/cK5pg==} - dependencies: - '@fastify/ajv-compiler': 3.5.0 - '@fastify/error': 3.4.1 - '@fastify/fast-json-stringify-compiler': 4.3.0 - abstract-logging: 2.0.1 - avvio: 8.2.1 - fast-content-type-parse: 1.1.0 - fast-json-stringify: 5.8.0 - find-my-way: 7.7.0 - light-my-request: 5.11.0 - pino: 8.16.2 - process-warning: 2.2.0 - proxy-addr: 2.0.7 - rfdc: 1.3.0 - secure-json-parse: 2.7.0 - semver: 7.5.4 - toad-cache: 3.3.0 - transitivePeerDependencies: - - supports-color - dev: false - /fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} dependencies: @@ -20926,15 +20814,6 @@ packages: pkg-dir: 7.0.0 dev: true - /find-my-way@7.7.0: - resolution: {integrity: sha512-+SrHpvQ52Q6W9f3wJoJBbAQULJuNEEQwBvlvYwACDhBTLOTMiQ0HYWh4+vC3OivGP2ENcTI1oKlFA2OepJNjhQ==} - engines: {node: '>=14'} - dependencies: - fast-deep-equal: 3.1.3 - fast-querystring: 1.1.2 - safe-regex2: 2.0.0 - dev: false - /find-requires@1.0.0: resolution: {integrity: sha512-UME7hNwBfzeISSFQcBEDemEEskpOjI/shPrpJM5PI4DSdn6hX0dmz+2dL70blZER2z8tSnTRL+2rfzlYgtbBoQ==} hasBin: true @@ -21545,6 +21424,7 @@ packages: inherits: 2.0.4 minimatch: 5.1.6 once: 1.4.0 + dev: true /global-dirs@3.0.1: resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} @@ -22005,13 +21885,6 @@ packages: resolution: {integrity: sha512-tUCGvt191vNSQgttSyJoibR+VO+I6+iCHIUdhzEMJKE+EAL8BwCN7fUOZlY4ofOelNHsK+gEjxB/B+9N3EWtdA==} dev: true - /help-me@4.2.0: - resolution: {integrity: sha512-TAOnTB8Tz5Dw8penUuzHVrKNKlCIbwwbHnXraNJxPwf8LRtE2HlM84RYuezMFcwOJmoYOCWVDyJ8TQGxn9PgxA==} - dependencies: - glob: 8.1.0 - readable-stream: 3.6.2 - dev: false - /hexer@1.5.0: resolution: {integrity: sha512-dyrPC8KzBzUJ19QTIo1gXNqIISRXQ0NwteW6OeQHRN4ZuZeHkdODfj0zHBdOlHbRY8GqbqK57C9oWSvQZizFsg==} engines: {node: '>= 0.10.x'} @@ -22329,7 +22202,7 @@ packages: engines: {node: '>= 4.5.0'} dependencies: agent-base: 4.3.0 - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7 transitivePeerDependencies: - supports-color dev: false @@ -22426,10 +22299,6 @@ packages: /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - /ignore-by-default@1.0.1: - resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} - dev: true - /ignore-walk@4.0.1: resolution: {integrity: sha512-rzDQLaW4jQbh2YrOFlJdCtX8qgJTehFRYiUB2r1osqTeDzV/3+Jh8fz1oAPzUThf3iku8Ds4IDqawI5d8mUiQw==} engines: {node: '>=10'} @@ -23367,6 +23236,9 @@ packages: istanbul-lib-report: 3.0.1 dev: true + /iterall@1.3.0: + resolution: {integrity: sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==} + /iterate-object@1.3.4: resolution: {integrity: sha512-4dG1D1x/7g8PwHS9aK6QV5V94+ZvyP4+d19qDv43EzImmrndysIl4prmJ1hWWIGCqrZHyaHBm6BSEWHOLnpoNw==} dev: false @@ -23938,11 +23810,6 @@ packages: resolution: {integrity: sha512-EqJPEUlZD0/CSUMubKtMaYUOtWe91tZXTWMJZoKSbLk+KtdhNdcvppH8lA9XwVu2V4Ailvsj0GBZJ2ZwDjfesQ==} dev: true - /joycon@3.1.1: - resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} - engines: {node: '>=10'} - dev: false - /js-levenshtein@1.1.6: resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==} engines: {node: '>=0.10.0'} @@ -24275,18 +24142,6 @@ packages: resolution: {integrity: sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==} dev: true - /jwt-decode@4.0.0: - resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} - engines: {node: '>=18'} - dev: false - - /keygrip@1.1.0: - resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==} - engines: {node: '>= 0.6'} - dependencies: - tsscmp: 1.0.6 - dev: false - /keyv@3.1.0: resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==} dependencies: @@ -24552,14 +24407,6 @@ packages: resolve: 1.22.6 dev: true - /light-my-request@5.11.0: - resolution: {integrity: sha512-qkFCeloXCOMpmEdZ/MV91P8AT4fjwFXWaAFz3lUeStM8RcoM1ks4J/F8r1b3r6y/H4u3ACEJ1T+Gv5bopj7oDA==} - dependencies: - cookie: 0.5.0 - process-warning: 2.2.0 - set-cookie-parser: 2.6.0 - dev: false - /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -26064,12 +25911,6 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - /nanoid@5.0.3: - resolution: {integrity: sha512-I7X2b22cxA4LIHXPSqbBCEQSL+1wv8TuoefejsX4HFWyC6jc5JG7CEaxOltiKjc1M+YCS2YkrZZcj4+dytw9GA==} - engines: {node: ^18 || >=20} - hasBin: true - dev: false - /native-promise-only@0.8.1: resolution: {integrity: sha512-zkVhZUA3y8mbz652WrL5x0fB0ehrBkulWT3TomAQ9iDtyXZvzKeEA6GPxAItBYeNYl5yngKRX612qHOhvMkDeg==} dev: true @@ -26099,7 +25940,7 @@ packages: hasBin: true requiresBuild: true dependencies: - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7 iconv-lite: 0.6.3 sax: 1.2.4 transitivePeerDependencies: @@ -26246,30 +26087,6 @@ packages: engines: {node: '>=6.0.0'} dev: false - /nodemon@3.0.1: - resolution: {integrity: sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==} - engines: {node: '>=10'} - hasBin: true - dependencies: - chokidar: 3.5.3 - debug: 3.2.7(supports-color@5.5.0) - ignore-by-default: 1.0.1 - minimatch: 3.1.2 - pstree.remy: 1.1.8 - semver: 7.5.4 - simple-update-notifier: 2.0.0 - supports-color: 5.5.0 - touch: 3.1.0 - undefsafe: 2.0.5 - dev: true - - /nopt@1.0.10: - resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} - hasBin: true - dependencies: - abbrev: 1.1.1 - dev: true - /nopt@5.0.0: resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} engines: {node: '>=6'} @@ -26857,10 +26674,6 @@ packages: resolution: {integrity: sha512-nnda7W8d+A3vEIY+UrDQzzboPf1vhs4JYVhff5CDkq9QNoZY7Xrxeo/htox37j9dZf7yNHevZzqtejWgy1vCqQ==} dev: true - /on-exit-leak-free@2.1.0: - resolution: {integrity: sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==} - dev: false - /on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -27529,54 +27342,6 @@ packages: resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} engines: {node: '>=0.10.0'} - /pino-abstract-transport@1.1.0: - resolution: {integrity: sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==} - dependencies: - readable-stream: 4.4.2 - split2: 4.2.0 - dev: false - - /pino-pretty@10.2.3: - resolution: {integrity: sha512-4jfIUc8TC1GPUfDyMSlW1STeORqkoxec71yhxIpLDQapUu8WOuoz2TTCoidrIssyz78LZC69whBMPIKCMbi3cw==} - hasBin: true - dependencies: - colorette: 2.0.20 - dateformat: 4.6.3 - fast-copy: 3.0.1 - fast-safe-stringify: 2.1.1 - help-me: 4.2.0 - joycon: 3.1.1 - minimist: 1.2.8 - on-exit-leak-free: 2.1.0 - pino-abstract-transport: 1.1.0 - pump: 3.0.0 - readable-stream: 4.4.2 - secure-json-parse: 2.7.0 - sonic-boom: 3.3.0 - strip-json-comments: 3.1.1 - dev: false - - /pino-std-serializers@6.2.2: - resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==} - dev: false - - /pino@8.16.2: - resolution: {integrity: sha512-2advCDGVEvkKu9TTVSa/kWW7Z3htI/sBKEZpqiHk6ive0i/7f5b1rsU8jn0aimxqfnSz5bj/nOYkwhBUn5xxvg==} - hasBin: true - dependencies: - atomic-sleep: 1.0.0 - fast-redact: 3.3.0 - on-exit-leak-free: 2.1.0 - pino-abstract-transport: 1.1.0 - pino-std-serializers: 6.2.2 - process-warning: 2.2.0 - quick-format-unescaped: 4.0.4 - real-require: 0.2.0 - safe-stable-stringify: 2.4.3 - sonic-boom: 3.7.0 - thread-stream: 2.4.0 - dev: false - /pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} @@ -27665,7 +27430,7 @@ packages: engines: {node: '>= 0.12.0'} dependencies: async: 2.6.4 - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7 mkdirp: 0.5.6 transitivePeerDependencies: - supports-color @@ -28955,10 +28720,6 @@ packages: type: 2.7.2 dev: true - /process-warning@2.2.0: - resolution: {integrity: sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==} - dev: false - /process@0.10.1: resolution: {integrity: sha512-dyIett8dgGIZ/TXKUzeYExt7WA6ldDzys9vTDU/cCA9L17Ypme+KzS+NjQCjpn9xsvi/shbMC+yP/BcFMBz0NA==} engines: {node: '>= 0.6.0'} @@ -29072,10 +28833,6 @@ packages: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} dev: true - /pstree.remy@1.1.8: - resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} - dev: true - /public-encrypt@4.0.3: resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} dependencies: @@ -29223,10 +28980,6 @@ packages: inherits: 2.0.4 dev: false - /quick-format-unescaped@4.0.4: - resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} - dev: false - /quick-lru@4.0.1: resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} engines: {node: '>=8'} @@ -30019,6 +29772,7 @@ packages: events: 3.3.0 process: 0.11.10 string_decoder: 1.3.0 + dev: true /readable-web-to-node-stream@3.0.2: resolution: {integrity: sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==} @@ -30053,11 +29807,6 @@ packages: resolution: {integrity: sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==} dev: false - /real-require@0.2.0: - resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} - engines: {node: '>= 12.13.0'} - dev: false - /recast@0.23.4: resolution: {integrity: sha512-qtEDqIZGVcSZCHniWwZWbRy79Dc6Wp3kT/UmDA2RJKBPg7+7k51aQBZirHmUGn5uvHf2rg8DkjizrN26k61ATw==} engines: {node: '>= 4'} @@ -30496,11 +30245,6 @@ packages: signal-exit: 3.0.7 dev: true - /ret@0.2.2: - resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==} - engines: {node: '>=4'} - dev: false - /retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} @@ -30704,23 +30448,12 @@ packages: get-intrinsic: 1.2.2 is-regex: 1.1.4 - /safe-regex2@2.0.0: - resolution: {integrity: sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==} - dependencies: - ret: 0.2.2 - dev: false - /safe-regex@2.1.1: resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==} dependencies: regexp-tree: 0.1.27 dev: true - /safe-stable-stringify@2.4.3: - resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} - engines: {node: '>=10'} - dev: false - /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -30867,10 +30600,6 @@ packages: resolution: {integrity: sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==} dev: true - /secure-json-parse@2.7.0: - resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} - dev: false - /seek-bzip@1.0.6: resolution: {integrity: sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==} hasBin: true @@ -31124,6 +30853,7 @@ packages: /set-cookie-parser@2.6.0: resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} + dev: true /set-function-length@1.1.1: resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} @@ -31432,18 +31162,6 @@ packages: smart-buffer: 4.2.0 dev: true - /sonic-boom@3.3.0: - resolution: {integrity: sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==} - dependencies: - atomic-sleep: 1.0.0 - dev: false - - /sonic-boom@3.7.0: - resolution: {integrity: sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg==} - dependencies: - atomic-sleep: 1.0.0 - dev: false - /sort-css-media-queries@2.1.0: resolution: {integrity: sha512-IeWvo8NkNiY2vVYdPa27MCQiR0MN0M80johAYFVxWWXQ44KU84WNxjslwBHmc/7ZL2ccwkM7/e6S5aiKZXm7jA==} engines: {node: '>= 6.3.0'} @@ -31599,11 +31317,6 @@ packages: readable-stream: 3.6.2 dev: true - /split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} - dev: false - /sponge-case@1.0.1: resolution: {integrity: sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA==} dependencies: @@ -32316,6 +32029,22 @@ packages: - supports-color dev: true + /subscriptions-transport-ws@0.11.0(graphql@16.8.1): + resolution: {integrity: sha512-8D4C6DIH5tGiAIpp5I0wD/xRlNiZAPGHygzCe7VzyzUoxHtawzjNAY9SUTXU05/EY2NMY9/9GF0ycizkXr1CWQ==} + deprecated: The `subscriptions-transport-ws` package is no longer maintained. We recommend you use `graphql-ws` instead. For help migrating Apollo software to `graphql-ws`, see https://www.apollographql.com/docs/apollo-server/data/subscriptions/#switching-from-subscriptions-transport-ws For general help using `graphql-ws`, see https://github.com/enisdenjo/graphql-ws/blob/master/README.md + peerDependencies: + graphql: ^15.7.2 || ^16.0.0 + dependencies: + backo2: 1.0.2 + eventemitter3: 3.1.2 + graphql: 16.8.1 + iterall: 1.3.0 + symbol-observable: 1.2.0 + ws: 7.5.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + /sucrase@3.34.0: resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==} engines: {node: '>=8'} @@ -32433,7 +32162,6 @@ packages: /symbol-observable@1.2.0: resolution: {integrity: sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==} engines: {node: '>=0.10.0'} - dev: false /symbol-observable@4.0.0: resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} @@ -32709,12 +32437,6 @@ packages: dependencies: any-promise: 1.3.0 - /thread-stream@2.4.0: - resolution: {integrity: sha512-xZYtOtmnA63zj04Q+F9bdEay5r47bvpo1CaNqsKi7TpoJHcotUez8Fkfo2RJWpW91lnnaApdpRbVwCWsy+ifcw==} - dependencies: - real-require: 0.2.0 - dev: false - /thriftrw@3.11.4: resolution: {integrity: sha512-UcuBd3eanB3T10nXWRRMwfwoaC6VMk7qe3/5YIWP2Jtw+EbHqJ0p1/K3x8ixiR5dozKSSfcg1W+0e33G1Di3XA==} engines: {node: '>= 0.10.x'} @@ -32816,11 +32538,6 @@ packages: dependencies: is-number: 7.0.0 - /toad-cache@3.3.0: - resolution: {integrity: sha512-3oDzcogWGHZdkwrHyvJVpPjA7oNzY6ENOV3PsWJY9XYPZ6INo94Yd47s5may1U+nleBPwDhrRiTPMIvKaa3MQg==} - engines: {node: '>=12'} - dev: false - /tocbot@4.23.0: resolution: {integrity: sha512-5DWuSZXsqG894mkGb8ZsQt9myyQyVxE50AiGRZ0obV0BVUTVkaZmc9jbgpknaAAPUm4FIrzGkEseD6FuQJYJDQ==} dev: true @@ -32842,13 +32559,6 @@ packages: engines: {node: '>=6'} dev: false - /touch@3.1.0: - resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} - hasBin: true - dependencies: - nopt: 1.0.10 - dev: true - /tough-cookie@4.1.3: resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} engines: {node: '>=6'} @@ -33091,11 +32801,6 @@ packages: /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - /tsscmp@1.0.6: - resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} - engines: {node: '>=0.6.x'} - dev: false - /tsutils@3.21.0(typescript@5.2.2): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} @@ -33353,10 +33058,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /undefsafe@2.0.5: - resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} - dev: true - /underscore@1.12.1: resolution: {integrity: sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==} dev: false