From d9f1a066ce379358dd4ea92e96c333b46c32d4a3 Mon Sep 17 00:00:00 2001 From: Ruslan Bakiev Date: Mon, 9 Mar 2026 09:26:41 +0700 Subject: [PATCH] Migrate teams backend from Django to Express + Apollo Server + Prisma Replace Django/Graphene stack with TypeScript Express server using Apollo Server v4 with 4 GraphQL endpoints (public/user/team/m2m) and Prisma ORM mapped to existing tables. --- .gitignore | 2 + Dockerfile | 36 +- README.md | 47 - db.sqlite3 | 0 manage.py | 17 - nixpacks.toml | 18 - package-lock.json | 4183 +++++++++++++++++ package.json | 30 + poetry.lock | 1005 ---- prisma/schema.prisma | 132 + pyproject.toml | 28 - src/auth.ts | 55 + src/db.ts | 3 + src/index.ts | 47 + src/schemas/m2m.ts | 149 + src/schemas/public.ts | 4 + src/schemas/team.ts | 286 ++ src/schemas/user.ts | 189 + src/services/temporal.ts | 46 + teams/__init__.py | 1 - teams/__pycache__/__init__.cpython-313.pyc | Bin 167 -> 0 bytes teams/__pycache__/settings.cpython-313.pyc | Bin 5291 -> 0 bytes .../settings_local.cpython-313.pyc | Bin 2005 -> 0 bytes teams/__pycache__/urls.cpython-313.pyc | Bin 1350 -> 0 bytes teams/settings.py | 161 - teams/settings_local.py | 71 - teams/urls.py | 17 - teams/wsgi.py | 6 - teams_app/__init__.py | 1 - .../__pycache__/__init__.cpython-313.pyc | Bin 171 -> 0 bytes teams_app/__pycache__/admin.cpython-313.pyc | Bin 2989 -> 0 bytes teams_app/__pycache__/apps.cpython-313.pyc | Bin 540 -> 0 bytes teams_app/__pycache__/auth.cpython-313.pyc | Bin 3467 -> 0 bytes .../graphql_middleware.cpython-313.pyc | Bin 4408 -> 0 bytes teams_app/__pycache__/models.cpython-313.pyc | Bin 9636 -> 0 bytes .../__pycache__/permissions.cpython-313.pyc | Bin 3531 -> 0 bytes teams_app/__pycache__/views.cpython-313.pyc | Bin 4957 -> 0 bytes teams_app/admin.py | 45 - teams_app/apps.py | 5 - teams_app/auth.py | 70 - teams_app/graphql_middleware.py | 81 - teams_app/middleware.py | 56 - teams_app/migrations/0001_initial.py | 68 - teams_app/migrations/0002_add_user_profile.py | 30 - teams_app/migrations/0003_add_team_type.py | 18 - teams_app/migrations/0004_teamaddress.py | 33 - .../0005_remove_team_prefect_flow_run_id.py | 17 - ...dd_address_status_and_selected_location.py | 59 - .../0007_teamaddress_country_code.py | 18 - ...graph_node_id_and_change_default_status.py | 31 - .../0009_alter_teamaddress_status.py | 18 - .../migrations/0010_remove_team_status.py | 17 - .../migrations/0011_teaminvitationtoken.py | 30 - .../0012_add_selected_location_details.py | 28 - teams_app/migrations/__init__.py | 0 .../__pycache__/0001_initial.cpython-313.pyc | Bin 4448 -> 0 bytes .../0002_add_user_profile.cpython-313.pyc | Bin 2148 -> 0 bytes .../0003_add_team_type.cpython-313.pyc | Bin 916 -> 0 bytes .../0004_teamaddress.cpython-313.pyc | Bin 1964 -> 0 bytes ...e_team_prefect_flow_run_id.cpython-313.pyc | Bin 723 -> 0 bytes ...atus_and_selected_location.cpython-313.pyc | Bin 1809 -> 0 bytes ...7_teamaddress_country_code.cpython-313.pyc | Bin 868 -> 0 bytes ..._and_change_default_status.cpython-313.pyc | Bin 1133 -> 0 bytes ...9_alter_teamaddress_status.cpython-313.pyc | Bin 1006 -> 0 bytes .../0010_remove_team_status.cpython-313.pyc | Bin 710 -> 0 bytes .../0011_teaminvitationtoken.cpython-313.pyc | Bin 1930 -> 0 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 182 -> 0 bytes teams_app/models.py | 165 - teams_app/permissions.py | 74 - .../__pycache__/m2m_schema.cpython-313.pyc | Bin 18693 -> 0 bytes .../__pycache__/public_schema.cpython-313.pyc | Bin 883 -> 0 bytes .../__pycache__/team_schema.cpython-313.pyc | Bin 20307 -> 0 bytes .../__pycache__/user_schema.cpython-313.pyc | Bin 14149 -> 0 bytes teams_app/schemas/m2m_schema.py | 329 -- teams_app/schemas/public_schema.py | 12 - teams_app/schemas/team_schema.py | 418 -- teams_app/schemas/user_schema.py | 287 -- teams_app/services.py | 160 - teams_app/temporal_client.py | 168 - teams_app/tests.py | 98 - teams_app/views.py | 97 - tsconfig.json | 18 + 82 files changed, 5164 insertions(+), 3820 deletions(-) create mode 100644 .gitignore delete mode 100644 README.md delete mode 100644 db.sqlite3 delete mode 100644 manage.py delete mode 100644 nixpacks.toml create mode 100644 package-lock.json create mode 100644 package.json delete mode 100644 poetry.lock create mode 100644 prisma/schema.prisma delete mode 100644 pyproject.toml create mode 100644 src/auth.ts create mode 100644 src/db.ts create mode 100644 src/index.ts create mode 100644 src/schemas/m2m.ts create mode 100644 src/schemas/public.ts create mode 100644 src/schemas/team.ts create mode 100644 src/schemas/user.ts create mode 100644 src/services/temporal.ts delete mode 100644 teams/__init__.py delete mode 100644 teams/__pycache__/__init__.cpython-313.pyc delete mode 100644 teams/__pycache__/settings.cpython-313.pyc delete mode 100644 teams/__pycache__/settings_local.cpython-313.pyc delete mode 100644 teams/__pycache__/urls.cpython-313.pyc delete mode 100644 teams/settings.py delete mode 100644 teams/settings_local.py delete mode 100644 teams/urls.py delete mode 100644 teams/wsgi.py delete mode 100644 teams_app/__init__.py delete mode 100644 teams_app/__pycache__/__init__.cpython-313.pyc delete mode 100644 teams_app/__pycache__/admin.cpython-313.pyc delete mode 100644 teams_app/__pycache__/apps.cpython-313.pyc delete mode 100644 teams_app/__pycache__/auth.cpython-313.pyc delete mode 100644 teams_app/__pycache__/graphql_middleware.cpython-313.pyc delete mode 100644 teams_app/__pycache__/models.cpython-313.pyc delete mode 100644 teams_app/__pycache__/permissions.cpython-313.pyc delete mode 100644 teams_app/__pycache__/views.cpython-313.pyc delete mode 100644 teams_app/admin.py delete mode 100644 teams_app/apps.py delete mode 100644 teams_app/auth.py delete mode 100644 teams_app/graphql_middleware.py delete mode 100644 teams_app/middleware.py delete mode 100644 teams_app/migrations/0001_initial.py delete mode 100644 teams_app/migrations/0002_add_user_profile.py delete mode 100644 teams_app/migrations/0003_add_team_type.py delete mode 100644 teams_app/migrations/0004_teamaddress.py delete mode 100644 teams_app/migrations/0005_remove_team_prefect_flow_run_id.py delete mode 100644 teams_app/migrations/0006_add_address_status_and_selected_location.py delete mode 100644 teams_app/migrations/0007_teamaddress_country_code.py delete mode 100644 teams_app/migrations/0008_remove_graph_node_id_and_change_default_status.py delete mode 100644 teams_app/migrations/0009_alter_teamaddress_status.py delete mode 100644 teams_app/migrations/0010_remove_team_status.py delete mode 100644 teams_app/migrations/0011_teaminvitationtoken.py delete mode 100644 teams_app/migrations/0012_add_selected_location_details.py delete mode 100644 teams_app/migrations/__init__.py delete mode 100644 teams_app/migrations/__pycache__/0001_initial.cpython-313.pyc delete mode 100644 teams_app/migrations/__pycache__/0002_add_user_profile.cpython-313.pyc delete mode 100644 teams_app/migrations/__pycache__/0003_add_team_type.cpython-313.pyc delete mode 100644 teams_app/migrations/__pycache__/0004_teamaddress.cpython-313.pyc delete mode 100644 teams_app/migrations/__pycache__/0005_remove_team_prefect_flow_run_id.cpython-313.pyc delete mode 100644 teams_app/migrations/__pycache__/0006_add_address_status_and_selected_location.cpython-313.pyc delete mode 100644 teams_app/migrations/__pycache__/0007_teamaddress_country_code.cpython-313.pyc delete mode 100644 teams_app/migrations/__pycache__/0008_remove_graph_node_id_and_change_default_status.cpython-313.pyc delete mode 100644 teams_app/migrations/__pycache__/0009_alter_teamaddress_status.cpython-313.pyc delete mode 100644 teams_app/migrations/__pycache__/0010_remove_team_status.cpython-313.pyc delete mode 100644 teams_app/migrations/__pycache__/0011_teaminvitationtoken.cpython-313.pyc delete mode 100644 teams_app/migrations/__pycache__/__init__.cpython-313.pyc delete mode 100644 teams_app/models.py delete mode 100644 teams_app/permissions.py delete mode 100644 teams_app/schemas/__pycache__/m2m_schema.cpython-313.pyc delete mode 100644 teams_app/schemas/__pycache__/public_schema.cpython-313.pyc delete mode 100644 teams_app/schemas/__pycache__/team_schema.cpython-313.pyc delete mode 100644 teams_app/schemas/__pycache__/user_schema.cpython-313.pyc delete mode 100644 teams_app/schemas/m2m_schema.py delete mode 100644 teams_app/schemas/public_schema.py delete mode 100644 teams_app/schemas/team_schema.py delete mode 100644 teams_app/schemas/user_schema.py delete mode 100644 teams_app/services.py delete mode 100644 teams_app/temporal_client.py delete mode 100644 teams_app/tests.py delete mode 100644 teams_app/views.py create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f06235c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +dist diff --git a/Dockerfile b/Dockerfile index 09bc067..f1daba3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,24 +1,28 @@ -FROM python:3.12-slim - -ENV PYTHONDONTWRITEBYTECODE=1 \ - PYTHONUNBUFFERED=1 \ - NIXPACKS_POETRY_VERSION=2.2.1 +FROM node:22-alpine AS builder WORKDIR /app -RUN apt-get update \ - && apt-get install -y --no-install-recommends build-essential curl \ - && rm -rf /var/lib/apt/lists/* +COPY package.json ./ +RUN npm install -RUN python -m venv --copies /opt/venv -ENV VIRTUAL_ENV=/opt/venv -ENV PATH="/opt/venv/bin:$PATH" +COPY prisma ./prisma +RUN npx prisma generate -COPY . . +COPY tsconfig.json ./ +COPY src ./src +RUN npm run build -RUN pip install --no-cache-dir poetry==$NIXPACKS_POETRY_VERSION \ - && poetry install --no-interaction --no-ansi +FROM node:22-alpine -ENV PORT=8000 +WORKDIR /app -CMD ["sh", "-c", "poetry run python manage.py migrate && poetry run python manage.py collectstatic --noinput && poetry run python -m gunicorn teams.wsgi:application --bind 0.0.0.0:${PORT:-8000}"] +COPY package.json ./ +RUN npm install --omit=dev + +COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma +COPY --from=builder /app/dist ./dist +COPY prisma ./prisma + +EXPOSE 8000 + +CMD ["sh", "-c", "npx prisma migrate deploy && node dist/index.js"] diff --git a/README.md b/README.md deleted file mode 100644 index 039d672..0000000 --- a/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Teams Service - -Backend сервис для управления командами и участниками в системе Optovia. - -## Описание - -Сервис для управления командами с интеграцией Logto для аутентификации. Включает управление участниками, приглашениями и KYC статусами команд. - -## Основные функции - -- Создание и управление командами -- Управление участниками команд (OWNER, ADMIN, MANAGER, MEMBER) -- Система приглашений в команды -- Интеграция с Logto для аутентификации -- KYC статусы команд -- Управление активной командой пользователя - -## Модели данных - -- **Team** - модель команды с KYC статусами -- **TeamMember** - участники команды с ролями -- **TeamInvitation** - приглашения в команды -- **User** - пользователи с привязкой к Logto - -## KYC статусы команд - -- `PENDING_KYC` - Требуется KYC -- `KYC_IN_REVIEW` - KYC на рассмотрении -- `KYC_APPROVED` - KYC одобрен -- `KYC_REJECTED` - KYC отклонен -- `SUSPENDED` - Заблокировано - -## Технологии - -- Django 5.2.8 -- GraphQL (Graphene-Django) -- PostgreSQL -- Logto Integration -- Gunicorn - -## Развертывание - -Проект развертывается через Nixpacks на Dokploy с автоматическими миграциями. - -## Автор - -Ruslan Bakiev diff --git a/db.sqlite3 b/db.sqlite3 deleted file mode 100644 index e69de29..0000000 diff --git a/manage.py b/manage.py deleted file mode 100644 index df2eb1b..0000000 --- a/manage.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python -"""Django's command-line utility for administrative tasks.""" -import os -import sys - -if __name__ == '__main__': - """Run administrative tasks.""" - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'teams.settings') - try: - from django.core.management import execute_from_command_line - except ImportError as exc: - raise ImportError( - "Couldn't import Django. Are you sure it's installed and " - "available on your PYTHONPATH environment variable? Did you " - "forget to activate a virtual environment?" - ) from exc - execute_from_command_line(sys.argv) \ No newline at end of file diff --git a/nixpacks.toml b/nixpacks.toml deleted file mode 100644 index b3161ac..0000000 --- a/nixpacks.toml +++ /dev/null @@ -1,18 +0,0 @@ -providers = ["python"] - -[build] - -[phases.install] -cmds = [ - "python -m venv --copies /opt/venv", - ". /opt/venv/bin/activate", - "pip install poetry==$NIXPACKS_POETRY_VERSION", - "poetry install --no-interaction --no-ansi" -] - -[start] -cmd = "poetry run python manage.py migrate && poetry run python manage.py collectstatic --noinput && poetry run python -m gunicorn teams.wsgi:application --bind 0.0.0.0:${PORT:-8000}" - -[variables] -# Set Poetry version to match local environment -NIXPACKS_POETRY_VERSION = "2.2.1" diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..33f7354 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4183 @@ +{ + "name": "teams", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "teams", + "version": "1.0.0", + "dependencies": { + "@apollo/server": "^4.11.3", + "@prisma/client": "^6.5.0", + "@sentry/node": "^9.5.0", + "@temporalio/client": "^1.11.7", + "cors": "^2.8.5", + "express": "^4.21.2", + "graphql": "^16.10.0", + "graphql-tag": "^2.12.6", + "jose": "^6.0.11" + }, + "devDependencies": { + "@types/cors": "^2.8.17", + "@types/express": "^5.0.0", + "@types/node": "^22.13.0", + "prisma": "^6.5.0", + "tsx": "^4.19.0", + "typescript": "^5.7.0" + } + }, + "node_modules/@apollo/cache-control-types": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@apollo/cache-control-types/-/cache-control-types-1.0.3.tgz", + "integrity": "sha512-F17/vCp7QVwom9eG7ToauIKdAxpSoadsJnqIfyryLFSkLSOEqu+eC5Z3N8OXcUVStuOMcNHlyraRsA6rRICu4g==", + "license": "MIT", + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/protobufjs": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.7.tgz", + "integrity": "sha512-Lahx5zntHPZia35myYDBRuF58tlwPskwHc5CWBZC/4bMKB6siTBWwtMrkqXcsNwQiFSzSx5hKdRPUmemrEp3Gg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "long": "^4.0.0" + }, + "bin": { + "apollo-pbjs": "bin/pbjs", + "apollo-pbts": "bin/pbts" + } + }, + "node_modules/@apollo/server": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@apollo/server/-/server-4.13.0.tgz", + "integrity": "sha512-t4GzaRiYIcPwYy40db6QjZzgvTr9ztDKBddykUXmBb2SVjswMKXbkaJ5nPeHqmT3awr9PAaZdCZdZhRj55I/8A==", + "deprecated": "Apollo Server v4 is end-of-life since January 26, 2026. As long as you are already using a non-EOL version of Node.js, upgrading to v5 should take only a few minutes. See https://www.apollographql.com/docs/apollo-server/previous-versions for details.", + "license": "MIT", + "dependencies": { + "@apollo/cache-control-types": "^1.0.3", + "@apollo/server-gateway-interface": "^1.1.1", + "@apollo/usage-reporting-protobuf": "^4.1.1", + "@apollo/utils.createhash": "^2.0.2", + "@apollo/utils.fetcher": "^2.0.0", + "@apollo/utils.isnodelike": "^2.0.0", + "@apollo/utils.keyvaluecache": "^2.1.0", + "@apollo/utils.logger": "^2.0.0", + "@apollo/utils.usagereporting": "^2.1.0", + "@apollo/utils.withrequired": "^2.0.0", + "@graphql-tools/schema": "^9.0.0", + "@types/express": "^4.17.13", + "@types/express-serve-static-core": "^4.17.30", + "@types/node-fetch": "^2.6.1", + "async-retry": "^1.2.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "express": "^4.21.1", + "loglevel": "^1.6.8", + "lru-cache": "^7.10.1", + "negotiator": "^0.6.3", + "node-abort-controller": "^3.1.1", + "node-fetch": "^2.6.7", + "uuid": "^9.0.0", + "whatwg-mimetype": "^3.0.0" + }, + "engines": { + "node": ">=14.16.0" + }, + "peerDependencies": { + "graphql": "^16.6.0" + } + }, + "node_modules/@apollo/server-gateway-interface": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@apollo/server-gateway-interface/-/server-gateway-interface-1.1.1.tgz", + "integrity": "sha512-pGwCl/po6+rxRmDMFgozKQo2pbsSwE91TpsDBAOgf74CRDPXHHtM88wbwjab0wMMZh95QfR45GGyDIdhY24bkQ==", + "deprecated": "@apollo/server-gateway-interface v1 is part of Apollo Server v4, which is deprecated and will transition to end-of-life on January 26, 2026. As long as you are already using a non-EOL version of Node.js, upgrading to v2 should take only a few minutes. See https://www.apollographql.com/docs/apollo-server/previous-versions for details.", + "license": "MIT", + "dependencies": { + "@apollo/usage-reporting-protobuf": "^4.1.1", + "@apollo/utils.fetcher": "^2.0.0", + "@apollo/utils.keyvaluecache": "^2.1.0", + "@apollo/utils.logger": "^2.0.0" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/server/node_modules/@types/express": { + "version": "4.17.25", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", + "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "^1" + } + }, + "node_modules/@apollo/server/node_modules/@types/send": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz", + "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@apollo/server/node_modules/@types/serve-static": { + "version": "1.15.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz", + "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "<1" + } + }, + "node_modules/@apollo/usage-reporting-protobuf": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@apollo/usage-reporting-protobuf/-/usage-reporting-protobuf-4.1.1.tgz", + "integrity": "sha512-u40dIUePHaSKVshcedO7Wp+mPiZsaU6xjv9J+VyxpoU/zL6Jle+9zWeG98tr/+SZ0nZ4OXhrbb8SNr0rAPpIDA==", + "license": "MIT", + "dependencies": { + "@apollo/protobufjs": "1.2.7" + } + }, + "node_modules/@apollo/utils.createhash": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@apollo/utils.createhash/-/utils.createhash-2.0.2.tgz", + "integrity": "sha512-UkS3xqnVFLZ3JFpEmU/2cM2iKJotQXMoSTgxXsfQgXLC5gR1WaepoXagmYnPSA7Q/2cmnyTYK5OgAgoC4RULPg==", + "license": "MIT", + "dependencies": { + "@apollo/utils.isnodelike": "^2.0.1", + "sha.js": "^2.4.11" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@apollo/utils.dropunuseddefinitions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.dropunuseddefinitions/-/utils.dropunuseddefinitions-2.0.1.tgz", + "integrity": "sha512-EsPIBqsSt2BwDsv8Wu76LK5R1KtsVkNoO4b0M5aK0hx+dGg9xJXuqlr7Fo34Dl+y83jmzn+UvEW+t1/GP2melA==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.fetcher": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.fetcher/-/utils.fetcher-2.0.1.tgz", + "integrity": "sha512-jvvon885hEyWXd4H6zpWeN3tl88QcWnHp5gWF5OPF34uhvoR+DFqcNxs9vrRaBBSY3qda3Qe0bdud7tz2zGx1A==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@apollo/utils.isnodelike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.isnodelike/-/utils.isnodelike-2.0.1.tgz", + "integrity": "sha512-w41XyepR+jBEuVpoRM715N2ZD0xMD413UiJx8w5xnAZD2ZkSJnMJBoIzauK83kJpSgNuR6ywbV29jG9NmxjK0Q==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@apollo/utils.keyvaluecache": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.keyvaluecache/-/utils.keyvaluecache-2.1.1.tgz", + "integrity": "sha512-qVo5PvUUMD8oB9oYvq4ViCjYAMWnZ5zZwEjNF37L2m1u528x5mueMlU+Cr1UinupCgdB78g+egA1G98rbJ03Vw==", + "license": "MIT", + "dependencies": { + "@apollo/utils.logger": "^2.0.1", + "lru-cache": "^7.14.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@apollo/utils.logger": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.logger/-/utils.logger-2.0.1.tgz", + "integrity": "sha512-YuplwLHaHf1oviidB7MxnCXAdHp3IqYV8n0momZ3JfLniae92eYqMIx+j5qJFX6WKJPs6q7bczmV4lXIsTu5Pg==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@apollo/utils.printwithreducedwhitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.printwithreducedwhitespace/-/utils.printwithreducedwhitespace-2.0.1.tgz", + "integrity": "sha512-9M4LUXV/fQBh8vZWlLvb/HyyhjJ77/I5ZKu+NBWV/BmYGyRmoEP9EVAy7LCVoY3t8BDcyCAGfxJaLFCSuQkPUg==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.removealiases": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.removealiases/-/utils.removealiases-2.0.1.tgz", + "integrity": "sha512-0joRc2HBO4u594Op1nev+mUF6yRnxoUH64xw8x3bX7n8QBDYdeYgY4tF0vJReTy+zdn2xv6fMsquATSgC722FA==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.sortast": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.sortast/-/utils.sortast-2.0.1.tgz", + "integrity": "sha512-eciIavsWpJ09za1pn37wpsCGrQNXUhM0TktnZmHwO+Zy9O4fu/WdB4+5BvVhFiZYOXvfjzJUcc+hsIV8RUOtMw==", + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.stripsensitiveliterals": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.stripsensitiveliterals/-/utils.stripsensitiveliterals-2.0.1.tgz", + "integrity": "sha512-QJs7HtzXS/JIPMKWimFnUMK7VjkGQTzqD9bKD1h3iuPAqLsxd0mUNVbkYOPTsDhUKgcvUOfOqOJWYohAKMvcSA==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.usagereporting": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.usagereporting/-/utils.usagereporting-2.1.0.tgz", + "integrity": "sha512-LPSlBrn+S17oBy5eWkrRSGb98sWmnEzo3DPTZgp8IQc8sJe0prDgDuppGq4NeQlpoqEHz0hQeYHAOA0Z3aQsxQ==", + "license": "MIT", + "dependencies": { + "@apollo/usage-reporting-protobuf": "^4.1.0", + "@apollo/utils.dropunuseddefinitions": "^2.0.1", + "@apollo/utils.printwithreducedwhitespace": "^2.0.1", + "@apollo/utils.removealiases": "2.0.1", + "@apollo/utils.sortast": "^2.0.1", + "@apollo/utils.stripsensitiveliterals": "^2.0.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.withrequired": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.withrequired/-/utils.withrequired-2.0.1.tgz", + "integrity": "sha512-YBDiuAX9i1lLc6GeTy1m7DGLFn/gMnvXqlalOIMjM7DeOgIacEjjfwPqb0M1CQ2v11HhR15d1NmxJoRCfrNqcA==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@graphql-tools/merge": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.4.2.tgz", + "integrity": "sha512-XbrHAaj8yDuINph+sAfuq3QCZ/tKblrTLOpirK0+CAgNlZUCHs0Fa+xtMUURgwCVThLle1AF7svJCxFizygLsw==", + "license": "MIT", + "dependencies": { + "@graphql-tools/utils": "^9.2.1", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/schema": { + "version": "9.0.19", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.19.tgz", + "integrity": "sha512-oBRPoNBtCkk0zbUsyP4GaIzCt8C0aCI4ycIRUL67KK5pOHljKLBBtGT+Jr6hkzA74C8Gco8bpZPe7aWFjiaK2w==", + "license": "MIT", + "dependencies": { + "@graphql-tools/merge": "^8.4.1", + "@graphql-tools/utils": "^9.2.1", + "tslib": "^2.4.0", + "value-or-promise": "^1.0.12" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/utils": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz", + "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==", + "license": "MIT", + "dependencies": { + "@graphql-typed-document-node/core": "^3.1.1", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-typed-document-node/core": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", + "license": "MIT", + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.3.tgz", + "integrity": "sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.8.0", + "@js-sdsl/ordered-map": "^4.4.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.0.tgz", + "integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.5.3", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@grpc/proto-loader/node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.30.1.tgz", + "integrity": "sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-amqplib": { + "version": "0.46.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.46.1.tgz", + "integrity": "sha512-AyXVnlCf/xV3K/rNumzKxZqsULyITJH6OVLiW6730JPRqWA7Zc9bvYoVNpN6iOpTU8CasH34SU/ksVJmObFibQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-connect": { + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.43.1.tgz", + "integrity": "sha512-ht7YGWQuV5BopMcw5Q2hXn3I8eG8TH0J/kc/GMcW4CuNTgiP6wCu44BOnucJWL3CmFWaRHI//vWyAhaC8BwePw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/connect": "3.4.38" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-dataloader": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.16.1.tgz", + "integrity": "sha512-K/qU4CjnzOpNkkKO4DfCLSQshejRNAJtd4esgigo/50nxCB6XCyi1dhAblUHM9jG5dRm8eu0FB+t87nIo99LYQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-express": { + "version": "0.47.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.47.1.tgz", + "integrity": "sha512-QNXPTWteDclR2B4pDFpz0TNghgB33UMjUt14B+BZPmtH1MwUFAfLHBaP5If0Z5NZC+jaH8oF2glgYjrmhZWmSw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fs": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.19.1.tgz", + "integrity": "sha512-6g0FhB3B9UobAR60BGTcXg4IHZ6aaYJzp0Ki5FhnxyAPt8Ns+9SSvgcrnsN2eGmk3RWG5vYycUGOEApycQL24A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-generic-pool": { + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.43.1.tgz", + "integrity": "sha512-M6qGYsp1cURtvVLGDrPPZemMFEbuMmCXgQYTReC/IbimV5sGrLBjB+/hANUpRZjX67nGLdKSVLZuQQAiNz+sww==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-graphql": { + "version": "0.47.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.47.1.tgz", + "integrity": "sha512-EGQRWMGqwiuVma8ZLAZnExQ7sBvbOx0N/AE/nlafISPs8S+QtXX+Viy6dcQwVWwYHQPAcuY3bFt3xgoAwb4ZNQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-hapi": { + "version": "0.45.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.45.2.tgz", + "integrity": "sha512-7Ehow/7Wp3aoyCrZwQpU7a2CnoMq0XhIcioFuKjBb0PLYfBfmTsFTUyatlHu0fRxhwcRsSQRTvEhmZu8CppBpQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.57.2.tgz", + "integrity": "sha512-1Uz5iJ9ZAlFOiPuwYg29Bf7bJJc/GeoeJIFKJYQf67nTVKFe8RHbEtxgkOmK4UGZNHKXcpW4P8cWBYzBn1USpg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/instrumentation": "0.57.2", + "@opentelemetry/semantic-conventions": "1.28.0", + "forwarded-parse": "2.1.2", + "semver": "^7.5.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-ioredis": { + "version": "0.47.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.47.1.tgz", + "integrity": "sha512-OtFGSN+kgk/aoKgdkKQnBsQFDiG8WdCxu+UrHr0bXScdAmtSzLSraLo7wFIb25RVHfRWvzI5kZomqJYEg/l1iA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/redis-common": "^0.36.2", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-kafkajs": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.7.1.tgz", + "integrity": "sha512-OtjaKs8H7oysfErajdYr1yuWSjMAectT7Dwr+axIoZqT9lmEOkD/H/3rgAs8h/NIuEi2imSXD+vL4MZtOuJfqQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-knex": { + "version": "0.44.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.44.1.tgz", + "integrity": "sha512-U4dQxkNhvPexffjEmGwCq68FuftFK15JgUF05y/HlK3M6W/G2iEaACIfXdSnwVNe9Qh0sPfw8LbOPxrWzGWGMQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-koa": { + "version": "0.47.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.47.1.tgz", + "integrity": "sha512-l/c+Z9F86cOiPJUllUCt09v+kICKvT+Vg1vOAJHtHPsJIzurGayucfCMq2acd/A/yxeNWunl9d9eqZ0G+XiI6A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-lru-memoizer": { + "version": "0.44.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.44.1.tgz", + "integrity": "sha512-5MPkYCvG2yw7WONEjYj5lr5JFehTobW7wX+ZUFy81oF2lr9IPfZk9qO+FTaM0bGEiymwfLwKe6jE15nHn1nmHg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongodb": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.52.0.tgz", + "integrity": "sha512-1xmAqOtRUQGR7QfJFfGV/M2kC7wmI2WgZdpru8hJl3S0r4hW0n3OQpEHlSGXJAaNFyvT+ilnwkT+g5L4ljHR6g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose": { + "version": "0.46.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.46.1.tgz", + "integrity": "sha512-3kINtW1LUTPkiXFRSSBmva1SXzS/72we/jL22N+BnF3DFcoewkdkHPYOIdAAk9gSicJ4d5Ojtt1/HeibEc5OQg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql": { + "version": "0.45.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.45.1.tgz", + "integrity": "sha512-TKp4hQ8iKQsY7vnp/j0yJJ4ZsP109Ht6l4RHTj0lNEG1TfgTrIH5vJMbgmoYXWzNHAqBH2e7fncN12p3BP8LFg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/mysql": "2.15.26" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql2": { + "version": "0.45.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.45.2.tgz", + "integrity": "sha512-h6Ad60FjCYdJZ5DTz1Lk2VmQsShiViKe0G7sYikb0GHI0NVvApp2XQNRHNjEMz87roFttGPLHOYVPlfy+yVIhQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/sql-common": "^0.40.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.51.1.tgz", + "integrity": "sha512-QxgjSrxyWZc7Vk+qGSfsejPVFL1AgAJdSBMYZdDUbwg730D09ub3PXScB9d04vIqPriZ+0dqzjmQx0yWKiCi2Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.26.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/sql-common": "^0.40.1", + "@types/pg": "8.6.1", + "@types/pg-pool": "2.0.6" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-redis-4": { + "version": "0.46.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis-4/-/instrumentation-redis-4-0.46.1.tgz", + "integrity": "sha512-UMqleEoabYMsWoTkqyt9WAzXwZ4BlFZHO40wr3d5ZvtjKCHlD4YXLm+6OLCeIi/HkX7EXvQaz8gtAwkwwSEvcQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/redis-common": "^0.36.2", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.18.1.tgz", + "integrity": "sha512-5Cuy/nj0HBaH+ZJ4leuD7RjgvA844aY2WW+B5uLcWtxGjRZl3MNLuxnNg5DYWZNPO+NafSSnra0q49KWAHsKBg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/tedious": "^4.0.14" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-undici": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.10.1.tgz", + "integrity": "sha512-rkOGikPEyRpMCmNu9AQuV5dtRlDmJp2dK5sw8roVshAGoB6hH/3QjDtRhdwd75SsJwgynWUNRUYe0wAkTo16tQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.7.0" + } + }, + "node_modules/@opentelemetry/redis-common": { + "version": "0.36.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.36.2.tgz", + "integrity": "sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", + "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/resources/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.30.1.tgz", + "integrity": "sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.40.0.tgz", + "integrity": "sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sql-common": { + "version": "0.40.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.40.1.tgz", + "integrity": "sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.1.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0" + } + }, + "node_modules/@prisma/client": { + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.19.2.tgz", + "integrity": "sha512-gR2EMvfK/aTxsuooaDA32D8v+us/8AAet+C3J1cc04SW35FPdZYgLF+iN4NDLUgAaUGTKdAB0CYenu1TAgGdMg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "peerDependencies": { + "prisma": "*", + "typescript": ">=5.1.0" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@prisma/config": { + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.19.2.tgz", + "integrity": "sha512-kadBGDl+aUswv/zZMk9Mx0C8UZs1kjao8H9/JpI4Wh4SHZaM7zkTwiKn/iFLfRg+XtOAo/Z/c6pAYhijKl0nzQ==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "c12": "3.1.0", + "deepmerge-ts": "7.1.5", + "effect": "3.18.4", + "empathic": "2.0.0" + } + }, + "node_modules/@prisma/debug": { + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.19.2.tgz", + "integrity": "sha512-lFnEZsLdFLmEVCVNdskLDCL8Uup41GDfU0LUfquw+ercJC8ODTuL0WNKgOKmYxCJVvFwf0OuZBzW99DuWmoH2A==", + "devOptional": true, + "license": "Apache-2.0" + }, + "node_modules/@prisma/engines": { + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.19.2.tgz", + "integrity": "sha512-TTkJ8r+uk/uqczX40wb+ODG0E0icVsMgwCTyTHXehaEfb0uo80M9g1aW1tEJrxmFHeOZFXdI2sTA1j1AgcHi4A==", + "devOptional": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "6.19.2", + "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", + "@prisma/fetch-engine": "6.19.2", + "@prisma/get-platform": "6.19.2" + } + }, + "node_modules/@prisma/engines-version": { + "version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7.tgz", + "integrity": "sha512-03bgb1VD5gvuumNf+7fVGBzfpJPjmqV423l/WxsWk2cNQ42JD0/SsFBPhN6z8iAvdHs07/7ei77SKu7aZfq8bA==", + "devOptional": true, + "license": "Apache-2.0" + }, + "node_modules/@prisma/fetch-engine": { + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.19.2.tgz", + "integrity": "sha512-h4Ff4Pho+SR1S8XerMCC12X//oY2bG3Iug/fUnudfcXEUnIeRiBdXHFdGlGOgQ3HqKgosTEhkZMvGM9tWtYC+Q==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "6.19.2", + "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", + "@prisma/get-platform": "6.19.2" + } + }, + "node_modules/@prisma/get-platform": { + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.19.2.tgz", + "integrity": "sha512-PGLr06JUSTqIvztJtAzIxOwtWKtJm5WwOG6xpsgD37Rc84FpfUBGLKz65YpJBGtkRQGXTYEFie7pYALocC3MtA==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "6.19.2" + } + }, + "node_modules/@prisma/instrumentation": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-6.11.1.tgz", + "integrity": "sha512-mrZOev24EDhnefmnZX7WVVT7v+r9LttPRqf54ONvj6re4XMF7wFTpK2tLJi4XHB7fFp/6xhYbgRel8YV7gQiyA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.52.0 || ^0.53.0 || ^0.54.0 || ^0.55.0 || ^0.56.0 || ^0.57.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.8" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@sentry/core": { + "version": "9.47.1", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.47.1.tgz", + "integrity": "sha512-KX62+qIt4xgy8eHKHiikfhz2p5fOciXd0Cl+dNzhgPFq8klq4MGMNaf148GB3M/vBqP4nw/eFvRMAayFCgdRQw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/node": { + "version": "9.47.1", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-9.47.1.tgz", + "integrity": "sha512-CDbkasBz3fnWRKSFs6mmaRepM2pa+tbZkrqhPWifFfIkJDidtVW40p6OnquTvPXyPAszCnDZRnZT14xyvNmKPQ==", + "license": "MIT", + "dependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1", + "@opentelemetry/core": "^1.30.1", + "@opentelemetry/instrumentation": "^0.57.2", + "@opentelemetry/instrumentation-amqplib": "^0.46.1", + "@opentelemetry/instrumentation-connect": "0.43.1", + "@opentelemetry/instrumentation-dataloader": "0.16.1", + "@opentelemetry/instrumentation-express": "0.47.1", + "@opentelemetry/instrumentation-fs": "0.19.1", + "@opentelemetry/instrumentation-generic-pool": "0.43.1", + "@opentelemetry/instrumentation-graphql": "0.47.1", + "@opentelemetry/instrumentation-hapi": "0.45.2", + "@opentelemetry/instrumentation-http": "0.57.2", + "@opentelemetry/instrumentation-ioredis": "0.47.1", + "@opentelemetry/instrumentation-kafkajs": "0.7.1", + "@opentelemetry/instrumentation-knex": "0.44.1", + "@opentelemetry/instrumentation-koa": "0.47.1", + "@opentelemetry/instrumentation-lru-memoizer": "0.44.1", + "@opentelemetry/instrumentation-mongodb": "0.52.0", + "@opentelemetry/instrumentation-mongoose": "0.46.1", + "@opentelemetry/instrumentation-mysql": "0.45.1", + "@opentelemetry/instrumentation-mysql2": "0.45.2", + "@opentelemetry/instrumentation-pg": "0.51.1", + "@opentelemetry/instrumentation-redis-4": "0.46.1", + "@opentelemetry/instrumentation-tedious": "0.18.1", + "@opentelemetry/instrumentation-undici": "0.10.1", + "@opentelemetry/resources": "^1.30.1", + "@opentelemetry/sdk-trace-base": "^1.30.1", + "@opentelemetry/semantic-conventions": "^1.34.0", + "@prisma/instrumentation": "6.11.1", + "@sentry/core": "9.47.1", + "@sentry/node-core": "9.47.1", + "@sentry/opentelemetry": "9.47.1", + "import-in-the-middle": "^1.14.2", + "minimatch": "^9.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/node-core": { + "version": "9.47.1", + "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-9.47.1.tgz", + "integrity": "sha512-7TEOiCGkyShJ8CKtsri9lbgMCbB+qNts2Xq37itiMPN2m+lIukK3OX//L8DC5nfKYZlgikrefS63/vJtm669hQ==", + "license": "MIT", + "dependencies": { + "@sentry/core": "9.47.1", + "@sentry/opentelemetry": "9.47.1", + "import-in-the-middle": "^1.14.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.0.0", + "@opentelemetry/core": "^1.30.1 || ^2.0.0", + "@opentelemetry/instrumentation": ">=0.57.1 <1", + "@opentelemetry/resources": "^1.30.1 || ^2.0.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.0.0", + "@opentelemetry/semantic-conventions": "^1.34.0" + } + }, + "node_modules/@sentry/opentelemetry": { + "version": "9.47.1", + "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-9.47.1.tgz", + "integrity": "sha512-STtFpjF7lwzeoedDJV+5XA6P89BfmFwFftmHSGSe3UTI8z8IoiR5yB6X2vCjSPvXlfeOs13qCNNCEZyznxM8Xw==", + "license": "MIT", + "dependencies": { + "@sentry/core": "9.47.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.0.0", + "@opentelemetry/core": "^1.30.1 || ^2.0.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.0.0", + "@opentelemetry/semantic-conventions": "^1.34.0" + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/@temporalio/client": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@temporalio/client/-/client-1.15.0.tgz", + "integrity": "sha512-SxTGqRIa2+Vy4P9+06ZpUf4u7ZZmOXfx/kr9XvNqAApLxTMKjTQIg5OH5Wt4JLUtIR7dFkuHIyhewdRyG+hSsQ==", + "license": "MIT", + "dependencies": { + "@grpc/grpc-js": "^1.12.4", + "@temporalio/common": "1.15.0", + "@temporalio/proto": "1.15.0", + "abort-controller": "^3.0.0", + "long": "^5.2.3", + "uuid": "^11.1.0" + }, + "engines": { + "node": ">= 20.0.0" + } + }, + "node_modules/@temporalio/client/node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/@temporalio/client/node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/@temporalio/common": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@temporalio/common/-/common-1.15.0.tgz", + "integrity": "sha512-tBfC3fdOExsNoS5krkMUXnaMtCRKj05Jts4+TH+cgHpbys68nslFvUQLqwPIw2x6155Divb9MF219a/75itbTg==", + "license": "MIT", + "dependencies": { + "@temporalio/proto": "1.15.0", + "long": "^5.2.3", + "ms": "3.0.0-canary.1", + "nexus-rpc": "^0.0.1", + "proto3-json-serializer": "^2.0.0" + }, + "engines": { + "node": ">= 20.0.0" + } + }, + "node_modules/@temporalio/common/node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/@temporalio/proto": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@temporalio/proto/-/proto-1.15.0.tgz", + "integrity": "sha512-Awy4Fjzyba7Pg/CVZjjQ3x2CWkDL1qELyTZWcLlyjXq8bX694JVfBsmiMmF6tHn5/ySOIxDTcc0MSScZ0oKX5A==", + "license": "MIT", + "dependencies": { + "long": "^5.2.3", + "protobufjs": "^7.2.5" + }, + "engines": { + "node": ">= 20.0.0" + } + }, + "node_modules/@temporalio/proto/node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz", + "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/serve-static": "^2" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.8", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz", + "integrity": "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/express/node_modules/@types/express-serve-static-core": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.1.tgz", + "integrity": "sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "license": "MIT" + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" + }, + "node_modules/@types/mysql": { + "version": "2.15.26", + "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.26.tgz", + "integrity": "sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "22.19.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.15.tgz", + "integrity": "sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.4" + } + }, + "node_modules/@types/pg": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz", + "integrity": "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "node_modules/@types/pg-pool": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.6.tgz", + "integrity": "sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==", + "license": "MIT", + "dependencies": { + "@types/pg": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", + "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*" + } + }, + "node_modules/@types/shimmer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.2.0.tgz", + "integrity": "sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==", + "license": "MIT" + }, + "node_modules/@types/tedious": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", + "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "license": "MIT", + "dependencies": { + "retry": "0.13.1" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/c12": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/c12/-/c12-3.1.0.tgz", + "integrity": "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.3", + "confbox": "^0.2.2", + "defu": "^6.1.4", + "dotenv": "^16.6.1", + "exsolve": "^1.0.7", + "giget": "^2.0.0", + "jiti": "^2.4.2", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "perfect-debounce": "^1.0.0", + "pkg-types": "^2.2.0", + "rc9": "^2.1.2" + }, + "peerDependencies": { + "magicast": "^0.3.5" + }, + "peerDependenciesMeta": { + "magicast": { + "optional": true + } + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/citty": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", + "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "consola": "^3.2.3" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "license": "MIT" + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/confbox": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz", + "integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/deepmerge-ts": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz", + "integrity": "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==", + "devOptional": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "devOptional": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/effect": { + "version": "3.18.4", + "resolved": "https://registry.npmjs.org/effect/-/effect-3.18.4.tgz", + "integrity": "sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "fast-check": "^3.23.1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/empathic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz", + "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/express": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", + "content-type": "~1.0.4", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "~0.1.12", + "proxy-addr": "~2.0.7", + "qs": "~6.14.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "~0.19.0", + "serve-static": "~1.16.2", + "setprototypeof": "1.2.0", + "statuses": "~2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/exsolve": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", + "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/fast-check": { + "version": "3.23.2", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.23.2.tgz", + "integrity": "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==", + "devOptional": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT", + "dependencies": { + "pure-rand": "^6.1.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/finalhandler": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "statuses": "~2.0.2", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/forwarded-parse": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", + "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==", + "license": "MIT" + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.6", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz", + "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/giget": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/giget/-/giget-2.0.0.tgz", + "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.0", + "defu": "^6.1.4", + "node-fetch-native": "^1.6.6", + "nypm": "^0.6.0", + "pathe": "^2.0.3" + }, + "bin": { + "giget": "dist/cli.mjs" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graphql": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.13.1.tgz", + "integrity": "sha512-gGgrVCoDKlIZ8fIqXBBb0pPKqDgki0Z/FSKNiQzSGj2uEYHr1tq5wmBegGwJx6QB5S5cM0khSBpi/JFHMCvsmQ==", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/graphql-tag": { + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", + "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/import-in-the-middle": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.15.0.tgz", + "integrity": "sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "devOptional": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/jose": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.0.tgz", + "integrity": "sha512-xsfE1TcSCbUdo6U07tR0mvhg0flGxU8tPLbF03mirl2ukGQENhUg4ubGYQnhVH0b5stLlPM+WOqDkEl1R1y5sQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT" + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "license": "MIT" + }, + "node_modules/loglevel": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", + "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "license": "Apache-2.0" + }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/module-details-from-path": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "3.0.0-canary.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-3.0.0-canary.1.tgz", + "integrity": "sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g==", + "license": "MIT", + "engines": { + "node": ">=12.13" + } + }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nexus-rpc": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/nexus-rpc/-/nexus-rpc-0.0.1.tgz", + "integrity": "sha512-hAWn8Hh2eewpB5McXR5EW81R3pR/ziuGhKCF3wFyUVCklanPqrIgMNr7jKCbzXeNVad0nUDfWpFRqh2u+zxQtw==", + "license": "MIT", + "engines": { + "node": ">= 18.0.0" + } + }, + "node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/nypm": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.5.tgz", + "integrity": "sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "citty": "^0.2.0", + "pathe": "^2.0.3", + "tinyexec": "^1.0.2" + }, + "bin": { + "nypm": "dist/cli.mjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/nypm/node_modules/citty": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.2.1.tgz", + "integrity": "sha512-kEV95lFBhQgtogAPlQfJJ0WGVSokvLr/UEoFPiKKOXF7pl98HfUVUD0ejsuTCld/9xH9vogSywZ5KqHzXrZpqg==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.13.0.tgz", + "integrity": "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-types": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", + "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.2.2", + "exsolve": "^1.0.7", + "pathe": "^2.0.3" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prisma": { + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.19.2.tgz", + "integrity": "sha512-XTKeKxtQElcq3U9/jHyxSPgiRgeYDKxWTPOf6NkXA0dNj5j40MfEsZkMbyNpwDWCUv7YBFUl7I2VK/6ALbmhEg==", + "devOptional": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/config": "6.19.2", + "@prisma/engines": "6.19.2" + }, + "bin": { + "prisma": "build/index.js" + }, + "engines": { + "node": ">=18.18" + }, + "peerDependencies": { + "typescript": ">=5.1.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/proto3-json-serializer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", + "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", + "license": "Apache-2.0", + "dependencies": { + "protobufjs": "^7.2.5" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/protobufjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/protobufjs/node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "devOptional": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", + "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc9": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", + "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "defu": "^6.1.4", + "destr": "^2.0.3" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/require-in-the-middle/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/require-in-the-middle/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/serve-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/sha.js": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", + "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" + }, + "bin": { + "sha.js": "bin.js" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", + "license": "BSD-2-Clause" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/to-buffer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", + "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "license": "MIT", + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/value-or-promise": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.12.tgz", + "integrity": "sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..29191a8 --- /dev/null +++ b/package.json @@ -0,0 +1,30 @@ +{ + "name": "teams", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "tsx watch src/index.ts", + "build": "prisma generate && tsc", + "start": "prisma migrate deploy && node dist/index.js" + }, + "dependencies": { + "@apollo/server": "^4.11.3", + "@prisma/client": "^6.5.0", + "@temporalio/client": "^1.11.7", + "cors": "^2.8.5", + "express": "^4.21.2", + "graphql": "^16.10.0", + "graphql-tag": "^2.12.6", + "jose": "^6.0.11", + "@sentry/node": "^9.5.0" + }, + "devDependencies": { + "@types/cors": "^2.8.17", + "@types/express": "^5.0.0", + "@types/node": "^22.13.0", + "prisma": "^6.5.0", + "tsx": "^4.19.0", + "typescript": "^5.7.0" + } +} diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index edff392..0000000 --- a/poetry.lock +++ /dev/null @@ -1,1005 +0,0 @@ -# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. - -[[package]] -name = "aenum" -version = "3.1.16" -description = "Advanced Enumerations (compatible with Python's stdlib Enum), NamedTuples, and NamedConstants" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "aenum-3.1.16-py2-none-any.whl", hash = "sha256:7810cbb6b4054b7654e5a7bafbe16e9ee1d25ef8e397be699f63f2f3a5800433"}, - {file = "aenum-3.1.16-py3-none-any.whl", hash = "sha256:9035092855a98e41b66e3d0998bd7b96280e85ceb3a04cc035636138a1943eaf"}, -] - -[[package]] -name = "asgiref" -version = "3.11.0" -description = "ASGI specs, helper code, and adapters" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "asgiref-3.11.0-py3-none-any.whl", hash = "sha256:1db9021efadb0d9512ce8ffaf72fcef601c7b73a8807a1bb2ef143dc6b14846d"}, - {file = "asgiref-3.11.0.tar.gz", hash = "sha256:13acff32519542a1736223fb79a715acdebe24286d98e8b164a73085f40da2c4"}, -] - -[package.extras] -tests = ["mypy (>=1.14.0)", "pytest", "pytest-asyncio"] - -[[package]] -name = "boto3" -version = "1.41.4" -description = "The AWS SDK for Python" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "boto3-1.41.4-py3-none-any.whl", hash = "sha256:77d84b7ce890a9b0c6a8993f8de106d8cf8138f332a4685e6de453965e60cb24"}, - {file = "boto3-1.41.4.tar.gz", hash = "sha256:2c6b8d13df6beb9255d0c8cb60a7a2164f5270580ea5b921a65658a0c28e3223"}, -] - -[package.dependencies] -botocore = ">=1.41.4,<1.42.0" -jmespath = ">=0.7.1,<2.0.0" -s3transfer = ">=0.15.0,<0.16.0" - -[package.extras] -crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] - -[[package]] -name = "botocore" -version = "1.41.4" -description = "Low-level, data-driven core of boto 3." -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "botocore-1.41.4-py3-none-any.whl", hash = "sha256:7143ef845f1d1400dbbf05d999f8c5e8cfaecd6bd84cbfbe5fa0a40e3a9f6353"}, - {file = "botocore-1.41.4.tar.gz", hash = "sha256:45c78f07b53a64cbe55e5d60297958f151bd4a2c6acb944a8bb65874bc2fd953"}, -] - -[package.dependencies] -jmespath = ">=0.7.1,<2.0.0" -python-dateutil = ">=2.1,<3.0.0" -urllib3 = {version = ">=1.25.4,<2.2.0 || >2.2.0,<3", markers = "python_version >= \"3.10\""} - -[package.extras] -crt = ["awscrt (==0.29.0)"] - -[[package]] -name = "certifi" -version = "2025.11.12" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b"}, - {file = "certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316"}, -] - -[[package]] -name = "cffi" -version = "2.0.0" -description = "Foreign Function Interface for Python calling C code." -optional = false -python-versions = ">=3.9" -groups = ["main"] -markers = "platform_python_implementation != \"PyPy\"" -files = [ - {file = "cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44"}, - {file = "cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49"}, - {file = "cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c"}, - {file = "cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb"}, - {file = "cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0"}, - {file = "cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4"}, - {file = "cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453"}, - {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495"}, - {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5"}, - {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb"}, - {file = "cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a"}, - {file = "cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739"}, - {file = "cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe"}, - {file = "cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c"}, - {file = "cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92"}, - {file = "cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93"}, - {file = "cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5"}, - {file = "cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664"}, - {file = "cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26"}, - {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9"}, - {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414"}, - {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743"}, - {file = "cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5"}, - {file = "cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5"}, - {file = "cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d"}, - {file = "cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d"}, - {file = "cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c"}, - {file = "cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe"}, - {file = "cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062"}, - {file = "cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e"}, - {file = "cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037"}, - {file = "cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba"}, - {file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94"}, - {file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187"}, - {file = "cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18"}, - {file = "cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5"}, - {file = "cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6"}, - {file = "cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb"}, - {file = "cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca"}, - {file = "cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b"}, - {file = "cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b"}, - {file = "cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2"}, - {file = "cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3"}, - {file = "cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26"}, - {file = "cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c"}, - {file = "cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b"}, - {file = "cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27"}, - {file = "cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75"}, - {file = "cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91"}, - {file = "cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5"}, - {file = "cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13"}, - {file = "cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b"}, - {file = "cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c"}, - {file = "cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef"}, - {file = "cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775"}, - {file = "cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205"}, - {file = "cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1"}, - {file = "cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f"}, - {file = "cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25"}, - {file = "cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad"}, - {file = "cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9"}, - {file = "cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d"}, - {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c"}, - {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8"}, - {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc"}, - {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592"}, - {file = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512"}, - {file = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4"}, - {file = "cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e"}, - {file = "cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6"}, - {file = "cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9"}, - {file = "cffi-2.0.0-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf"}, - {file = "cffi-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7"}, - {file = "cffi-2.0.0-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:4647afc2f90d1ddd33441e5b0e85b16b12ddec4fca55f0d9671fef036ecca27c"}, - {file = "cffi-2.0.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3f4d46d8b35698056ec29bca21546e1551a205058ae1a181d871e278b0b28165"}, - {file = "cffi-2.0.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e6e73b9e02893c764e7e8d5bb5ce277f1a009cd5243f8228f75f842bf937c534"}, - {file = "cffi-2.0.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:cb527a79772e5ef98fb1d700678fe031e353e765d1ca2d409c92263c6d43e09f"}, - {file = "cffi-2.0.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:61d028e90346df14fedc3d1e5441df818d095f3b87d286825dfcbd6459b7ef63"}, - {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0f6084a0ea23d05d20c3edcda20c3d006f9b6f3fefeac38f59262e10cef47ee2"}, - {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1cd13c99ce269b3ed80b417dcd591415d3372bcac067009b6e0f59c7d4015e65"}, - {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:89472c9762729b5ae1ad974b777416bfda4ac5642423fa93bd57a09204712322"}, - {file = "cffi-2.0.0-cp39-cp39-win32.whl", hash = "sha256:2081580ebb843f759b9f617314a24ed5738c51d2aee65d31e02f6f7a2b97707a"}, - {file = "cffi-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9"}, - {file = "cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529"}, -] - -[package.dependencies] -pycparser = {version = "*", markers = "implementation_name != \"PyPy\""} - -[[package]] -name = "charset-normalizer" -version = "3.4.4" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-win32.whl", hash = "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_riscv64.whl", hash = "sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-win32.whl", hash = "sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-win32.whl", hash = "sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-win_arm64.whl", hash = "sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50"}, - {file = "charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f"}, - {file = "charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a"}, -] - -[[package]] -name = "cryptography" -version = "46.0.3" -description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -optional = false -python-versions = "!=3.9.0,!=3.9.1,>=3.8" -groups = ["main"] -files = [ - {file = "cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a"}, - {file = "cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc"}, - {file = "cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d"}, - {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb"}, - {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849"}, - {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8"}, - {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec"}, - {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91"}, - {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e"}, - {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926"}, - {file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71"}, - {file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac"}, - {file = "cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018"}, - {file = "cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb"}, - {file = "cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c"}, - {file = "cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217"}, - {file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5"}, - {file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715"}, - {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54"}, - {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459"}, - {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422"}, - {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7"}, - {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044"}, - {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665"}, - {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3"}, - {file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20"}, - {file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de"}, - {file = "cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914"}, - {file = "cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db"}, - {file = "cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21"}, - {file = "cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936"}, - {file = "cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683"}, - {file = "cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d"}, - {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0"}, - {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc"}, - {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3"}, - {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971"}, - {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac"}, - {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04"}, - {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506"}, - {file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963"}, - {file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4"}, - {file = "cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df"}, - {file = "cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f"}, - {file = "cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372"}, - {file = "cryptography-46.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a23582810fedb8c0bc47524558fb6c56aac3fc252cb306072fd2815da2a47c32"}, - {file = "cryptography-46.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7aec276d68421f9574040c26e2a7c3771060bc0cff408bae1dcb19d3ab1e63c"}, - {file = "cryptography-46.0.3-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7ce938a99998ed3c8aa7e7272dca1a610401ede816d36d0693907d863b10d9ea"}, - {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:191bb60a7be5e6f54e30ba16fdfae78ad3a342a0599eb4193ba88e3f3d6e185b"}, - {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c70cc23f12726be8f8bc72e41d5065d77e4515efae3690326764ea1b07845cfb"}, - {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:9394673a9f4de09e28b5356e7fff97d778f8abad85c9d5ac4a4b7e25a0de7717"}, - {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94cd0549accc38d1494e1f8de71eca837d0509d0d44bf11d158524b0e12cebf9"}, - {file = "cryptography-46.0.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6b5063083824e5509fdba180721d55909ffacccc8adbec85268b48439423d78c"}, - {file = "cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1"}, -] - -[package.dependencies] -cffi = {version = ">=2.0.0", markers = "python_full_version >= \"3.9.0\" and platform_python_implementation != \"PyPy\""} - -[package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-inline-tabs", "sphinx-rtd-theme (>=3.0.0)"] -docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] -nox = ["nox[uv] (>=2024.4.15)"] -pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.14)", "ruff (>=0.11.11)"] -sdist = ["build (>=1.0.0)"] -ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi (>=2024)", "cryptography-vectors (==46.0.3)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] -test-randomorder = ["pytest-randomly"] - -[[package]] -name = "django" -version = "5.2.8" -description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." -optional = false -python-versions = ">=3.10" -groups = ["main"] -files = [ - {file = "django-5.2.8-py3-none-any.whl", hash = "sha256:37e687f7bd73ddf043e2b6b97cfe02fcbb11f2dbb3adccc6a2b18c6daa054d7f"}, - {file = "django-5.2.8.tar.gz", hash = "sha256:23254866a5bb9a2cfa6004e8b809ec6246eba4b58a7589bc2772f1bcc8456c7f"}, -] - -[package.dependencies] -asgiref = ">=3.8.1" -sqlparse = ">=0.3.1" -tzdata = {version = "*", markers = "sys_platform == \"win32\""} - -[package.extras] -argon2 = ["argon2-cffi (>=19.1.0)"] -bcrypt = ["bcrypt"] - -[[package]] -name = "django-cors-headers" -version = "4.9.0" -description = "django-cors-headers is a Django application for handling the server headers required for Cross-Origin Resource Sharing (CORS)." -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "django_cors_headers-4.9.0-py3-none-any.whl", hash = "sha256:15c7f20727f90044dcee2216a9fd7303741a864865f0c3657e28b7056f61b449"}, - {file = "django_cors_headers-4.9.0.tar.gz", hash = "sha256:fe5d7cb59fdc2c8c646ce84b727ac2bca8912a247e6e68e1fb507372178e59e8"}, -] - -[package.dependencies] -asgiref = ">=3.6" -django = ">=4.2" - -[[package]] -name = "graphene" -version = "3.4.3" -description = "GraphQL Framework for Python" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "graphene-3.4.3-py2.py3-none-any.whl", hash = "sha256:820db6289754c181007a150db1f7fff544b94142b556d12e3ebc777a7bf36c71"}, - {file = "graphene-3.4.3.tar.gz", hash = "sha256:2a3786948ce75fe7e078443d37f609cbe5bb36ad8d6b828740ad3b95ed1a0aaa"}, -] - -[package.dependencies] -graphql-core = ">=3.1,<3.3" -graphql-relay = ">=3.1,<3.3" -python-dateutil = ">=2.7.0,<3" -typing-extensions = ">=4.7.1,<5" - -[package.extras] -dev = ["coveralls (>=3.3,<5)", "mypy (>=1.10,<2)", "pytest (>=8,<9)", "pytest-asyncio (>=0.16,<2)", "pytest-benchmark (>=4,<5)", "pytest-cov (>=5,<6)", "pytest-mock (>=3,<4)", "ruff (==0.5.0)", "types-python-dateutil (>=2.8.1,<3)"] -test = ["coveralls (>=3.3,<5)", "pytest (>=8,<9)", "pytest-asyncio (>=0.16,<2)", "pytest-benchmark (>=4,<5)", "pytest-cov (>=5,<6)", "pytest-mock (>=3,<4)"] - -[[package]] -name = "graphene-django" -version = "3.2.3" -description = "Graphene Django integration" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "graphene-django-3.2.3.tar.gz", hash = "sha256:d831bfe8e9a6e77e477b7854faef4addb318f386119a69ee4c57b74560f3e07d"}, - {file = "graphene_django-3.2.3-py2.py3-none-any.whl", hash = "sha256:0c673a4dad315b26b4d18eb379ad0c7027fd6a36d23a1848b7c7c09a14a9271e"}, -] - -[package.dependencies] -Django = ">=3.2" -graphene = ">=3.0,<4" -graphql-core = ">=3.1.0,<4" -graphql-relay = ">=3.1.1,<4" -promise = ">=2.1" -text-unidecode = "*" - -[package.extras] -dev = ["coveralls", "django-filter (>=22.1)", "djangorestframework (>=3.6.3)", "mock", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-django (>=4.5.2)", "pytest-random-order", "pytz", "ruff (==0.1.2)"] -rest-framework = ["djangorestframework (>=3.6.3)"] -test = ["coveralls", "django-filter (>=22.1)", "djangorestframework (>=3.6.3)", "mock", "pytest (>=7.3.1)", "pytest-cov", "pytest-django (>=4.5.2)", "pytest-random-order", "pytz"] - -[[package]] -name = "graphql-core" -version = "3.2.7" -description = "GraphQL implementation for Python, a port of GraphQL.js, the JavaScript reference implementation for GraphQL." -optional = false -python-versions = "<4,>=3.7" -groups = ["main"] -files = [ - {file = "graphql_core-3.2.7-py3-none-any.whl", hash = "sha256:17fc8f3ca4a42913d8e24d9ac9f08deddf0a0b2483076575757f6c412ead2ec0"}, - {file = "graphql_core-3.2.7.tar.gz", hash = "sha256:27b6904bdd3b43f2a0556dad5d579bdfdeab1f38e8e8788e555bdcb586a6f62c"}, -] - -[[package]] -name = "graphql-relay" -version = "3.2.0" -description = "Relay library for graphql-core" -optional = false -python-versions = ">=3.6,<4" -groups = ["main"] -files = [ - {file = "graphql-relay-3.2.0.tar.gz", hash = "sha256:1ff1c51298356e481a0be009ccdff249832ce53f30559c1338f22a0e0d17250c"}, - {file = "graphql_relay-3.2.0-py3-none-any.whl", hash = "sha256:c9b22bd28b170ba1fe674c74384a8ff30a76c8e26f88ac3aa1584dd3179953e5"}, -] - -[package.dependencies] -graphql-core = ">=3.2,<3.3" - -[[package]] -name = "gunicorn" -version = "23.0.0" -description = "WSGI HTTP Server for UNIX" -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d"}, - {file = "gunicorn-23.0.0.tar.gz", hash = "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec"}, -] - -[package.dependencies] -packaging = "*" - -[package.extras] -eventlet = ["eventlet (>=0.24.1,!=0.36.0)"] -gevent = ["gevent (>=1.4.0)"] -setproctitle = ["setproctitle"] -testing = ["coverage", "eventlet", "gevent", "pytest", "pytest-cov"] -tornado = ["tornado (>=0.2)"] - -[[package]] -name = "idna" -version = "3.11" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.8" -groups = ["main"] -files = [ - {file = "idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}, - {file = "idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "infisicalsdk" -version = "1.0.12" -description = "Official Infisical SDK for Python (Latest)" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "infisicalsdk-1.0.12-py3-none-any.whl", hash = "sha256:348af8f665fd81beac643db5a81f858eaf473e5809bdb7dfdcca923fe3ab49ea"}, - {file = "infisicalsdk-1.0.12.tar.gz", hash = "sha256:d376e3a649ff4733d1586488d58bf9305c2a60e9360a7d6c315a4639799aedd4"}, -] - -[package.dependencies] -aenum = "*" -boto3 = ">=1.35,<2.0" -botocore = ">=1.35,<2.0" -python-dateutil = "*" -requests = ">=2.32,<3.0" - -[[package]] -name = "jmespath" -version = "1.0.1" -description = "JSON Matching Expressions" -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, - {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, -] - -[[package]] -name = "nexus-rpc" -version = "1.2.0" -description = "Nexus Python SDK" -optional = false -python-versions = ">=3.10" -groups = ["main"] -files = [ - {file = "nexus_rpc-1.2.0-py3-none-any.whl", hash = "sha256:977876f3af811ad1a09b2961d3d1ac9233bda43ff0febbb0c9906483b9d9f8a3"}, - {file = "nexus_rpc-1.2.0.tar.gz", hash = "sha256:b4ddaffa4d3996aaeadf49b80dfcdfbca48fe4cb616defaf3b3c5c2c8fc61890"}, -] - -[package.dependencies] -typing-extensions = ">=4.12.2" - -[[package]] -name = "packaging" -version = "25.0" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -groups = ["main"] -files = [ - {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, - {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, -] - -[[package]] -name = "promise" -version = "2.3" -description = "Promises/A+ implementation for Python" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "promise-2.3.tar.gz", hash = "sha256:dfd18337c523ba4b6a58801c164c1904a9d4d1b1747c7d5dbf45b693a49d93d0"}, -] - -[package.dependencies] -six = "*" - -[package.extras] -test = ["coveralls", "futures", "mock", "pytest (>=2.7.3)", "pytest-benchmark", "pytest-cov"] - -[[package]] -name = "protobuf" -version = "6.33.1" -description = "" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "protobuf-6.33.1-cp310-abi3-win32.whl", hash = "sha256:f8d3fdbc966aaab1d05046d0240dd94d40f2a8c62856d41eaa141ff64a79de6b"}, - {file = "protobuf-6.33.1-cp310-abi3-win_amd64.whl", hash = "sha256:923aa6d27a92bf44394f6abf7ea0500f38769d4b07f4be41cb52bd8b1123b9ed"}, - {file = "protobuf-6.33.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:fe34575f2bdde76ac429ec7b570235bf0c788883e70aee90068e9981806f2490"}, - {file = "protobuf-6.33.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:f8adba2e44cde2d7618996b3fc02341f03f5bc3f2748be72dc7b063319276178"}, - {file = "protobuf-6.33.1-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:0f4cf01222c0d959c2b399142deb526de420be8236f22c71356e2a544e153c53"}, - {file = "protobuf-6.33.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:8fd7d5e0eb08cd5b87fd3df49bc193f5cfd778701f47e11d127d0afc6c39f1d1"}, - {file = "protobuf-6.33.1-cp39-cp39-win32.whl", hash = "sha256:023af8449482fa884d88b4563d85e83accab54138ae098924a985bcbb734a213"}, - {file = "protobuf-6.33.1-cp39-cp39-win_amd64.whl", hash = "sha256:df051de4fd7e5e4371334e234c62ba43763f15ab605579e04c7008c05735cd82"}, - {file = "protobuf-6.33.1-py3-none-any.whl", hash = "sha256:d595a9fd694fdeb061a62fbe10eb039cc1e444df81ec9bb70c7fc59ebcb1eafa"}, - {file = "protobuf-6.33.1.tar.gz", hash = "sha256:97f65757e8d09870de6fd973aeddb92f85435607235d20b2dfed93405d00c85b"}, -] - -[[package]] -name = "psycopg2-binary" -version = "2.9.11" -description = "psycopg2 - Python-PostgreSQL Database Adapter" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "psycopg2-binary-2.9.11.tar.gz", hash = "sha256:b6aed9e096bf63f9e75edf2581aa9a7e7186d97ab5c177aa6c87797cd591236c"}, - {file = "psycopg2_binary-2.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d6fe6b47d0b42ce1c9f1fa3e35bb365011ca22e39db37074458f27921dca40f2"}, - {file = "psycopg2_binary-2.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a6c0e4262e089516603a09474ee13eabf09cb65c332277e39af68f6233911087"}, - {file = "psycopg2_binary-2.9.11-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c47676e5b485393f069b4d7a811267d3168ce46f988fa602658b8bb901e9e64d"}, - {file = "psycopg2_binary-2.9.11-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:a28d8c01a7b27a1e3265b11250ba7557e5f72b5ee9e5f3a2fa8d2949c29bf5d2"}, - {file = "psycopg2_binary-2.9.11-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5f3f2732cf504a1aa9e9609d02f79bea1067d99edf844ab92c247bbca143303b"}, - {file = "psycopg2_binary-2.9.11-cp310-cp310-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:865f9945ed1b3950d968ec4690ce68c55019d79e4497366d36e090327ce7db14"}, - {file = "psycopg2_binary-2.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:91537a8df2bde69b1c1db01d6d944c831ca793952e4f57892600e96cee95f2cd"}, - {file = "psycopg2_binary-2.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4dca1f356a67ecb68c81a7bc7809f1569ad9e152ce7fd02c2f2036862ca9f66b"}, - {file = "psycopg2_binary-2.9.11-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:0da4de5c1ac69d94ed4364b6cbe7190c1a70d325f112ba783d83f8440285f152"}, - {file = "psycopg2_binary-2.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37d8412565a7267f7d79e29ab66876e55cb5e8e7b3bbf94f8206f6795f8f7e7e"}, - {file = "psycopg2_binary-2.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:c665f01ec8ab273a61c62beeb8cce3014c214429ced8a308ca1fc410ecac3a39"}, - {file = "psycopg2_binary-2.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0e8480afd62362d0a6a27dd09e4ca2def6fa50ed3a4e7c09165266106b2ffa10"}, - {file = "psycopg2_binary-2.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:763c93ef1df3da6d1a90f86ea7f3f806dc06b21c198fa87c3c25504abec9404a"}, - {file = "psycopg2_binary-2.9.11-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2e164359396576a3cc701ba8af4751ae68a07235d7a380c631184a611220d9a4"}, - {file = "psycopg2_binary-2.9.11-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:d57c9c387660b8893093459738b6abddbb30a7eab058b77b0d0d1c7d521ddfd7"}, - {file = "psycopg2_binary-2.9.11-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2c226ef95eb2250974bf6fa7a842082b31f68385c4f3268370e3f3870e7859ee"}, - {file = "psycopg2_binary-2.9.11-cp311-cp311-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a311f1edc9967723d3511ea7d2708e2c3592e3405677bf53d5c7246753591fbb"}, - {file = "psycopg2_binary-2.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ebb415404821b6d1c47353ebe9c8645967a5235e6d88f914147e7fd411419e6f"}, - {file = "psycopg2_binary-2.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f07c9c4a5093258a03b28fab9b4f151aa376989e7f35f855088234e656ee6a94"}, - {file = "psycopg2_binary-2.9.11-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:00ce1830d971f43b667abe4a56e42c1e2d594b32da4802e44a73bacacb25535f"}, - {file = "psycopg2_binary-2.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cffe9d7697ae7456649617e8bb8d7a45afb71cd13f7ab22af3e5c61f04840908"}, - {file = "psycopg2_binary-2.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:304fd7b7f97eef30e91b8f7e720b3db75fee010b520e434ea35ed1ff22501d03"}, - {file = "psycopg2_binary-2.9.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:be9b840ac0525a283a96b556616f5b4820e0526addb8dcf6525a0fa162730be4"}, - {file = "psycopg2_binary-2.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f090b7ddd13ca842ebfe301cd587a76a4cf0913b1e429eb92c1be5dbeb1a19bc"}, - {file = "psycopg2_binary-2.9.11-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ab8905b5dcb05bf3fb22e0cf90e10f469563486ffb6a96569e51f897c750a76a"}, - {file = "psycopg2_binary-2.9.11-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:bf940cd7e7fec19181fdbc29d76911741153d51cab52e5c21165f3262125685e"}, - {file = "psycopg2_binary-2.9.11-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fa0f693d3c68ae925966f0b14b8edda71696608039f4ed61b1fe9ffa468d16db"}, - {file = "psycopg2_binary-2.9.11-cp312-cp312-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a1cf393f1cdaf6a9b57c0a719a1068ba1069f022a59b8b1fe44b006745b59757"}, - {file = "psycopg2_binary-2.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ef7a6beb4beaa62f88592ccc65df20328029d721db309cb3250b0aae0fa146c3"}, - {file = "psycopg2_binary-2.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:31b32c457a6025e74d233957cc9736742ac5a6cb196c6b68499f6bb51390bd6a"}, - {file = "psycopg2_binary-2.9.11-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:edcb3aeb11cb4bf13a2af3c53a15b3d612edeb6409047ea0b5d6a21a9d744b34"}, - {file = "psycopg2_binary-2.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:62b6d93d7c0b61a1dd6197d208ab613eb7dcfdcca0a49c42ceb082257991de9d"}, - {file = "psycopg2_binary-2.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:b33fabeb1fde21180479b2d4667e994de7bbf0eec22832ba5d9b5e4cf65b6c6d"}, - {file = "psycopg2_binary-2.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b8fb3db325435d34235b044b199e56cdf9ff41223a4b9752e8576465170bb38c"}, - {file = "psycopg2_binary-2.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:366df99e710a2acd90efed3764bb1e28df6c675d33a7fb40df9b7281694432ee"}, - {file = "psycopg2_binary-2.9.11-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8c55b385daa2f92cb64b12ec4536c66954ac53654c7f15a203578da4e78105c0"}, - {file = "psycopg2_binary-2.9.11-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c0377174bf1dd416993d16edc15357f6eb17ac998244cca19bc67cdc0e2e5766"}, - {file = "psycopg2_binary-2.9.11-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5c6ff3335ce08c75afaed19e08699e8aacf95d4a260b495a4a8545244fe2ceb3"}, - {file = "psycopg2_binary-2.9.11-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:84011ba3109e06ac412f95399b704d3d6950e386b7994475b231cf61eec2fc1f"}, - {file = "psycopg2_binary-2.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ba34475ceb08cccbdd98f6b46916917ae6eeb92b5ae111df10b544c3a4621dc4"}, - {file = "psycopg2_binary-2.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b31e90fdd0f968c2de3b26ab014314fe814225b6c324f770952f7d38abf17e3c"}, - {file = "psycopg2_binary-2.9.11-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:d526864e0f67f74937a8fce859bd56c979f5e2ec57ca7c627f5f1071ef7fee60"}, - {file = "psycopg2_binary-2.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04195548662fa544626c8ea0f06561eb6203f1984ba5b4562764fbeb4c3d14b1"}, - {file = "psycopg2_binary-2.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:efff12b432179443f54e230fdf60de1f6cc726b6c832db8701227d089310e8aa"}, - {file = "psycopg2_binary-2.9.11-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:92e3b669236327083a2e33ccfa0d320dd01b9803b3e14dd986a4fc54aa00f4e1"}, - {file = "psycopg2_binary-2.9.11-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e0deeb03da539fa3577fcb0b3f2554a97f7e5477c246098dbb18091a4a01c16f"}, - {file = "psycopg2_binary-2.9.11-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9b52a3f9bb540a3e4ec0f6ba6d31339727b2950c9772850d6545b7eae0b9d7c5"}, - {file = "psycopg2_binary-2.9.11-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:db4fd476874ccfdbb630a54426964959e58da4c61c9feba73e6094d51303d7d8"}, - {file = "psycopg2_binary-2.9.11-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:47f212c1d3be608a12937cc131bd85502954398aaa1320cb4c14421a0ffccf4c"}, - {file = "psycopg2_binary-2.9.11-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e35b7abae2b0adab776add56111df1735ccc71406e56203515e228a8dc07089f"}, - {file = "psycopg2_binary-2.9.11-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fcf21be3ce5f5659daefd2b3b3b6e4727b028221ddc94e6c1523425579664747"}, - {file = "psycopg2_binary-2.9.11-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:9bd81e64e8de111237737b29d68039b9c813bdf520156af36d26819c9a979e5f"}, - {file = "psycopg2_binary-2.9.11-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:32770a4d666fbdafab017086655bcddab791d7cb260a16679cc5a7338b64343b"}, - {file = "psycopg2_binary-2.9.11-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c3cb3a676873d7506825221045bd70e0427c905b9c8ee8d6acd70cfcbd6e576d"}, - {file = "psycopg2_binary-2.9.11-cp314-cp314-win_amd64.whl", hash = "sha256:4012c9c954dfaccd28f94e84ab9f94e12df76b4afb22331b1f0d3154893a6316"}, - {file = "psycopg2_binary-2.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:20e7fb94e20b03dcc783f76c0865f9da39559dcc0c28dd1a3fce0d01902a6b9c"}, - {file = "psycopg2_binary-2.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4bdab48575b6f870f465b397c38f1b415520e9879fdf10a53ee4f49dcbdf8a21"}, - {file = "psycopg2_binary-2.9.11-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9d3a9edcfbe77a3ed4bc72836d466dfce4174beb79eda79ea155cc77237ed9e8"}, - {file = "psycopg2_binary-2.9.11-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:44fc5c2b8fa871ce7f0023f619f1349a0aa03a0857f2c96fbc01c657dcbbdb49"}, - {file = "psycopg2_binary-2.9.11-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9c55460033867b4622cda1b6872edf445809535144152e5d14941ef591980edf"}, - {file = "psycopg2_binary-2.9.11-cp39-cp39-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:2d11098a83cca92deaeaed3d58cfd150d49b3b06ee0d0852be466bf87596899e"}, - {file = "psycopg2_binary-2.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:691c807d94aecfbc76a14e1408847d59ff5b5906a04a23e12a89007672b9e819"}, - {file = "psycopg2_binary-2.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:8b81627b691f29c4c30a8f322546ad039c40c328373b11dff7490a3e1b517855"}, - {file = "psycopg2_binary-2.9.11-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:b637d6d941209e8d96a072d7977238eea128046effbf37d1d8b2c0764750017d"}, - {file = "psycopg2_binary-2.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:41360b01c140c2a03d346cec3280cf8a71aa07d94f3b1509fa0161c366af66b4"}, - {file = "psycopg2_binary-2.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:875039274f8a2361e5207857899706da840768e2a775bf8c65e82f60b197df02"}, -] - -[[package]] -name = "pycparser" -version = "2.23" -description = "C parser in Python" -optional = false -python-versions = ">=3.8" -groups = ["main"] -markers = "platform_python_implementation != \"PyPy\" and implementation_name != \"PyPy\"" -files = [ - {file = "pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934"}, - {file = "pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2"}, -] - -[[package]] -name = "pyjwt" -version = "2.10.1" -description = "JSON Web Token implementation in Python" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, - {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, -] - -[package.extras] -crypto = ["cryptography (>=3.4.0)"] -dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] -docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] -tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main"] -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "python-dotenv" -version = "1.2.1" -description = "Read key-value pairs from a .env file and set them as environment variables" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61"}, - {file = "python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6"}, -] - -[package.extras] -cli = ["click (>=5.0)"] - -[[package]] -name = "requests" -version = "2.32.5" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6"}, - {file = "requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset_normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "s3transfer" -version = "0.15.0" -description = "An Amazon S3 Transfer Manager" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "s3transfer-0.15.0-py3-none-any.whl", hash = "sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852"}, - {file = "s3transfer-0.15.0.tar.gz", hash = "sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379"}, -] - -[package.dependencies] -botocore = ">=1.37.4,<2.0a.0" - -[package.extras] -crt = ["botocore[crt] (>=1.37.4,<2.0a.0)"] - -[[package]] -name = "sentry-sdk" -version = "2.47.0" -description = "Python client for Sentry (https://sentry.io)" -optional = false -python-versions = ">=3.6" -groups = ["main"] -files = [ - {file = "sentry_sdk-2.47.0-py2.py3-none-any.whl", hash = "sha256:d72f8c61025b7d1d9e52510d03a6247b280094a327dd900d987717a4fce93412"}, - {file = "sentry_sdk-2.47.0.tar.gz", hash = "sha256:8218891d5e41b4ea8d61d2aed62ed10c80e39d9f2959d6f939efbf056857e050"}, -] - -[package.dependencies] -certifi = "*" -urllib3 = ">=1.26.11" - -[package.extras] -aiohttp = ["aiohttp (>=3.5)"] -anthropic = ["anthropic (>=0.16)"] -arq = ["arq (>=0.23)"] -asyncpg = ["asyncpg (>=0.23)"] -beam = ["apache-beam (>=2.12)"] -bottle = ["bottle (>=0.12.13)"] -celery = ["celery (>=3)"] -celery-redbeat = ["celery-redbeat (>=2)"] -chalice = ["chalice (>=1.16.0)"] -clickhouse-driver = ["clickhouse-driver (>=0.2.0)"] -django = ["django (>=1.8)"] -falcon = ["falcon (>=1.4)"] -fastapi = ["fastapi (>=0.79.0)"] -flask = ["blinker (>=1.1)", "flask (>=0.11)", "markupsafe"] -google-genai = ["google-genai (>=1.29.0)"] -grpcio = ["grpcio (>=1.21.1)", "protobuf (>=3.8.0)"] -http2 = ["httpcore[http2] (==1.*)"] -httpx = ["httpx (>=0.16.0)"] -huey = ["huey (>=2)"] -huggingface-hub = ["huggingface_hub (>=0.22)"] -langchain = ["langchain (>=0.0.210)"] -langgraph = ["langgraph (>=0.6.6)"] -launchdarkly = ["launchdarkly-server-sdk (>=9.8.0)"] -litellm = ["litellm (>=1.77.5)"] -litestar = ["litestar (>=2.0.0)"] -loguru = ["loguru (>=0.5)"] -mcp = ["mcp (>=1.15.0)"] -openai = ["openai (>=1.0.0)", "tiktoken (>=0.3.0)"] -openfeature = ["openfeature-sdk (>=0.7.1)"] -opentelemetry = ["opentelemetry-distro (>=0.35b0)"] -opentelemetry-experimental = ["opentelemetry-distro"] -opentelemetry-otlp = ["opentelemetry-distro[otlp] (>=0.35b0)"] -pure-eval = ["asttokens", "executing", "pure_eval"] -pydantic-ai = ["pydantic-ai (>=1.0.0)"] -pymongo = ["pymongo (>=3.1)"] -pyspark = ["pyspark (>=2.4.4)"] -quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] -rq = ["rq (>=0.6)"] -sanic = ["sanic (>=0.8)"] -sqlalchemy = ["sqlalchemy (>=1.2)"] -starlette = ["starlette (>=0.19.1)"] -starlite = ["starlite (>=1.48)"] -statsig = ["statsig (>=0.55.3)"] -tornado = ["tornado (>=6)"] -unleash = ["UnleashClient (>=6.0.1)"] - -[[package]] -name = "six" -version = "1.17.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main"] -files = [ - {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, - {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, -] - -[[package]] -name = "sqlparse" -version = "0.5.3" -description = "A non-validating SQL parser." -optional = false -python-versions = ">=3.8" -groups = ["main"] -files = [ - {file = "sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca"}, - {file = "sqlparse-0.5.3.tar.gz", hash = "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272"}, -] - -[package.extras] -dev = ["build", "hatch"] -doc = ["sphinx"] - -[[package]] -name = "temporalio" -version = "1.20.0" -description = "Temporal.io Python SDK" -optional = false -python-versions = ">=3.10" -groups = ["main"] -files = [ - {file = "temporalio-1.20.0-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:fba70314b4068f8b1994bddfa0e2ad742483f0ae714d2ef52e63013ccfd7042e"}, - {file = "temporalio-1.20.0-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffc5bb6cabc6ae67f0bfba44de6a9c121603134ae18784a2ff3a7f230ad99080"}, - {file = "temporalio-1.20.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1e80c1e4cdf88fa8277177f563edc91466fe4dc13c0322f26e55c76b6a219e6"}, - {file = "temporalio-1.20.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba92d909188930860c9d89ca6d7a753bc5a67e4e9eac6cea351477c967355eed"}, - {file = "temporalio-1.20.0-cp310-abi3-win_amd64.whl", hash = "sha256:eacfd571b653e0a0f4aa6593f4d06fc628797898f0900d400e833a1f40cad03a"}, - {file = "temporalio-1.20.0.tar.gz", hash = "sha256:5a6a85b7d298b7359bffa30025f7deac83c74ac095a4c6952fbf06c249a2a67c"}, -] - -[package.dependencies] -nexus-rpc = "1.2.0" -protobuf = ">=3.20,<7.0.0" -types-protobuf = ">=3.20" -typing-extensions = ">=4.2.0,<5" - -[package.extras] -grpc = ["grpcio (>=1.48.2,<2)"] -openai-agents = ["mcp (>=1.9.4,<2)", "openai-agents (>=0.3,<0.5)"] -opentelemetry = ["opentelemetry-api (>=1.11.1,<2)", "opentelemetry-sdk (>=1.11.1,<2)"] -pydantic = ["pydantic (>=2.0.0,<3)"] - -[[package]] -name = "text-unidecode" -version = "1.3" -description = "The most basic Text::Unidecode port" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, - {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, -] - -[[package]] -name = "types-protobuf" -version = "6.32.1.20251105" -description = "Typing stubs for protobuf" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "types_protobuf-6.32.1.20251105-py3-none-any.whl", hash = "sha256:a15109d38f7cfefd2539ef86d3f93a6a41c7cad53924f8aa1a51eaddbb72a660"}, - {file = "types_protobuf-6.32.1.20251105.tar.gz", hash = "sha256:641002611ff87dd9fedc38a39a29cacb9907ae5ce61489b53e99ca2074bef764"}, -] - -[[package]] -name = "typing-extensions" -version = "4.15.0" -description = "Backported and Experimental Type Hints for Python 3.9+" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, - {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, -] - -[[package]] -name = "tzdata" -version = "2025.2" -description = "Provider of IANA time zone data" -optional = false -python-versions = ">=2" -groups = ["main"] -markers = "sys_platform == \"win32\"" -files = [ - {file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"}, - {file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"}, -] - -[[package]] -name = "urllib3" -version = "2.5.0" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, - {file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "whitenoise" -version = "6.11.0" -description = "Radically simplified static file serving for WSGI applications" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "whitenoise-6.11.0-py3-none-any.whl", hash = "sha256:b2aeb45950597236f53b5342b3121c5de69c8da0109362aee506ce88e022d258"}, - {file = "whitenoise-6.11.0.tar.gz", hash = "sha256:0f5bfce6061ae6611cd9396a8231e088722e4fc67bc13a111be74c738d99375f"}, -] - -[package.extras] -brotli = ["brotli"] - -[metadata] -lock-version = "2.1" -python-versions = "^3.11" -content-hash = "33bcae3d5a20ac5a5cbabf6a11f0b74a9cfa86ef799f7df5ead9052178fefb07" diff --git a/prisma/schema.prisma b/prisma/schema.prisma new file mode 100644 index 0000000..360b9e0 --- /dev/null +++ b/prisma/schema.prisma @@ -0,0 +1,132 @@ +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "postgresql" + url = env("TEAMS_DATABASE_URL") +} + +model Team { + id Int @id @default(autoincrement()) + uuid String @unique @default(uuid()) + name String @db.VarChar(200) + teamType String @default("BUYER") @map("team_type") @db.VarChar(20) + logtoOrgId String? @map("logto_org_id") @db.VarChar(100) + ownerId Int? @map("owner_id") + owner User? @relation(fields: [ownerId], references: [id]) + selectedLocationType String? @map("selected_location_type") @db.VarChar(20) + selectedLocationUuid String? @map("selected_location_uuid") @db.VarChar(100) + selectedLocationName String? @map("selected_location_name") @db.VarChar(255) + selectedLocationLat Float? @map("selected_location_lat") + selectedLocationLon Float? @map("selected_location_lon") + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + + members TeamMember[] + invitations TeamInvitation[] + addresses TeamAddress[] + profiles UserProfile[] @relation("ActiveTeam") + + @@map("teams_app_team") +} + +model User { + id Int @id @default(autoincrement()) + password String @default("") @db.VarChar(128) + username String @unique @db.VarChar(150) + firstName String @default("") @map("first_name") @db.VarChar(150) + lastName String @default("") @map("last_name") @db.VarChar(150) + email String @default("") @db.VarChar(254) + isActive Boolean @default(true) @map("is_active") + dateJoined DateTime @default(now()) @map("date_joined") + isSuperuser Boolean @default(false) @map("is_superuser") + isStaff Boolean @default(false) @map("is_staff") + lastLogin DateTime? @map("last_login") + + profile UserProfile? + teams Team[] + memberships TeamMember[] + + @@map("auth_user") +} + +model UserProfile { + id Int @id @default(autoincrement()) + userId Int @unique @map("user_id") + user User @relation(fields: [userId], references: [id]) + logtoId String @unique @map("logto_id") @db.VarChar(255) + avatarId String? @map("avatar_id") @db.VarChar(255) + phone String @default("") @db.VarChar(50) + activeTeamId Int? @map("active_team_id") + activeTeam Team? @relation("ActiveTeam", fields: [activeTeamId], references: [id]) + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + + @@map("teams_app_userprofile") +} + +model TeamMember { + id Int @id @default(autoincrement()) + uuid String @unique @default(uuid()) + teamId Int @map("team_id") + team Team @relation(fields: [teamId], references: [id]) + userId Int? @map("user_id") + user User? @relation(fields: [userId], references: [id]) + role String @default("MEMBER") @db.VarChar(20) + joinedAt DateTime @default(now()) @map("joined_at") + + @@unique([teamId, userId]) + @@map("teams_app_teammember") +} + +model TeamInvitation { + id Int @id @default(autoincrement()) + uuid String @unique @default(uuid()) + teamId Int @map("team_id") + team Team @relation(fields: [teamId], references: [id]) + email String @db.VarChar(254) + role String @default("MEMBER") @db.VarChar(20) + status String @default("PENDING") @db.VarChar(20) + invitedBy String @default("") @map("invited_by") @db.VarChar(255) + expiresAt DateTime? @map("expires_at") + createdAt DateTime @default(now()) @map("created_at") + + tokens TeamInvitationToken[] + + @@unique([teamId, email]) + @@map("teams_app_teaminvitation") +} + +model TeamInvitationToken { + id Int @id @default(autoincrement()) + uuid String @unique @default(uuid()) + invitationId Int @map("invitation_id") + invitation TeamInvitation @relation(fields: [invitationId], references: [id]) + tokenHash String @unique @map("token_hash") @db.VarChar(255) + workflowStatus String @default("pending") @map("workflow_status") @db.VarChar(20) + expiresAt DateTime? @map("expires_at") + createdAt DateTime @default(now()) @map("created_at") + + @@map("teams_app_teaminvitationtoken") +} + +model TeamAddress { + id Int @id @default(autoincrement()) + uuid String @unique @default(uuid()) + teamId Int @map("team_id") + team Team @relation(fields: [teamId], references: [id]) + name String @db.VarChar(255) + address String + latitude Float? + longitude Float? + countryCode String @default("") @map("country_code") @db.VarChar(10) + isDefault Boolean @default(false) @map("is_default") + status String @default("pending") @db.VarChar(20) + processedAt DateTime? @map("processed_at") + errorMessage String? @map("error_message") + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + + @@map("teams_app_teamaddress") +} diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index d812da7..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,28 +0,0 @@ -[project] -name = "teams" -version = "0.1.0" -description = "" -authors = [ - {name = "Ruslan Bakiev",email = "572431+veikab@users.noreply.github.com"} -] -readme = "README.md" -requires-python = "^3.11" -dependencies = [ - "django (>=5.2.8,<6.0)", - "graphene-django (>=3.2.3,<4.0.0)", - "django-cors-headers (>=4.9.0,<5.0.0)", - "psycopg2-binary (>=2.9.11,<3.0.0)", - "requests (>=2.32.5,<3.0.0)", - "temporalio (>=1.4.0,<2.0.0)", - "python-dotenv (>=1.2.1,<2.0.0)", - "pyjwt (>=2.10.1,<3.0.0)", - "cryptography (>=46.0.3,<47.0.0)", - "infisicalsdk (>=1.0.12,<2.0.0)", - "gunicorn (>=23.0.0,<24.0.0)", - "whitenoise (>=6.7.0,<7.0.0)", - "sentry-sdk (>=2.47.0,<3.0.0)" -] - -[build-system] -requires = ["poetry-core>=2.0.0,<3.0.0"] -build-backend = "poetry.core.masonry.api" diff --git a/src/auth.ts b/src/auth.ts new file mode 100644 index 0000000..22b9eab --- /dev/null +++ b/src/auth.ts @@ -0,0 +1,55 @@ +import { createRemoteJWKSet, jwtVerify, type JWTPayload } from 'jose' +import { GraphQLError } from 'graphql' +import type { Request } from 'express' + +const LOGTO_JWKS_URL = process.env.LOGTO_JWKS_URL || 'https://auth.optovia.ru/oidc/jwks' +const LOGTO_ISSUER = process.env.LOGTO_ISSUER || 'https://auth.optovia.ru/oidc' +const LOGTO_TEAMS_AUDIENCE = process.env.LOGTO_TEAMS_AUDIENCE || 'https://teams.optovia.ru' + +const jwks = createRemoteJWKSet(new URL(LOGTO_JWKS_URL)) + +export interface AuthContext { + userId?: string + teamUuid?: string + scopes: string[] + isM2M?: boolean +} + +function getBearerToken(req: Request): string { + const auth = req.headers.authorization || '' + if (!auth.startsWith('Bearer ')) throw new GraphQLError('Missing Bearer token', { extensions: { code: 'UNAUTHENTICATED' } }) + const token = auth.slice(7) + if (!token || token === 'undefined') throw new GraphQLError('Empty Bearer token', { extensions: { code: 'UNAUTHENTICATED' } }) + return token +} + +function scopesFromPayload(payload: JWTPayload): string[] { + const scope = payload.scope + if (!scope) return [] + if (typeof scope === 'string') return scope.split(' ') + return [] +} + +export async function publicContext(): Promise { return { scopes: [] } } + +export async function userContext(req: Request): Promise { + const token = getBearerToken(req) + const { payload } = await jwtVerify(token, jwks, { issuer: LOGTO_ISSUER }) + return { userId: payload.sub, scopes: [] } +} + +export async function teamContext(req: Request): Promise { + const token = getBearerToken(req) + const { payload } = await jwtVerify(token, jwks, { issuer: LOGTO_ISSUER, audience: LOGTO_TEAMS_AUDIENCE }) + const teamUuid = (payload as Record).team_uuid as string | undefined + const scopes = scopesFromPayload(payload) + if (!teamUuid || !scopes.includes('teams:member')) throw new GraphQLError('Unauthorized', { extensions: { code: 'UNAUTHENTICATED' } }) + return { userId: payload.sub, teamUuid, scopes } +} + +export async function m2mContext(): Promise { return { scopes: [], isM2M: true } } + +export function requireScopes(ctx: AuthContext, ...required: string[]): void { + const missing = required.filter(s => !ctx.scopes.includes(s)) + if (missing.length > 0) throw new GraphQLError(`Missing required scopes: ${missing.join(', ')}`, { extensions: { code: 'FORBIDDEN' } }) +} diff --git a/src/db.ts b/src/db.ts new file mode 100644 index 0000000..6260dd0 --- /dev/null +++ b/src/db.ts @@ -0,0 +1,3 @@ +import { PrismaClient } from '@prisma/client' + +export const prisma = new PrismaClient() diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..6e89bc4 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,47 @@ +import express from 'express' +import cors from 'cors' +import { ApolloServer } from '@apollo/server' +import { expressMiddleware } from '@apollo/server/express4' +import * as Sentry from '@sentry/node' +import { publicTypeDefs, publicResolvers } from './schemas/public.js' +import { userTypeDefs, userResolvers } from './schemas/user.js' +import { teamTypeDefs, teamResolvers } from './schemas/team.js' +import { m2mTypeDefs, m2mResolvers } from './schemas/m2m.js' +import { publicContext, userContext, teamContext, m2mContext, type AuthContext } from './auth.js' + +const PORT = parseInt(process.env.PORT || '8000', 10) +const SENTRY_DSN = process.env.SENTRY_DSN || '' + +if (SENTRY_DSN) { + Sentry.init({ + dsn: SENTRY_DSN, + tracesSampleRate: 0.01, + release: process.env.RELEASE_VERSION || '1.0.0', + environment: process.env.ENVIRONMENT || 'production', + }) +} + +const app = express() +app.use(cors({ origin: ['https://optovia.ru'], credentials: true })) + +const publicServer = new ApolloServer({ typeDefs: publicTypeDefs, resolvers: publicResolvers, introspection: true }) +const userServer = new ApolloServer({ typeDefs: userTypeDefs, resolvers: userResolvers, introspection: true }) +const teamServer = new ApolloServer({ typeDefs: teamTypeDefs, resolvers: teamResolvers, introspection: true }) +const m2mServer = new ApolloServer({ typeDefs: m2mTypeDefs, resolvers: m2mResolvers, introspection: true }) + +await Promise.all([publicServer.start(), userServer.start(), teamServer.start(), m2mServer.start()]) + +app.use('/graphql/public', express.json(), expressMiddleware(publicServer, { context: async () => publicContext() }) as unknown as express.RequestHandler) +app.use('/graphql/user', express.json(), expressMiddleware(userServer, { context: async ({ req }) => userContext(req as unknown as import('express').Request) }) as unknown as express.RequestHandler) +app.use('/graphql/team', express.json(), expressMiddleware(teamServer, { context: async ({ req }) => teamContext(req as unknown as import('express').Request) }) as unknown as express.RequestHandler) +app.use('/graphql/m2m', express.json(), expressMiddleware(m2mServer, { context: async () => m2mContext() }) as unknown as express.RequestHandler) + +app.get('/health', (_, res) => { res.json({ status: 'ok' }) }) + +app.listen(PORT, '0.0.0.0', () => { + console.log(`Teams server ready on port ${PORT}`) + console.log(` /graphql/public - public`) + console.log(` /graphql/user - id token auth`) + console.log(` /graphql/team - team access token auth`) + console.log(` /graphql/m2m - internal services (no auth)`) +}) diff --git a/src/schemas/m2m.ts b/src/schemas/m2m.ts new file mode 100644 index 0000000..4afe378 --- /dev/null +++ b/src/schemas/m2m.ts @@ -0,0 +1,149 @@ +import { prisma } from '../db.js' + +export const m2mTypeDefs = `#graphql + type Team { + uuid: String! + name: String! + logtoOrgId: String + createdAt: String + updatedAt: String + } + + type TeamInvitation { + uuid: String! + email: String! + role: String! + status: String! + invitedBy: String + expiresAt: String + createdAt: String + } + + type TeamInvitationToken { + uuid: String! + workflowStatus: String! + expiresAt: String + createdAt: String + } + + input CreateInvitationFromWorkflowInput { + teamUuid: String! + email: String! + role: String + invitedBy: String + expiresAt: String + } + + input CreateInvitationTokenInput { + invitationUuid: String! + tokenHash: String! + expiresAt: String + } + + input UpdateInvitationTokenStatusInput { + tokenUuid: String! + status: String! + } + + type SetLogtoOrgIdResult { team: Team, success: Boolean! } + type CreateTeamResult { success: Boolean!, teamId: String, teamUuid: String, message: String } + type CreateAddressResult { success: Boolean!, addressUuid: String, teamType: String, message: String } + type UpdateAddressStatusResult { success: Boolean! } + type CreateInvitationResult { success: Boolean!, message: String, invitationUuid: String, invitation: TeamInvitation } + type CreateTokenResult { success: Boolean! } + type UpdateTokenStatusResult { success: Boolean! } + + type Query { + team(teamId: String!): Team + invitation(invitationUuid: String!): TeamInvitation + } + + type Mutation { + setLogtoOrgId(teamId: String!, logtoOrgId: String!): SetLogtoOrgIdResult + createTeamFromWorkflow(teamName: String!, ownerId: String!, teamType: String, countryCode: String): CreateTeamResult + createAddressFromWorkflow(workflowId: String!, teamUuid: String!, name: String!, address: String!, latitude: Float, longitude: Float, countryCode: String, isDefault: Boolean): CreateAddressResult + updateAddressStatus(addressUuid: String!, status: String!, errorMessage: String): UpdateAddressStatusResult + createInvitationFromWorkflow(input: CreateInvitationFromWorkflowInput!): CreateInvitationResult + createInvitationToken(input: CreateInvitationTokenInput!): CreateTokenResult + updateInvitationTokenStatus(input: UpdateInvitationTokenStatusInput!): UpdateTokenStatusResult + } +` + +export const m2mResolvers = { + Query: { + team: async (_: unknown, args: { teamId: string }) => { + const team = await prisma.team.findUnique({ where: { uuid: args.teamId } }) + if (!team) return null + return { uuid: team.uuid, name: team.name, logtoOrgId: team.logtoOrgId, createdAt: team.createdAt.toISOString(), updatedAt: team.updatedAt.toISOString() } + }, + + invitation: async (_: unknown, args: { invitationUuid: string }) => { + const inv = await prisma.teamInvitation.findUnique({ where: { uuid: args.invitationUuid } }) + if (!inv) return null + return { uuid: inv.uuid, email: inv.email, role: inv.role, status: inv.status, invitedBy: inv.invitedBy, expiresAt: inv.expiresAt?.toISOString() ?? null, createdAt: inv.createdAt.toISOString() } + }, + }, + + Mutation: { + setLogtoOrgId: async (_: unknown, args: { teamId: string; logtoOrgId: string }) => { + const team = await prisma.team.update({ where: { uuid: args.teamId }, data: { logtoOrgId: args.logtoOrgId } }) + return { team: { uuid: team.uuid, name: team.name, logtoOrgId: team.logtoOrgId, createdAt: team.createdAt.toISOString(), updatedAt: team.updatedAt.toISOString() }, success: true } + }, + + createTeamFromWorkflow: async (_: unknown, args: { teamName: string; ownerId: string; teamType?: string; countryCode?: string }) => { + try { + let profile = await prisma.userProfile.findUnique({ where: { logtoId: args.ownerId }, include: { user: true } }) + if (!profile) { + const user = await prisma.user.create({ data: { username: args.ownerId } }) + profile = await prisma.userProfile.create({ data: { userId: user.id, logtoId: args.ownerId }, include: { user: true } }) + } + const team = await prisma.team.create({ data: { name: args.teamName, teamType: args.teamType || 'BUYER', ownerId: profile.userId } }) + await prisma.teamMember.create({ data: { teamId: team.id, userId: profile.userId, role: 'OWNER' } }) + await prisma.userProfile.update({ where: { id: profile.id }, data: { activeTeamId: team.id } }) + return { success: true, teamId: team.id.toString(), teamUuid: team.uuid, message: 'Team created' } + } catch (e) { + return { success: false, teamId: null, teamUuid: null, message: String(e) } + } + }, + + createAddressFromWorkflow: async (_: unknown, args: { workflowId: string; teamUuid: string; name: string; address: string; latitude?: number; longitude?: number; countryCode?: string; isDefault?: boolean }) => { + const team = await prisma.team.findUnique({ where: { uuid: args.teamUuid } }) + if (!team) return { success: false, addressUuid: null, teamType: null, message: 'Team not found' } + const addr = await prisma.teamAddress.create({ + data: { teamId: team.id, name: args.name, address: args.address, latitude: args.latitude, longitude: args.longitude, countryCode: args.countryCode || '', isDefault: args.isDefault || false }, + }) + return { success: true, addressUuid: addr.uuid, teamType: team.teamType, message: 'Address created' } + }, + + updateAddressStatus: async (_: unknown, args: { addressUuid: string; status: string; errorMessage?: string }) => { + await prisma.teamAddress.update({ + where: { uuid: args.addressUuid }, + data: { status: args.status, errorMessage: args.errorMessage || null, processedAt: new Date() }, + }) + return { success: true } + }, + + createInvitationFromWorkflow: async (_: unknown, args: { input: { teamUuid: string; email: string; role?: string; invitedBy?: string; expiresAt?: string } }) => { + const team = await prisma.team.findUnique({ where: { uuid: args.input.teamUuid } }) + if (!team) return { success: false, message: 'Team not found', invitationUuid: null, invitation: null } + const inv = await prisma.teamInvitation.create({ + data: { teamId: team.id, email: args.input.email, role: args.input.role || 'MEMBER', invitedBy: args.input.invitedBy || '', expiresAt: args.input.expiresAt ? new Date(args.input.expiresAt) : null }, + }) + return { success: true, message: 'Invitation created', invitationUuid: inv.uuid, invitation: { uuid: inv.uuid, email: inv.email, role: inv.role, status: inv.status, invitedBy: inv.invitedBy, expiresAt: inv.expiresAt?.toISOString() ?? null, createdAt: inv.createdAt.toISOString() } } + }, + + createInvitationToken: async (_: unknown, args: { input: { invitationUuid: string; tokenHash: string; expiresAt?: string } }) => { + const inv = await prisma.teamInvitation.findUnique({ where: { uuid: args.input.invitationUuid } }) + if (!inv) return { success: false } + await prisma.teamInvitationToken.create({ + data: { invitationId: inv.id, tokenHash: args.input.tokenHash, expiresAt: args.input.expiresAt ? new Date(args.input.expiresAt) : null }, + }) + return { success: true } + }, + + updateInvitationTokenStatus: async (_: unknown, args: { input: { tokenUuid: string; status: string } }) => { + await prisma.teamInvitationToken.update({ where: { uuid: args.input.tokenUuid }, data: { workflowStatus: args.input.status } }) + return { success: true } + }, + }, +} diff --git a/src/schemas/public.ts b/src/schemas/public.ts new file mode 100644 index 0000000..531bf55 --- /dev/null +++ b/src/schemas/public.ts @@ -0,0 +1,4 @@ +export const publicTypeDefs = `#graphql + type Query { health: String! } +` +export const publicResolvers = { Query: { health: () => 'ok' } } diff --git a/src/schemas/team.ts b/src/schemas/team.ts new file mode 100644 index 0000000..6dcc22c --- /dev/null +++ b/src/schemas/team.ts @@ -0,0 +1,286 @@ +import { GraphQLError } from 'graphql' +import { prisma } from '../db.js' +import { requireScopes, type AuthContext } from '../auth.js' +import { startAddressWorkflow, startInviteWorkflow } from '../services/temporal.js' + +export const teamTypeDefs = `#graphql + type TeamUser { + id: String + firstName: String + lastName: String + phone: String + avatarId: String + createdAt: String + } + + type TeamMember { + user: TeamUser + role: String! + joinedAt: String + } + + type TeamAddress { + uuid: String! + name: String! + address: String! + latitude: Float + longitude: Float + isDefault: Boolean! + countryCode: String + createdAt: String + processedAt: String + status: String! + } + + type SelectedLocation { + type: String + uuid: String + name: String + latitude: Float + longitude: Float + } + + type Team { + id: String! + name: String! + ownerId: String + members: [TeamMember] + addresses: [TeamAddress] + selectedLocation: SelectedLocation + } + + input InviteMemberInput { + email: String! + role: String + } + + input CreateTeamAddressInput { + name: String! + address: String! + latitude: Float + longitude: Float + countryCode: String + isDefault: Boolean + } + + input UpdateTeamAddressInput { + uuid: String! + name: String + address: String + latitude: Float + longitude: Float + countryCode: String + isDefault: Boolean + } + + input SetSelectedLocationInput { + type: String! + uuid: String! + name: String! + latitude: Float! + longitude: Float! + } + + type InviteMemberResult { success: Boolean!, message: String } + type CreateTeamAddressResult { success: Boolean!, message: String, workflowId: String } + type UpdateTeamAddressResult { success: Boolean!, address: TeamAddress } + type DeleteTeamAddressResult { success: Boolean! } + type SetSelectedLocationResult { success: Boolean! } + + type Query { + team: Team + getTeam(teamId: String!): Team + teamMembers: [TeamMember] + teamAddresses: [TeamAddress] + } + + type Mutation { + inviteMember(input: InviteMemberInput!): InviteMemberResult + createTeamAddress(input: CreateTeamAddressInput!): CreateTeamAddressResult + updateTeamAddress(input: UpdateTeamAddressInput!): UpdateTeamAddressResult + deleteTeamAddress(uuid: String!): DeleteTeamAddressResult + setSelectedLocation(input: SetSelectedLocationInput!): SetSelectedLocationResult + } +` + +async function getTeamByUuid(uuid: string) { + return prisma.team.findUnique({ + where: { uuid }, + include: { + members: { include: { user: { include: { profile: true } } } }, + addresses: { orderBy: { createdAt: 'desc' } }, + }, + }) +} + +function mapTeam(team: NonNullable>>) { + return { + id: team.uuid, + name: team.name, + ownerId: team.ownerId?.toString() ?? null, + members: team.members.map(m => ({ + user: m.user ? { + id: m.user.profile?.logtoId ?? m.user.id.toString(), + firstName: m.user.firstName, + lastName: m.user.lastName, + phone: m.user.profile?.phone ?? '', + avatarId: m.user.profile?.avatarId ?? null, + createdAt: m.user.dateJoined.toISOString(), + } : null, + role: m.role, + joinedAt: m.joinedAt.toISOString(), + })), + addresses: team.addresses.map(a => ({ + uuid: a.uuid, name: a.name, address: a.address, + latitude: a.latitude, longitude: a.longitude, + isDefault: a.isDefault, countryCode: a.countryCode, + createdAt: a.createdAt.toISOString(), + processedAt: a.processedAt?.toISOString() ?? null, + status: a.status, + })), + selectedLocation: team.selectedLocationType ? { + type: team.selectedLocationType, + uuid: team.selectedLocationUuid, + name: team.selectedLocationName, + latitude: team.selectedLocationLat, + longitude: team.selectedLocationLon, + } : null, + } +} + +export const teamResolvers = { + Query: { + team: async (_: unknown, __: unknown, ctx: AuthContext) => { + requireScopes(ctx, 'teams:member') + if (!ctx.teamUuid) throw new GraphQLError('Team UUID not found') + const team = await getTeamByUuid(ctx.teamUuid) + return team ? mapTeam(team) : null + }, + + getTeam: async (_: unknown, args: { teamId: string }, ctx: AuthContext) => { + requireScopes(ctx, 'teams:member') + const team = await getTeamByUuid(args.teamId) + return team ? mapTeam(team) : null + }, + + teamMembers: async (_: unknown, __: unknown, ctx: AuthContext) => { + requireScopes(ctx, 'teams:member') + if (!ctx.teamUuid) return [] + const team = await prisma.team.findUnique({ where: { uuid: ctx.teamUuid } }) + if (!team) return [] + const members = await prisma.teamMember.findMany({ + where: { teamId: team.id }, + include: { user: { include: { profile: true } } }, + }) + return members.map(m => ({ + user: m.user ? { + id: m.user.profile?.logtoId ?? m.user.id.toString(), + firstName: m.user.firstName, lastName: m.user.lastName, + phone: m.user.profile?.phone ?? '', avatarId: m.user.profile?.avatarId ?? null, + createdAt: m.user.dateJoined.toISOString(), + } : null, + role: m.role, joinedAt: m.joinedAt.toISOString(), + })) + }, + + teamAddresses: async (_: unknown, __: unknown, ctx: AuthContext) => { + requireScopes(ctx, 'teams:member') + if (!ctx.teamUuid) return [] + const team = await prisma.team.findUnique({ where: { uuid: ctx.teamUuid } }) + if (!team) return [] + const addrs = await prisma.teamAddress.findMany({ where: { teamId: team.id }, orderBy: { createdAt: 'desc' } }) + return addrs.map(a => ({ + uuid: a.uuid, name: a.name, address: a.address, + latitude: a.latitude, longitude: a.longitude, + isDefault: a.isDefault, countryCode: a.countryCode, + createdAt: a.createdAt.toISOString(), + processedAt: a.processedAt?.toISOString() ?? null, + status: a.status, + })) + }, + }, + + Mutation: { + inviteMember: async (_: unknown, args: { input: { email: string; role?: string } }, ctx: AuthContext) => { + requireScopes(ctx, 'teams:member') + if (!ctx.teamUuid || !ctx.userId) throw new GraphQLError('Not authenticated') + try { + await startInviteWorkflow(ctx.teamUuid, args.input.email, args.input.role || 'MEMBER', ctx.userId) + return { success: true, message: 'Invitation workflow started' } + } catch (e) { + console.error('Failed to start invite workflow:', e) + return { success: false, message: String(e) } + } + }, + + createTeamAddress: async (_: unknown, args: { input: { name: string; address: string; latitude?: number; longitude?: number; countryCode?: string; isDefault?: boolean } }, ctx: AuthContext) => { + requireScopes(ctx, 'teams:member') + if (!ctx.teamUuid) throw new GraphQLError('Not authenticated') + const team = await prisma.team.findUnique({ where: { uuid: ctx.teamUuid } }) + if (!team) throw new GraphQLError('Team not found') + const addr = await prisma.teamAddress.create({ + data: { + teamId: team.id, name: args.input.name, address: args.input.address, + latitude: args.input.latitude, longitude: args.input.longitude, + countryCode: args.input.countryCode || '', isDefault: args.input.isDefault || false, + }, + }) + try { + const wfId = await startAddressWorkflow( + ctx.teamUuid, addr.uuid, addr.name, addr.address, + addr.latitude ?? undefined, addr.longitude ?? undefined, + addr.countryCode || undefined, addr.isDefault, + ) + return { success: true, message: 'Address created', workflowId: wfId } + } catch (e) { + console.error('Failed to start address workflow:', e) + return { success: true, message: 'Address created but workflow failed', workflowId: null } + } + }, + + updateTeamAddress: async (_: unknown, args: { input: { uuid: string; name?: string; address?: string; latitude?: number; longitude?: number; countryCode?: string; isDefault?: boolean } }, ctx: AuthContext) => { + requireScopes(ctx, 'teams:member') + const data: Record = {} + if (args.input.name !== undefined) data.name = args.input.name + if (args.input.address !== undefined) data.address = args.input.address + if (args.input.latitude !== undefined) data.latitude = args.input.latitude + if (args.input.longitude !== undefined) data.longitude = args.input.longitude + if (args.input.countryCode !== undefined) data.countryCode = args.input.countryCode + if (args.input.isDefault !== undefined) data.isDefault = args.input.isDefault + const addr = await prisma.teamAddress.update({ where: { uuid: args.input.uuid }, data }) + return { + success: true, + address: { + uuid: addr.uuid, name: addr.name, address: addr.address, + latitude: addr.latitude, longitude: addr.longitude, + isDefault: addr.isDefault, countryCode: addr.countryCode, + createdAt: addr.createdAt.toISOString(), + processedAt: addr.processedAt?.toISOString() ?? null, + status: addr.status, + }, + } + }, + + deleteTeamAddress: async (_: unknown, args: { uuid: string }, ctx: AuthContext) => { + requireScopes(ctx, 'teams:member') + await prisma.teamAddress.delete({ where: { uuid: args.uuid } }) + return { success: true } + }, + + setSelectedLocation: async (_: unknown, args: { input: { type: string; uuid: string; name: string; latitude: number; longitude: number } }, ctx: AuthContext) => { + requireScopes(ctx, 'teams:member') + if (!ctx.teamUuid) throw new GraphQLError('Not authenticated') + await prisma.team.update({ + where: { uuid: ctx.teamUuid }, + data: { + selectedLocationType: args.input.type, + selectedLocationUuid: args.input.uuid, + selectedLocationName: args.input.name, + selectedLocationLat: args.input.latitude, + selectedLocationLon: args.input.longitude, + }, + }) + return { success: true } + }, + }, +} diff --git a/src/schemas/user.ts b/src/schemas/user.ts new file mode 100644 index 0000000..7931389 --- /dev/null +++ b/src/schemas/user.ts @@ -0,0 +1,189 @@ +import { GraphQLError } from 'graphql' +import { prisma } from '../db.js' +import { startTeamCreated } from '../services/temporal.js' +import type { AuthContext } from '../auth.js' + +export const userTypeDefs = `#graphql + type UserTeam { + id: String! + name: String! + teamType: String + logtoOrgId: String + createdAt: String + } + + type User { + id: String + firstName: String + lastName: String + phone: String + avatarId: String + activeTeamId: String + activeTeam: UserTeam + teams: [UserTeam] + } + + type TeamMemberInfo { + uuid: String! + role: String! + joinedAt: String + } + + type TeamInvitationInfo { + uuid: String! + email: String! + role: String! + status: String! + invitedBy: String + expiresAt: String + createdAt: String + } + + type TeamWithMembers { + uuid: String! + name: String! + members: [TeamMemberInfo] + invitations: [TeamInvitationInfo] + } + + input CreateTeamInput { + name: String! + teamType: String + } + + input UpdateUserInput { + firstName: String + lastName: String + phone: String + avatarId: String + } + + type CreateTeamResult { + team: UserTeam + success: Boolean! + } + + type UpdateUserResult { + user: User + success: Boolean! + } + + type SwitchTeamResult { + success: Boolean! + } + + type Query { + me: User + getTeam(teamId: String!): TeamWithMembers + } + + type Mutation { + createTeam(input: CreateTeamInput!): CreateTeamResult + updateUser(userId: String!, input: UpdateUserInput!): UpdateUserResult + switchTeam(teamId: String!): SwitchTeamResult + } +` + +async function getOrCreateProfile(logtoId: string) { + let profile = await prisma.userProfile.findUnique({ where: { logtoId: logtoId }, include: { user: true, activeTeam: true } }) + if (!profile) { + const user = await prisma.user.create({ data: { username: logtoId, firstName: '', lastName: '' } }) + profile = await prisma.userProfile.create({ + data: { userId: user.id, logtoId: logtoId }, + include: { user: true, activeTeam: true }, + }) + } + return profile +} + +export const userResolvers = { + Query: { + me: async (_: unknown, __: unknown, ctx: AuthContext) => { + if (!ctx.userId) throw new GraphQLError('Not authenticated') + const profile = await getOrCreateProfile(ctx.userId) + const memberships = await prisma.teamMember.findMany({ where: { userId: profile.userId }, include: { team: true } }) + return { + id: ctx.userId, + firstName: profile.user.firstName, + lastName: profile.user.lastName, + phone: profile.phone, + avatarId: profile.avatarId, + activeTeamId: profile.activeTeam?.uuid ?? null, + activeTeam: profile.activeTeam ? { id: profile.activeTeam.uuid, name: profile.activeTeam.name, teamType: profile.activeTeam.teamType, logtoOrgId: profile.activeTeam.logtoOrgId, createdAt: profile.activeTeam.createdAt.toISOString() } : null, + teams: memberships.map(m => ({ id: m.team.uuid, name: m.team.name, teamType: m.team.teamType, logtoOrgId: m.team.logtoOrgId, createdAt: m.team.createdAt.toISOString() })), + } + }, + + getTeam: async (_: unknown, args: { teamId: string }, ctx: AuthContext) => { + if (!ctx.userId) throw new GraphQLError('Not authenticated') + const team = await prisma.team.findUnique({ + where: { uuid: args.teamId }, + include: { + members: { include: { user: true } }, + invitations: true, + }, + }) + if (!team) return null + return { + uuid: team.uuid, + name: team.name, + members: team.members.map(m => ({ uuid: m.uuid, role: m.role, joinedAt: m.joinedAt.toISOString() })), + invitations: team.invitations.map(i => ({ + uuid: i.uuid, email: i.email, role: i.role, status: i.status, + invitedBy: i.invitedBy, expiresAt: i.expiresAt?.toISOString() ?? null, + createdAt: i.createdAt.toISOString(), + })), + } + }, + }, + + Mutation: { + createTeam: async (_: unknown, args: { input: { name: string; teamType?: string } }, ctx: AuthContext) => { + if (!ctx.userId) throw new GraphQLError('Not authenticated') + const profile = await getOrCreateProfile(ctx.userId) + const team = await prisma.team.create({ + data: { name: args.input.name, teamType: args.input.teamType || 'BUYER', ownerId: profile.userId }, + }) + await prisma.teamMember.create({ data: { teamId: team.id, userId: profile.userId, role: 'OWNER' } }) + await prisma.userProfile.update({ where: { id: profile.id }, data: { activeTeamId: team.id } }) + + try { + await startTeamCreated(team.uuid, team.name, ctx.userId, team.teamType) + } catch (e) { + console.error('Failed to start team_created workflow:', e) + } + + return { + team: { id: team.uuid, name: team.name, teamType: team.teamType, logtoOrgId: team.logtoOrgId, createdAt: team.createdAt.toISOString() }, + success: true, + } + }, + + updateUser: async (_: unknown, args: { userId: string; input: { firstName?: string; lastName?: string; phone?: string; avatarId?: string } }, ctx: AuthContext) => { + if (!ctx.userId) throw new GraphQLError('Not authenticated') + const profile = await getOrCreateProfile(ctx.userId) + const userUpdate: Record = {} + if (args.input.firstName !== undefined) userUpdate.firstName = args.input.firstName + if (args.input.lastName !== undefined) userUpdate.lastName = args.input.lastName + if (Object.keys(userUpdate).length > 0) { + await prisma.user.update({ where: { id: profile.userId }, data: userUpdate }) + } + const profileUpdate: Record = {} + if (args.input.phone !== undefined) profileUpdate.phone = args.input.phone + if (args.input.avatarId !== undefined) profileUpdate.avatarId = args.input.avatarId + if (Object.keys(profileUpdate).length > 0) { + await prisma.userProfile.update({ where: { id: profile.id }, data: profileUpdate }) + } + return { user: { id: ctx.userId }, success: true } + }, + + switchTeam: async (_: unknown, args: { teamId: string }, ctx: AuthContext) => { + if (!ctx.userId) throw new GraphQLError('Not authenticated') + const profile = await getOrCreateProfile(ctx.userId) + const team = await prisma.team.findUnique({ where: { uuid: args.teamId } }) + if (!team) throw new GraphQLError('Team not found') + await prisma.userProfile.update({ where: { id: profile.id }, data: { activeTeamId: team.id } }) + return { success: true } + }, + }, +} diff --git a/src/services/temporal.ts b/src/services/temporal.ts new file mode 100644 index 0000000..321a0af --- /dev/null +++ b/src/services/temporal.ts @@ -0,0 +1,46 @@ +import { Client, Connection } from '@temporalio/client' +import { randomUUID } from 'crypto' + +const TEMPORAL_HOST = process.env.TEMPORAL_INTERNAL_URL || 'temporal:7233' +const TEMPORAL_NAMESPACE = process.env.TEMPORAL_NAMESPACE || 'default' +const TEMPORAL_TASK_QUEUE = process.env.TEMPORAL_TASK_QUEUE || 'platform-worker' + +async function getClient() { + const connection = await Connection.connect({ address: TEMPORAL_HOST }) + return new Client({ connection, namespace: TEMPORAL_NAMESPACE }) +} + +export async function startTeamCreated(teamUuid: string, teamName: string, ownerId: string, teamType: string) { + const client = await getClient() + const handle = await client.workflow.start('team_created_workflow', { + args: [{ team_uuid: teamUuid, team_name: teamName, owner_id: ownerId, team_type: teamType }], + taskQueue: TEMPORAL_TASK_QUEUE, + workflowId: teamUuid, + }) + console.log(`Team created workflow started: ${handle.workflowId}`) + return handle.workflowId +} + +export async function startAddressWorkflow(teamUuid: string, addressUuid: string, name: string, address: string, latitude?: number, longitude?: number, countryCode?: string, isDefault?: boolean) { + const client = await getClient() + const workflowId = `address-${randomUUID()}` + const handle = await client.workflow.start('create_address', { + args: [{ team_uuid: teamUuid, address_uuid: addressUuid, name, address, latitude, longitude, country_code: countryCode, is_default: isDefault }], + taskQueue: TEMPORAL_TASK_QUEUE, + workflowId, + }) + console.log(`Address workflow started: ${handle.workflowId}`) + return handle.workflowId +} + +export async function startInviteWorkflow(teamUuid: string, email: string, role: string, invitedBy: string) { + const client = await getClient() + const workflowId = `invite-${randomUUID()}` + const handle = await client.workflow.start('invite_user', { + args: [{ team_uuid: teamUuid, email, role, invited_by: invitedBy }], + taskQueue: TEMPORAL_TASK_QUEUE, + workflowId, + }) + console.log(`Invite workflow started: ${handle.workflowId}`) + return handle.workflowId +} diff --git a/teams/__init__.py b/teams/__init__.py deleted file mode 100644 index baaa45d..0000000 --- a/teams/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# Django orders service \ No newline at end of file diff --git a/teams/__pycache__/__init__.cpython-313.pyc b/teams/__pycache__/__init__.cpython-313.pyc deleted file mode 100644 index c5032b0b13c8f43fdf5d182552f443f068435019..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167 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 diff --git a/teams/__pycache__/settings_local.cpython-313.pyc b/teams/__pycache__/settings_local.cpython-313.pyc deleted file mode 100644 index c8e56bce8c634046aa42ace4495542ecd724d2b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2005 zcma)7OK;mo5GM7cL{XL%Sys{n%>#YNtw|e6+9C)7&=TdUkwr&KHEm#kpry6Um=c*? z%Bgwcy_Z}H1K7vRH!NarGF$9zW-D@^J!Q101 z0z^>~#3UAR5(DB-Sd^mg1bwGL67e8FqaeW2PuLX}@M6HtfD90};vl=sGYps$BP%Qt zKn`WWJes2(bM!Y4@+eO^R{{>Y0t%=A7SIAHf<-BUij=X~E0wSQ6(n0`No><_cRj(f zJBGE~h5O5U@IWK%QaR-ny3dV4&lWrOz(wY^XmtDLz`HVw4ypYIGhko>2d;bIKDc|gJ)qeHum7N8v?EsN@~sJ9PEo&{$;F_}n9f6{-?R^Aht}_3F=jV$R{CksJsWBXMu^1|< zlT)XKYE1Hz!}NozJIL zUnTs)GF^DrOH(kE%Mp@Ln(OtZLSjvML-FEhxQvD*+SV!_C*jHTNQ6HXCS&B?2$QE? z`gRvuSX?uE^tjkH6I$Jxx3KHF&I3uBTnxK5b|2hbSy}P&0gNebJFdNN8X_7t%O#R@ z=q+NI+bBwJ6~gIy5JcBW5%?_1sWjPdJ||Aq5!QCAnA>Iwc1dg$}NRtTB@q)?N+0rHftoMDI1#&SyKQ> zRb@>Mf&d~kMkY&2P`R|1cO59J^P z$yb${+-_*P+}2dRR#zHTQmm*gpihzwR$Xn?Y4HImyvJ$IXXrGW?zpNnwYuB@KQr%w zE0{E-Hl|mZgofBM2HVD-3HPO!Hrm6E(Sc`mmd>U`nv7DoV(7Yb?yx@TlIR=|?jh~w z(1MT9=hS)duZ4f1%Q(ui?4L~OH-7FF_v52C{H-JY*021XH~i8Ozx0M*J>pk=?pV0) zr$=1IkB{aHuj0ON5=-YJe)go4%0~S3xX9$L`J2lDUM3g;i_`DSUY42qpLTLm?B!D+xiD{wUEF7 diff --git a/teams/__pycache__/urls.cpython-313.pyc b/teams/__pycache__/urls.cpython-313.pyc deleted file mode 100644 index 2800b3e960c68d81f8f299a2f44a65cb2368d226..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1350 zcmah|&rcIU6rOFj?Y3oGN=-ySK@6nzN7o=d03yMQ$u1aet1+fhx9!p{wB6;+7PL2S z9N}OHH%=zrOgx)#^jK&Nag)Y_CvO=30cWOd3L%Y?&CK_HeBaD_J98$AK14?O%aZ=p ziO_FqbVi^J&OUJneMCu=QJtP#m%ooD4e^UUq?tVP0{|9`MKl2(lNvvJZT+ zAN(xlQu<^OM26i;Kn_BXVUN-;hakkTpbW@i2#=w(a~vhTX)Y1z9H_e{Zg+79#T_lg zc)ql29HoWC-A=T-5>Fdc1^<)Ma)8CUB?#b*= zdy=8#z>HIJ!_`7KdgTu-D9YI`HDA^%1n{P670K$)VOY&*@3gXMMP0UFY1qoFZCQ5c zSv6bIb5B4ui_e!{>e`kae1SE%;7Dm|`Me{rJhgnzCi$Evy6S*2RAK+mvIl3G$yD(bKW=F>Myw!5WV6FXT{U+S7vU#j(WqC{V+d1;mR zNR<+}TYcdxYFT?49kc`aHMLSOVmYH?fu03&`;qN$JF8H_z*Emi+p|gff@66tXMk!M zfMc|s;G!u(x--tGrWs>dY%B1P5D0Yg(uqDZd$gO`Dh9_cbPfD8>-y!abFGBF9yyfN z?k|WmXXLU@x9LD%x6NbS(rliVYkO3jq30(*4oc+GSQ=FDXLLsLko{PqR{~2=#U-_p zRo8WGQ`$0M9h+)SlMK@`Hg#3Xs=0NolE)I;x;<0%nEBoo9+r)KwWK|Qn?#bnJ^YPK zr%sOJnrN(vMw)2)7t((qy@_U;D9*kIf8EIC-5%VD@6GPc?k(&tH27OTd7lk>-u^M_VFl{uPx+Za+CeD=S=8~eit sD<>0k#}jjhsd^%PH1Vc!ZKc6yD06tHc<}m&zke!vf{qV<7$p__1AuO9I{*Lx diff --git a/teams/settings.py b/teams/settings.py deleted file mode 100644 index 522c860..0000000 --- a/teams/settings.py +++ /dev/null @@ -1,161 +0,0 @@ -import os -from pathlib import Path -from urllib.parse import urlparse -from dotenv import load_dotenv -from infisical_sdk import InfisicalSDKClient -import sentry_sdk -from sentry_sdk.integrations.django import DjangoIntegration - -load_dotenv() - -INFISICAL_API_URL = os.environ["INFISICAL_API_URL"] -INFISICAL_CLIENT_ID = os.environ["INFISICAL_CLIENT_ID"] -INFISICAL_CLIENT_SECRET = os.environ["INFISICAL_CLIENT_SECRET"] -INFISICAL_PROJECT_ID = os.environ["INFISICAL_PROJECT_ID"] -INFISICAL_ENV = os.environ.get("INFISICAL_ENV", "prod") - -client = InfisicalSDKClient(host=INFISICAL_API_URL) -client.auth.universal_auth.login( - client_id=INFISICAL_CLIENT_ID, - client_secret=INFISICAL_CLIENT_SECRET, -) - -# Fetch secrets from /teams and /shared -for secret_path in ["/teams", "/shared"]: - secrets_response = client.secrets.list_secrets( - environment_slug=INFISICAL_ENV, - secret_path=secret_path, - project_id=INFISICAL_PROJECT_ID, - expand_secret_references=True, - view_secret_value=True, - ) - for secret in secrets_response.secrets: - os.environ[secret.secretKey] = secret.secretValue - -BASE_DIR = Path(__file__).resolve().parent.parent - -SECRET_KEY = os.getenv('DJANGO_SECRET_KEY', 'dev-secret-key-change-in-production') - -DEBUG = os.getenv('DEBUG', 'False') == 'True' - -# Sentry/GlitchTip configuration -SENTRY_DSN = os.getenv('SENTRY_DSN', '') -if SENTRY_DSN: - sentry_sdk.init( - dsn=SENTRY_DSN, - integrations=[DjangoIntegration()], - auto_session_tracking=False, - traces_sample_rate=0.01, - release=os.getenv('RELEASE_VERSION', '1.0.0'), - environment=os.getenv('ENVIRONMENT', 'production'), - send_default_pii=False, - debug=DEBUG, - ) - -ALLOWED_HOSTS = ['*'] - -CSRF_TRUSTED_ORIGINS = ['https://teams.optovia.ru'] - -INSTALLED_APPS = [ - 'whitenoise.runserver_nostatic', - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'corsheaders', - 'graphene_django', - 'teams_app', -] - -MIDDLEWARE = [ - 'corsheaders.middleware.CorsMiddleware', - 'django.middleware.security.SecurityMiddleware', - 'whitenoise.middleware.WhiteNoiseMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', -] - -ROOT_URLCONF = 'teams.urls' - -TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - ], - }, - }, -] - -WSGI_APPLICATION = 'teams.wsgi.application' - -db_url = os.environ["TEAMS_DATABASE_URL"] -parsed = urlparse(db_url) -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': parsed.path.lstrip('/'), - 'USER': parsed.username, - 'PASSWORD': parsed.password, - 'HOST': parsed.hostname, - 'PORT': str(parsed.port) if parsed.port else '', - } -} - -# Internationalization -LANGUAGE_CODE = 'ru-ru' -TIME_ZONE = 'UTC' -USE_I18N = True -USE_TZ = True - -# Static files -STATIC_URL = '/static/' -STATIC_ROOT = BASE_DIR / 'staticfiles' - -# Default primary key field type -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' - -# CORS -CORS_ALLOW_ALL_ORIGINS = False -CORS_ALLOWED_ORIGINS = ['https://optovia.ru'] -CORS_ALLOW_CREDENTIALS = True - -# Logging -LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, - 'handlers': { - 'console': { - 'class': 'logging.StreamHandler', - }, - }, - 'loggers': { - 'django.request': { - 'handlers': ['console'], - 'level': 'DEBUG', - 'propagate': False, - }, - }, -} - -# Logto JWT settings -LOGTO_JWKS_URL = os.getenv('LOGTO_JWKS_URL', 'https://auth.optovia.ru/oidc/jwks') -LOGTO_ISSUER = os.getenv('LOGTO_ISSUER', 'https://auth.optovia.ru/oidc') -LOGTO_TEAMS_AUDIENCE = os.getenv('LOGTO_TEAMS_AUDIENCE', 'https://teams.optovia.ru') -# ID Token audience can be omitted when we only need signature + issuer validation. -LOGTO_ID_TOKEN_AUDIENCE = os.getenv('LOGTO_ID_TOKEN_AUDIENCE') - -# Odoo connection (internal M2M) -ODOO_INTERNAL_URL = os.getenv('ODOO_INTERNAL_URL', 'odoo:8069') diff --git a/teams/settings_local.py b/teams/settings_local.py deleted file mode 100644 index c5e2b7c..0000000 --- a/teams/settings_local.py +++ /dev/null @@ -1,71 +0,0 @@ -# Local settings for makemigrations (no Infisical, SQLite) -from pathlib import Path - -BASE_DIR = Path(__file__).resolve().parent.parent - -SECRET_KEY = 'local-dev-key' -DEBUG = True -ALLOWED_HOSTS = ['*'] - -INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'corsheaders', - 'graphene_django', - 'teams_app', -] - -MIDDLEWARE = [ - 'corsheaders.middleware.CorsMiddleware', - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', -] - -ROOT_URLCONF = 'teams.urls' - -TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - ], - }, - }, -] - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': BASE_DIR / 'db.sqlite3', - } -} - -LANGUAGE_CODE = 'ru-ru' -TIME_ZONE = 'UTC' -USE_I18N = True -USE_TZ = True - -STATIC_URL = '/static/' -STATIC_ROOT = BASE_DIR / 'staticfiles' - -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' - -# CORS -CORS_ALLOW_ALL_ORIGINS = False -CORS_ALLOWED_ORIGINS = ['http://localhost:3000', 'https://optovia.ru'] -CORS_ALLOW_CREDENTIALS = True diff --git a/teams/urls.py b/teams/urls.py deleted file mode 100644 index e019bb2..0000000 --- a/teams/urls.py +++ /dev/null @@ -1,17 +0,0 @@ -from django.contrib import admin -from django.urls import path -from django.views.decorators.csrf import csrf_exempt -from teams_app.views import test_jwt, PublicGraphQLView, UserGraphQLView, TeamGraphQLView, M2MGraphQLView -from teams_app.schemas.public_schema import public_schema -from teams_app.schemas.user_schema import user_schema -from teams_app.schemas.team_schema import team_schema -from teams_app.schemas.m2m_schema import m2m_schema - -urlpatterns = [ - path('admin/', admin.site.urls), - path('graphql/public/', csrf_exempt(PublicGraphQLView.as_view(graphiql=True, schema=public_schema))), - path('graphql/user/', csrf_exempt(UserGraphQLView.as_view(graphiql=True, schema=user_schema))), - path('graphql/team/', csrf_exempt(TeamGraphQLView.as_view(graphiql=True, schema=team_schema))), - path('graphql/m2m/', csrf_exempt(M2MGraphQLView.as_view(graphiql=True, schema=m2m_schema))), - path('test-jwt/', test_jwt, name='test_jwt'), -] \ No newline at end of file diff --git a/teams/wsgi.py b/teams/wsgi.py deleted file mode 100644 index 66d0000..0000000 --- a/teams/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -import os -from django.core.wsgi import get_wsgi_application - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'teams.settings') - -application = get_wsgi_application() \ No newline at end of file diff --git a/teams_app/__init__.py b/teams_app/__init__.py deleted file mode 100644 index 6c1ab79..0000000 --- a/teams_app/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# Orders Django app \ No newline at end of file diff --git a/teams_app/__pycache__/__init__.cpython-313.pyc b/teams_app/__pycache__/__init__.cpython-313.pyc deleted file mode 100644 index c442b4f2b3dd7845a56f098f7d603d218da82c91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171 zcmey&%ge<81nR2NnZiK&F^B^Lj8MjB79e9PLpp;dqu)w~A|@d3Gf3)|mwsq*YEiL% zQE72bVqQ{Wc4lgsetCXTc5y*sa;koQK}mjDW}<#lVsdtBUP`fkNory)l#EX-DA13O q&&R;fW^s!MMf<{6`>J#cqD)R$+&y1bK6r)H)%JqDlIllMYduQAmAI}T^ zyZeV7{*x8rZ%hV%nf{=6IwiydVGG+>5DkNjs<2abdLh+FQ@UZ2*|5lJWGK_fQnrz! zTvgmKzS%dR+4(#!Zlo_7dOj_V3)`F#w#C>3JD9=fVp@+b_7|uylG7aG%rIwmkDSGk zoYoL$jycEn$T>ceGc&}QXHLYlm)J`qIkQ8YMdrl!?}f8Gk~25NSz=CL_rh6eR%#PZ zk+GT~E!STT+fR}2T1J}J19w^GVHbntrGR7!<1gDQVd5rX)Ry~)=hvg#L0cBSjRX3c zqMKnWkOd&-eV>9j_WE_9KKeB!dM9}LK->^y*n(2FL1{Zhrky6sHYsCUl(jRIYi4UX zIi|_rq6rr*X?DAzFU_{Q97rp=(`Fxwt*DtqPDD+IxAGnZZW8#8o74$dtkWyiT0Qk=BHcF>Nn-3sHx@x!>&a#v+R%~-jFBN>kam%N|&K+y7IS>{Om zsNGr}EF5&47>V#WxP-!`ZW6?fLzC=ikN<_dQb#J{I(6fg+g@^ShrvqyPDHokj_U>W zsFOr1p<7>aJW^T$M}L@#gqMwdsiRrJ9cm3(E;z? z;-kq+_rIcJ1K=y?x{O@wvYS^$Szv0;ol2VtPdWJrqcpunQ-h(7^Ejp`UuEFmwlp6@npsHm9i(}4APvy3 zEX{LWr{z(loz*U%;%|{wuE_z8_Nb9v{*==zfoJu5(mH+i*uNFM&FuEi?8nrn!kS!YcWu;+!DF%J8hO1WWn{4 za3ydMgjOI;AMpmA!S2MaUELTux>}Z|0eTGv!O$TX_(exxsxS~@SF>Ek6b7EexK(hE ze9F-uxN?6{1F`+$n9)3=V;*`bDkzBlv!i3joxnb;ibj8^M?hv>{WK9uUlzTn+fHcJ z@ghGMNTHhIbDU5uX6o1DGb|`Fvn30g5(JR$rLB>r_MCob>7_+#atq5_MUl!XWPZaq1mxUWusL~Z zeex8Lb3h&ja&8A%+Axj+dG_~{n=@zDXU+h57RV})XSYgy&Oa+}Y#1jrw7Yqd9MS>)m8$HIOgg<9pxBd&!{Dm>_n2*?D^LPZ>u&UgB?rm2qTOh zlOu|BlPr_Zgn6rk`4{x7U*(~f1Yzyj1tB%#`$h3R&pI+`S8|1P6b#laxg!?@DI@4H ziazr&U_RDZfMZE595d6Wg7?&Woo9E?^+x=YXGz|STg_e`i&QlaWU^oC{7{NCHsjiP zfEUF*ISD_QIzYyI0>DfFSVNgQJ_YcrCNqc8nG&cXELF<07Vk>Yk1liUs)DyglovYhOCGg& zyDPF-MZYD-iGcY)PjY7KBe@DZ2b>Bx^#Q~LhLbgy#iu1kNE%q diff --git a/teams_app/__pycache__/auth.cpython-313.pyc b/teams_app/__pycache__/auth.cpython-313.pyc deleted file mode 100644 index 93d5c1bf53d38c47515f88ff7703ee0b821dfbc3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3467 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 diff --git a/teams_app/__pycache__/models.cpython-313.pyc b/teams_app/__pycache__/models.cpython-313.pyc deleted file mode 100644 index 793ceda6c8e2debd1e3a96a9e475751b38c320b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9636 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 KevDu+nEe;v>yDQI diff --git a/teams_app/__pycache__/views.cpython-313.pyc b/teams_app/__pycache__/views.cpython-313.pyc deleted file mode 100644 index 5614d6e5500741622127035083e4a4b80fa36aee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4957 zcmcf_TWlQF_0G)B?s)C>u3xdUPVmHyLpH=~z&H;Q5O!in)_K+AEwmdt8t;znN!ByV zomnSw5i)#G(^d@?LN#ioSnWrXzX*ZqLLcVwk!E`+>kH9Q{KgWL;gg723(vUViE!s0QXCQp_)XH1{1ZkHc?0GL~=SH2~pBl zK8S`uPR&q#B22?Be{d+0XrK*=M%tKYqD_fr+6?sCD4{KFq?1T>Q6hy-hx@pa0J_Pg z)&n(MMQwGd5ui3yQQKTFsGG-`So2L3cOu3(f~i`TrjMI|*Ck9tA6Ctrp_?lF zu1%YCOjggUlQ|21HXPNbl&qE+G0v*`Af*Pq$$*p?=S0R;OCD7fs#4j)Rj0{J8#&dK z$EYzW=adUsL&-Qb?smm8Xc{+q1I>fiTfK)xBiut$mDMEaE8{wos_`}?8IPJ|Bwq6S zNIj7PfD00jcrPc_#95sKNwwad6qvp=q@cum&#C)T^&WjV;$iD^CwZz_s@>1(e3Bb( zTBm!MRF`V@@Zn7!wmx@~DqZ;`KfHN;&BLTn_lB_39V&kmDNxuE8$#xKl*V%rM zRGP<_G4cr4LB^O3l6RqGsR>SRz86H^O)ji4?pn33p0+Lfx&L-rY*YS85NrR=ezWj= z;RXAz_Unb8+kX;OJ(Dvu-4g9L?6(USMf-1s8C(Rm8T&1JK}Bo^v9F4S z=Ya`W-T=4&vVKwcW!&La^y(Pv_)SZ(@+L*6(Ov-;j4?C>_=%e$z-cZXk87WN_0?Cv zTIV{voK^L4Yr+YYe&wh-rK#tf=3^(H7&$4A4E7(FXn3ka}pakgXhM42m^o*)oH_^Zt zrDq_BdmO~&lO*DFI=$>n<4-Zm5plk?7>UjD zYXaG}eSYxw!9{*Cy+{{>3(sEby_UC=Pua;IUi-UwMSr`` z?mDnAQfwNS6_y*@uQzsn(AYWOS7@Eax~;2(LEXdc^XLBDv>?6RR@gFdt+x<9`Jr&~%M}h6zg*klGIF5n z($*cb!pm(1A-cS!W1joX5%|?w5H^E=xg(dQ#iy=4vv|A^9{x}m{&FRNJH9Xvz)QVQ zJ8&QQ!vJ@vjl6qb@K6i)ZePox2=`u)0sOrPkFYIxxQ=_Tv*U1pd!Jzde?Pzj#Pab3 zRdN&GKlTGKMa<_k9e?on38O!6O&r%UnXGya%7wG(RDLw8rSG6OjDS5MXscKo&>?Ok z-Bv{~o48e^RLYZN7zi7O#5{bC5C!Z%&O&vlzEDk7i2idif==q&~2b6?E>J`44zM`IXpAQ(H%&B7(p)p6Kx17fI=l9POGe$@@-1W z?&0(xtnNYfGXQ4DCxQB(KKJ}{bDN5Rj-_z(3d{2?%i*Sr(?6S@yZ6%W*LGizb{ERw zRSfT)^({r3e=YnSc|E*$e&T9ZVaHxu*n4ZawizR>iW!Q#V8f zq6=z)mUd~e_#F`v25GA(@=@m1sy?d^C^&kUB&g|DXYU$hgiDgAp-f;eb3gP4hnYQ$ zNXE$(_Jk9htb{UHG7b_P-pqqe=o^}@S+ab^=lD!DJLdQlI&M1tvk><%*T`}@tC%LZ z5XK%@e8x37J&Z!4cf3Q~lQ#(KCVJ7W8L}+yDT@2-j{UR#*=GyFmSrLIQs4ujZEm|Q z#O8Mth1e=Ek}KqjfC}l#q$_RmP>KK_-o!TZ){EpL zU;pPmmfy8X0MH?imNdZ=BKWW@8TA18}3wbisP_rwc->H6vbY<_PhObUj z2wdm?dUIfXqX_Ut*3I$QMspy`w`Pud=vJz&@gopE{oEba04{Ooq>`S1jL~fw-DNaZ z6-)8piH(U_#D-X-YDVl9A^tMr=mjjrD%F*&2=O?jficCMBkvCYTrG-X<#!t0wP&*OdX1#+>tdOtZuGcm4_g_xI=Csv zb#(X6)Qt!?Hr!rFI9RG$kJ2pc!17|A2LO!;!+cC?KPJH&M7%+^-yjd&Alv>y1`1?g z#ZTDKr))bTF{>P)D=zxkV+>*9pZj=*T_phi9jRej*4lVx*Iexy5O%Fa0K9zmE_eXw Lsm};ZZq)t dict: - """Decode and verify a JWT, enforcing issuer and optional audience.""" - try: - signing_key = self._jwks_client.get_signing_key_from_jwt(token) - header_alg = jwt.get_unverified_header(token).get("alg") - - return jwt.decode( - token, - signing_key.key, - algorithms=[header_alg] if header_alg else None, - issuer=self._issuer, - audience=audience, - options={"verify_aud": audience is not None}, - ) - except InvalidTokenError as exc: - logger.warning("Failed to validate Logto token: %s", exc) - raise - - -def get_bearer_token(request) -> str: - """Extract Bearer token from Authorization header.""" - auth_header = request.META.get("HTTP_AUTHORIZATION", "") - if not auth_header.startswith("Bearer "): - raise InvalidTokenError("Missing Bearer token") - - token = auth_header.split(" ", 1)[1] - if not token or token == "undefined": - raise InvalidTokenError("Empty Bearer token") - - return token - - -def scopes_from_payload(payload: dict) -> list[str]: - """Split scope string (if present) into a list.""" - scope_value = payload.get("scope") - if not scope_value: - return [] - if isinstance(scope_value, str): - return scope_value.split() - if isinstance(scope_value, Iterable): - return list(scope_value) - return [] - - -validator = LogtoTokenValidator( - getattr(settings, "LOGTO_JWKS_URL", "https://auth.optovia.ru/oidc/jwks"), - getattr(settings, "LOGTO_ISSUER", "https://auth.optovia.ru/oidc"), -) diff --git a/teams_app/graphql_middleware.py b/teams_app/graphql_middleware.py deleted file mode 100644 index f1ce978..0000000 --- a/teams_app/graphql_middleware.py +++ /dev/null @@ -1,81 +0,0 @@ -""" -GraphQL middleware for JWT authentication. - -Each class is bound to a specific GraphQL endpoint (public/user/team/m2m). -""" -import logging -from django.conf import settings -from graphql import GraphQLError -from jwt import InvalidTokenError - -from .auth import get_bearer_token, scopes_from_payload, validator - -logger = logging.getLogger(__name__) - - -def _is_introspection(info) -> bool: - """Возвращает True для любых introspection резолвов.""" - field = getattr(info, "field_name", "") - parent = getattr(getattr(info, "parent_type", None), "name", "") - return field.startswith("__") or parent.startswith("__") - - -class PublicNoAuthMiddleware: - """Public endpoint - no authentication required.""" - - def resolve(self, next, root, info, **kwargs): - return next(root, info, **kwargs) - - -class UserJWTMiddleware: - """User endpoint - requires ID token.""" - - def resolve(self, next, root, info, **kwargs): - request = info.context - if _is_introspection(info): - return next(root, info, **kwargs) - - # Only process auth once (check if already processed) - if not hasattr(request, 'user_id'): - try: - token = get_bearer_token(request) - payload = validator.decode(token) - request.user_id = payload.get('sub') - logger.info(f"[UserJWTMiddleware] user_id set to: {request.user_id}") - except InvalidTokenError as exc: - logger.warning(f"[UserJWTMiddleware] Token error: {exc}") - raise GraphQLError("Unauthorized") from exc - - return next(root, info, **kwargs) - - -class TeamJWTMiddleware: - """Team endpoint - requires Access token for teams audience.""" - - def resolve(self, next, root, info, **kwargs): - request = info.context - if _is_introspection(info): - return next(root, info, **kwargs) - - try: - token = get_bearer_token(request) - payload = validator.decode( - token, - audience=getattr(settings, 'LOGTO_TEAMS_AUDIENCE', None), - ) - request.user_id = payload.get('sub') - request.team_uuid = payload.get('team_uuid') - request.scopes = scopes_from_payload(payload) - if not request.team_uuid or 'teams:member' not in request.scopes: - raise GraphQLError("Unauthorized") - except InvalidTokenError as exc: - raise GraphQLError("Unauthorized") from exc - - return next(root, info, **kwargs) - - -class M2MNoAuthMiddleware: - """M2M endpoint - internal services only, no auth for now.""" - - def resolve(self, next, root, info, **kwargs): - return next(root, info, **kwargs) diff --git a/teams_app/middleware.py b/teams_app/middleware.py deleted file mode 100644 index 62357f3..0000000 --- a/teams_app/middleware.py +++ /dev/null @@ -1,56 +0,0 @@ -import json -import logging - -from django.conf import settings -from django.utils.deprecation import MiddlewareMixin -from jwt import InvalidTokenError - -from .auth import get_bearer_token, scopes_from_payload, validator - -logger = logging.getLogger(__name__) - -class LogtoJWTMiddleware(MiddlewareMixin): - """ - JWT middleware для проверки токенов от Logto - """ - - def __init__(self, get_response=None): - super().__init__(get_response) - - # Audience validated only for non-introspection API calls - self.audience = getattr(settings, "LOGTO_TEAMS_AUDIENCE", None) - - def _is_introspection_query(self, request): - """Проверяет, является ли запрос introspection (для GraphQL codegen)""" - if request.method != 'POST': - return False - try: - body = json.loads(request.body.decode('utf-8')) - query = body.get('query', '') - return '__schema' in query or '__type' in query - except Exception: - return False - - def process_request(self, request): - """Обрабатывает JWT токен из заголовка Authorization""" - - # Пропускаем проверку для admin панели и статики - if request.path.startswith('/admin/') or request.path.startswith('/static/'): - return None - - # Пропускаем introspection запросы (для GraphQL codegen) - if self._is_introspection_query(request): - return None - - try: - token = get_bearer_token(request) - payload = validator.decode(token, audience=self.audience) - - request.user_id = payload.get('sub') - request.team_uuid = payload.get('team_uuid') - request.scopes = scopes_from_payload(payload) - - except InvalidTokenError: - return None - - return None diff --git a/teams_app/migrations/0001_initial.py b/teams_app/migrations/0001_initial.py deleted file mode 100644 index c275c55..0000000 --- a/teams_app/migrations/0001_initial.py +++ /dev/null @@ -1,68 +0,0 @@ -# Generated by Django 5.2.8 on 2025-12-04 08:11 - -import django.db.models.deletion -import uuid -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='Team', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('uuid', models.CharField(default=uuid.uuid4, max_length=100, unique=True)), - ('name', models.CharField(max_length=255)), - ('logto_org_id', models.CharField(blank=True, max_length=255, null=True)), - ('status', models.CharField(choices=[('PENDING_KYC', 'Требуется KYC'), ('KYC_IN_REVIEW', 'KYC на рассмотрении'), ('KYC_APPROVED', 'KYC одобрен'), ('KYC_REJECTED', 'KYC отклонен'), ('SUSPENDED', 'Заблокировано')], default='PENDING_KYC', max_length=50)), - ('prefect_flow_run_id', models.CharField(blank=True, max_length=255, null=True)), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('owner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='owned_teams', to=settings.AUTH_USER_MODEL)), - ], - options={ - 'db_table': 'teams_team', - }, - ), - migrations.CreateModel( - name='TeamInvitation', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('uuid', models.CharField(default=uuid.uuid4, max_length=100, unique=True)), - ('email', models.EmailField(max_length=254)), - ('role', models.CharField(choices=[('OWNER', 'Владелец'), ('ADMIN', 'Администратор'), ('MANAGER', 'Менеджер'), ('MEMBER', 'Участник')], default='MEMBER', max_length=50)), - ('status', models.CharField(choices=[('PENDING', 'Ожидает ответа'), ('ACCEPTED', 'Принято'), ('DECLINED', 'Отклонено'), ('EXPIRED', 'Истекло')], default='PENDING', max_length=50)), - ('invited_by', models.CharField(max_length=255)), - ('expires_at', models.DateTimeField()), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='invitations', to='teams_app.team')), - ], - options={ - 'db_table': 'teams_invitation', - 'unique_together': {('team', 'email')}, - }, - ), - migrations.CreateModel( - name='TeamMember', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('uuid', models.CharField(default=uuid.uuid4, max_length=100, unique=True)), - ('role', models.CharField(choices=[('OWNER', 'Владелец'), ('ADMIN', 'Администратор'), ('MANAGER', 'Менеджер'), ('MEMBER', 'Участник')], default='MEMBER', max_length=50)), - ('joined_at', models.DateTimeField(auto_now_add=True)), - ('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='members', to='teams_app.team')), - ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='team_memberships', to=settings.AUTH_USER_MODEL)), - ], - options={ - 'db_table': 'teams_member', - 'unique_together': {('team', 'user')}, - }, - ), - ] diff --git a/teams_app/migrations/0002_add_user_profile.py b/teams_app/migrations/0002_add_user_profile.py deleted file mode 100644 index 49e3cff..0000000 --- a/teams_app/migrations/0002_add_user_profile.py +++ /dev/null @@ -1,30 +0,0 @@ -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('teams_app', '0001_initial'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='UserProfile', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('logto_id', models.CharField(max_length=255, unique=True)), - ('avatar_id', models.CharField(blank=True, max_length=100, null=True)), - ('phone', models.CharField(blank=True, max_length=20, null=True)), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('active_team', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='active_profiles', to='teams_app.team')), - ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL)), - ], - options={ - 'db_table': 'teams_user_profile', - }, - ), - ] diff --git a/teams_app/migrations/0003_add_team_type.py b/teams_app/migrations/0003_add_team_type.py deleted file mode 100644 index c21f6f1..0000000 --- a/teams_app/migrations/0003_add_team_type.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.2.8 on 2025-12-08 09:47 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('teams_app', '0002_add_user_profile'), - ] - - operations = [ - migrations.AddField( - model_name='team', - name='team_type', - field=models.CharField(choices=[('BUYER', 'Покупатель'), ('SELLER', 'Продавец')], default='BUYER', max_length=20), - ), - ] diff --git a/teams_app/migrations/0004_teamaddress.py b/teams_app/migrations/0004_teamaddress.py deleted file mode 100644 index 153d876..0000000 --- a/teams_app/migrations/0004_teamaddress.py +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by Django 5.2.8 on 2025-12-09 03:18 - -import django.db.models.deletion -import uuid -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('teams_app', '0003_add_team_type'), - ] - - operations = [ - migrations.CreateModel( - name='TeamAddress', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('uuid', models.CharField(default=uuid.uuid4, max_length=100, unique=True)), - ('name', models.CharField(max_length=255)), - ('address', models.TextField()), - ('latitude', models.FloatField(blank=True, null=True)), - ('longitude', models.FloatField(blank=True, null=True)), - ('is_default', models.BooleanField(default=False)), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='addresses', to='teams_app.team')), - ], - options={ - 'db_table': 'teams_address', - }, - ), - ] diff --git a/teams_app/migrations/0005_remove_team_prefect_flow_run_id.py b/teams_app/migrations/0005_remove_team_prefect_flow_run_id.py deleted file mode 100644 index 4989a8b..0000000 --- a/teams_app/migrations/0005_remove_team_prefect_flow_run_id.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 5.2.8 on 2025-12-16 01:42 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('teams_app', '0004_teamaddress'), - ] - - operations = [ - migrations.RemoveField( - model_name='team', - name='prefect_flow_run_id', - ), - ] diff --git a/teams_app/migrations/0006_add_address_status_and_selected_location.py b/teams_app/migrations/0006_add_address_status_and_selected_location.py deleted file mode 100644 index 9b83b1d..0000000 --- a/teams_app/migrations/0006_add_address_status_and_selected_location.py +++ /dev/null @@ -1,59 +0,0 @@ -# Generated manually - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('teams_app', '0005_remove_team_prefect_flow_run_id'), - ] - - operations = [ - # TeamAddress fields - migrations.AddField( - model_name='teamaddress', - name='status', - field=models.CharField( - choices=[ - ('pending', 'Ожидает обработки'), - ('processing', 'Обрабатывается'), - ('ready', 'Готов'), - ('error', 'Ошибка'), - ], - default='pending', - max_length=20, - ), - ), - migrations.AddField( - model_name='teamaddress', - name='graph_node_id', - field=models.CharField(blank=True, max_length=100, null=True), - ), - migrations.AddField( - model_name='teamaddress', - name='processed_at', - field=models.DateTimeField(blank=True, null=True), - ), - migrations.AddField( - model_name='teamaddress', - name='error_message', - field=models.TextField(blank=True, null=True), - ), - # Team selected location fields - migrations.AddField( - model_name='team', - name='selected_location_type', - field=models.CharField( - blank=True, - choices=[('address', 'Адрес'), ('hub', 'Хаб')], - max_length=20, - null=True, - ), - ), - migrations.AddField( - model_name='team', - name='selected_location_uuid', - field=models.CharField(blank=True, max_length=100, null=True), - ), - ] diff --git a/teams_app/migrations/0007_teamaddress_country_code.py b/teams_app/migrations/0007_teamaddress_country_code.py deleted file mode 100644 index a015a37..0000000 --- a/teams_app/migrations/0007_teamaddress_country_code.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.2.8 on 2025-12-16 12:53 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('teams_app', '0006_add_address_status_and_selected_location'), - ] - - operations = [ - migrations.AddField( - model_name='teamaddress', - name='country_code', - field=models.CharField(blank=True, max_length=2, null=True), - ), - ] diff --git a/teams_app/migrations/0008_remove_graph_node_id_and_change_default_status.py b/teams_app/migrations/0008_remove_graph_node_id_and_change_default_status.py deleted file mode 100644 index 6b3a688..0000000 --- a/teams_app/migrations/0008_remove_graph_node_id_and_change_default_status.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated manually - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('teams_app', '0007_teamaddress_country_code'), - ] - - operations = [ - migrations.RemoveField( - model_name='teamaddress', - name='graph_node_id', - ), - migrations.AlterField( - model_name='teamaddress', - name='status', - field=models.CharField( - choices=[ - ('pending', 'Ожидает обработки'), - ('processing', 'Обрабатывается'), - ('ready', 'Готов'), - ('error', 'Ошибка') - ], - default='processing', - max_length=20 - ), - ), - ] diff --git a/teams_app/migrations/0009_alter_teamaddress_status.py b/teams_app/migrations/0009_alter_teamaddress_status.py deleted file mode 100644 index e78c897..0000000 --- a/teams_app/migrations/0009_alter_teamaddress_status.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.2.8 on 2025-12-30 02:48 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('teams_app', '0008_remove_graph_node_id_and_change_default_status'), - ] - - operations = [ - migrations.AlterField( - model_name='teamaddress', - name='status', - field=models.CharField(choices=[('pending', 'Ожидает обработки'), ('active', 'Активен'), ('error', 'Ошибка')], default='pending', max_length=20), - ), - ] diff --git a/teams_app/migrations/0010_remove_team_status.py b/teams_app/migrations/0010_remove_team_status.py deleted file mode 100644 index 4c97a8e..0000000 --- a/teams_app/migrations/0010_remove_team_status.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 5.2.8 on 2025-12-30 03:00 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('teams_app', '0009_alter_teamaddress_status'), - ] - - operations = [ - migrations.RemoveField( - model_name='team', - name='status', - ), - ] diff --git a/teams_app/migrations/0011_teaminvitationtoken.py b/teams_app/migrations/0011_teaminvitationtoken.py deleted file mode 100644 index 81e9409..0000000 --- a/teams_app/migrations/0011_teaminvitationtoken.py +++ /dev/null @@ -1,30 +0,0 @@ -# Generated by Django 5.2.8 on 2025-12-30 07:43 - -import django.db.models.deletion -import uuid -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('teams_app', '0010_remove_team_status'), - ] - - operations = [ - migrations.CreateModel( - name='TeamInvitationToken', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('uuid', models.CharField(default=uuid.uuid4, max_length=100, unique=True)), - ('token_hash', models.CharField(max_length=255, unique=True)), - ('workflow_status', models.CharField(choices=[('pending', 'Ожидает обработки'), ('active', 'Активен'), ('error', 'Ошибка')], default='pending', max_length=20)), - ('expires_at', models.DateTimeField()), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('invitation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tokens', to='teams_app.teaminvitation')), - ], - options={ - 'db_table': 'teams_invitation_token', - }, - ), - ] diff --git a/teams_app/migrations/0012_add_selected_location_details.py b/teams_app/migrations/0012_add_selected_location_details.py deleted file mode 100644 index cc2dc81..0000000 --- a/teams_app/migrations/0012_add_selected_location_details.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 5.2.8 on 2026-01-03 05:05 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('teams_app', '0011_teaminvitationtoken'), - ] - - operations = [ - migrations.AddField( - model_name='team', - name='selected_location_latitude', - field=models.FloatField(blank=True, null=True), - ), - migrations.AddField( - model_name='team', - name='selected_location_longitude', - field=models.FloatField(blank=True, null=True), - ), - migrations.AddField( - model_name='team', - name='selected_location_name', - field=models.CharField(blank=True, max_length=255, null=True), - ), - ] diff --git a/teams_app/migrations/__init__.py b/teams_app/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/teams_app/migrations/__pycache__/0001_initial.cpython-313.pyc b/teams_app/migrations/__pycache__/0001_initial.cpython-313.pyc deleted file mode 100644 index 7ccbe3a04f6ca52701d590f7b1f875b575cfb2a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4448 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 diff --git a/teams_app/migrations/__pycache__/0004_teamaddress.cpython-313.pyc b/teams_app/migrations/__pycache__/0004_teamaddress.cpython-313.pyc deleted file mode 100644 index 3aa9c136d404b245d4f17cb6ca40b1dcb5845edb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1964 zcma)7%}*Og6rWw&Ywu#nnr{=Z2|`s&krxH5im0l}m(xN+C6*wOQjON^;A~lTo!MOy za;j9R=UgK3FZ4!E;h1BNwtFy|9$KjnD%RBSl`^}r*`oFReM5Aa5>5(y{NB5#z z$@bc7Lm|=J*T!2Y@OTF%_H3wS^ev%&76N}LWQI`SN-wn5?Yz^Pk>k6#yS&YESHi;?0l(SG5xka&NHnk`h=dD6ZGt21gbuyPtxJ? zo!k_YA9niZG64>tqhy~LM;X79Mqc(_anDkcx3WlMySfsI9Z9+=$TnRqYy zJ|rv8XAp(#Id z&q`RFhy0eHQLafYTjeDvTajPzN#hEsN#XqF%WJT-7zvG~f8zOuBs#uT?gIycx5#-0z= z+=s;b)G7r&@i3+z1Dh-OBlfNK2ztrWXy8GiOU9u^jsA%dI!>XzicdQiI-J2>ZHS&3xsAO0Y-x;%C8|6A=0lH6+w@v`v8vv`NR6Eq8{@O}@!6lp^Ho*5NZmf&X-wqn6Zy04x6#_fT2(Dx zq{dGV8X2vg(ay}bgSAYtsy?_#O`IM#viIuQd*_8(cB!f^w^j4?>^z{d*HBz_zFo^M zSJjm^jhT9S=4|K9?(5w~VXanJYZNwXh0R7`r&idhl1dYyW1%R%M`-MU2tw)$u{qQ; z*w-9GK=EtH%TV9@iIl7~BLn@?59{>vP6~5zmTpx(Z)-qjIM$RwL#t#yqXa~5UwO7-1!Cd{EF`WA*BWBrP5HRYwGl$ I2!znb->nh;lmGw# diff --git a/teams_app/migrations/__pycache__/0005_remove_team_prefect_flow_run_id.cpython-313.pyc b/teams_app/migrations/__pycache__/0005_remove_team_prefect_flow_run_id.cpython-313.pyc deleted file mode 100644 index c618b35801731540c14bc81ce20d44234931d91d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 723 zcmZuvzi-qq7`5}ON!k+!1qui%KowFzYHpwd2z6vA<%WycPWt3a+*7#x>gU{5Y)DAV zEd3+c_*YsQhbJn2HS1R#9? zC7EVi;SGS}Da*7>v1jR#bGyXc|St9+i;#cX& zTL7X~NyWhG8q?9V<^lja%Cyjzm&f5d!BK=b6&Wi=Y?AU>cv9j-R4nFUS=Hq%W#Nd$ z6V+3MO#*GzIfSd12vs6`fXzXgVBkMd>{cI8zfx0ls^Xa{pUK=I-qX2h+;l!3&VAx- zp1IpU-0kzN2j|zH{IX5YpPTj#=hFe+Ub_2%DZS)9E5_w+GHP;YKdmp<%C;1e?yEM~ meY~rv`ZtNVugct{lwLZ7KKkvfQ|F6+*4_Eu-MJ)+H10nqPQT~? diff --git a/teams_app/migrations/__pycache__/0006_add_address_status_and_selected_location.cpython-313.pyc b/teams_app/migrations/__pycache__/0006_add_address_status_and_selected_location.cpython-313.pyc deleted file mode 100644 index 769f700eed634509f4f0b3f1345c3cb5ddffa8b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1809 zcmbVMOK;p%6uy4U!}Dk|&ZC*66=8^qyom!MNRc2CqEsT3O5~=yNLQZm&5Vi1HrICA zuxf*ZkXTR&vF#42>?T!{yp+jI zYRg*gfGe7ql)6@%8G+?GevT7MO%ZU10KRZn<(c zAd{gL3CpX6<>8BLI>Nax1f0hOTwIW_vLIcOrSz&SxQr|CR9~Cn3S>|(>I0(7cxXX< zO$WmeKl;DpYgoNxf)PBbi-1EJk1fcT_EE#*m*hEvgq~+*e3ez&6Iwk{J|FD&fO7&i zt_0NR`o!?OWM*z|Zk{mObvG#CpNYrl8f^t+&35k*7COW-lQOp$rpc%e9PtAq2z^b4 zOa+fRrscH5Hz9NMIQli(iJnEh=y|*~9qmTj@dHq{quqEb`YqbwWb>HYf-F4dS{5^K z>cv~}_tDcVI(``c0PZ%rKoeOVOl*?dt7(6v3zHgcNYC+0#(io7vfypIt@OZ= zVAG=<#uIF_K_5lW0JrDyL$FAluo?2TML%;SH90F%bmzzz>S4*9iMSaHajimUIY2M-hF`28% z#~p*EdQ!b<1a!sf(o9uW==~rQORh%;cgq+doH5)2 z^K};bfOOMXx9Em`&t>brXSAs9dV#xP8G6%btwU?Rp0YT5b1v(r_m~c>exCrS{Nbcc zD~CXN$0RRpVbq-y5ml zjXm|ola(DgRzJMZ>uk0j+eSIeG*OFf;RhO^&=(6J5`{A z(K8*Ki~3KecLiO|f3w792Uy+FcBcEux})lqgGv)?ENqLX{8_l}hQ5gDui=v9GBc$2NC%p&Jqs zGfV#iY>cq+7uu!OtxVa10%GMor%^g!>0Uq2y&rzx=g#AW1rNb9__`Z?#|Zt@Wct{b zV7vw31QA5=bF_m6-Z6x+ik49W5#tsjW(T*OY0~Wdz?@)V_N^*gEKFkfSXdpqUA>wx!O)6Htj=7!_Ftb(9AcBX zO_NkMO{n4$S9m?IHLu(k(|(3}2I$buIU7jIvP`XQY-~KFEDZG$TuLf)mKWemLMnO8 zgPeynPJ?nFHLo)-BULp>izFAvG=L#r4h>!0RCYIJNgq^T?`X`EUVfmgq=;j1d8HaO zVFM0(+S>aOkHar$5BjXo(nG28D22!(=76h|zA0F&qk&zcbUzX@kE4Vqsdk4v<4MSq zAmUQ!^H7y1Vfaj!6_%#%(*q_-uDmqk)04SD%SoevvOE`2x5&AqR4hWu7#328{wv9a z^hF_Ipf2l2{K$WsioVQP!2LAK)1!#_T^97A0qK{TPOMhepWOl&! zg+7vb7mI9TsOg^cnoy6V+q$-amvTuo1pzyOG fc^k~g#2Ei|5N`c;s@VDDo!6SDwdNlLq|E*Y=;G=! diff --git a/teams_app/migrations/__pycache__/0008_remove_graph_node_id_and_change_default_status.cpython-313.pyc b/teams_app/migrations/__pycache__/0008_remove_graph_node_id_and_change_default_status.cpython-313.pyc deleted file mode 100644 index 8dc1efd3467586e6a28eba270bed48fb24700951..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1133 zcmY*XL2ukd6dv2V-nDl(q?;lVAXNw{k}q{GsEq`b5E6#~k%+}@rP0Km?7H#V=8YYi zTbd$-!~rDKYtL{?DnJ#7{02LhM04eo+lGJ;H{N(-EsQj8zW3g|dGCGmu6sS3;QHss zt?+$=kl&S3ujUQ7eu&^1@rb8=Og1&pHg(Wf$Rb%Kp8h)VjDfao)kX zUc+l{=;)uD*=tn!%|Uy+Ut4D9DshR|`b_iMp5@sahS%9JTpet$3!P!lnUmJ1bEPG5N9uKpTV}J^V9tzpq4S5v&M7Er+Y}2Y& zN~KLH{(c^D#9d0i$XTTNN9`3#cS8_a6vjMGlsn*x2p;<(7oes}cDDIA+2?oSN;wt4u;#3t6ldHc>;`_9E{YZtdxu9}8rPui7r z`K-NMS(h&Qi|75-v;OKIdUL5i>5`?p7jGr%NGo`R zRVDX=or>d%%4tE0q3PW*y?*>>11blW=9F5rn^ zVmxx;%H10nF@!|U9=lv1y?Wxdh{mgbS~hTSlKJ!h{Qqa(|L>pm_v;AO$`8wZAS3is z7`;_ISI(wE*+dqyq!(yLV$zJv7!#%H@Py2PleFsFmgi z{^v81ReUX3s#UVeQ;MZcDe#hJ=}d3*8I@Ffww2;Z- zf=fN;GnzB{(lX9G7^gbM5E*+E^a{rBV&aKtu&!df;4&V0u220yxE(6Wq`vJ^&cqm` z`cp5W?74WD6~u-1tVwb^)q{}sM&dfoTIkxCL=kiAaYQ-B>;|Nq!A9w#`G!-*O%`*H z_;s@6(zdxAuq7T6o0>rw1#Op@bz(081a4+T=2FmUUW}g!#7z&>sz{rax{5rcuD$H)NE&6ALfigsyT}=OTmOw&w7^iDaRnn&tt{dq~#|$ n6VvP-m=bJ$2SitqBbOg=c&foEV8G}F zoFIYj!EJZ|*t!GQ9-@J>Dp)@s+Z`6x#EIMsLn5TYoKFO;d0EKuS_|;6(Xq~+!Vm<) zAS{f8jjb37XXp;L{x9gT9>K;Ac8`o^1AD@sY(%~aUah)Zcv=`)DySLFC81TN_L3wy zA~dU+ASO%GR4^%ttZ6-y$}u_Rbxc==d6}||6f|ebG4UJpqd@tjO%b9(LbPO-F^#tf zc{ih(k!f~?kT+b&I^zW^O7l8p6)RF!j5(9S7^F4_EHCHmIcHg_!m?sZchpVNPQ=HA z*0tcHS*4$@k(^y0AkD9pvQ!5AqY>hJ{`4}vF+ZQbxby=+1VuAlk)KmGml zoxSs`yT4sK2pikI=6ya9w^r5t$W}r6mKKxpFden4cb_)e;r@>uL@s((k2 fcXeoNgwUl2=>8vX6M0|5v+aW)+Xt7RNn8CFqk+2! diff --git a/teams_app/migrations/__pycache__/0011_teaminvitationtoken.cpython-313.pyc b/teams_app/migrations/__pycache__/0011_teaminvitationtoken.cpython-313.pyc deleted file mode 100644 index f4f2c106ea28632abcac962e436d44e154c357bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1930 zcmZ`)O-vg{6rSC+*FS)l=LMYy44z?wcMZwPi zqDxfK4#XSHNuZGe zjWeftDa6($PRiF}r^qHxkxiYHX=B>Bc1Gl$4QXe!b90h*KBquchO`MfTux^ud1SR$ z-~BK+fQm<4Y*ZcHsMUCCZtmioPI1+)V_k@K$2DBf;lp`gu3L2iEVM@6-ozG{iJ4#K z^7U((0PiUcpw`-QcQck-Hw|QC9@iHw5#wv+3q~#lF`~ zHlx6yLN#oe#439iK!rVJKeAo+1KVcL8jmK~3%1jE2+R(9(Rjq3vt2Myjgm|1*c0fp z$Lu+5?6U9KGxiH?1~H{J^~5b=Pa9vu&JLJu({T{&i%i4;N*gvQVTTR_@2AJ3_eUIe~G*1#9(B8h1x2L zTx=_HQhj){9YvAhR(PTrp4dyg{byq2alMtAX{Kg&1Fxpp9i3UUk#bnv-AkmNjJC!z z&GF3k^iMN8Gp~l(?N1xycUb(hy~Oz^^;SCDOlNm5y>uJtn=HP%mzer?xivlCoSy$1 zp{qo0Ljv*_V!5uYD6bKE>!t!sVpZwdUuvc={g%GW;#ZCdUM3sqWfuRqE1GMj=XS6B zn)^A|T3Bf;th5&LjfH$`q0m?;uuTX2ZAqF8&L{ICQsTDU9t(Q9mg$IXg8krC7ftH8B@T#wQjO=;vmp z7bTWt=I0gb$H!;pWtPOp>lIYq;;_lhPbtkwwJTx;+5&P#F^KVznURsPh#ANN0A2ns A*Z=?k diff --git a/teams_app/models.py b/teams_app/models.py deleted file mode 100644 index 32bab42..0000000 --- a/teams_app/models.py +++ /dev/null @@ -1,165 +0,0 @@ -from django.conf import settings -from django.db import models -import uuid - -class Team(models.Model): - TEAM_TYPE_CHOICES = [ - ('BUYER', 'Покупатель'), - ('SELLER', 'Продавец'), - ] - - LOCATION_TYPE_CHOICES = [ - ('address', 'Адрес'), - ('hub', 'Хаб'), - ] - - uuid = models.CharField(max_length=100, unique=True, default=uuid.uuid4) - name = models.CharField(max_length=255) - team_type = models.CharField(max_length=20, choices=TEAM_TYPE_CHOICES, default='BUYER') - logto_org_id = models.CharField(max_length=255, null=True, blank=True) - owner = models.ForeignKey( - settings.AUTH_USER_MODEL, - on_delete=models.CASCADE, - related_name='owned_teams', - null=True, - blank=True, - ) - selected_location_type = models.CharField(max_length=20, choices=LOCATION_TYPE_CHOICES, null=True, blank=True) - selected_location_uuid = models.CharField(max_length=100, null=True, blank=True) - selected_location_name = models.CharField(max_length=255, null=True, blank=True) - selected_location_latitude = models.FloatField(null=True, blank=True) - selected_location_longitude = models.FloatField(null=True, blank=True) - created_at = models.DateTimeField(auto_now_add=True) - updated_at = models.DateTimeField(auto_now=True) - - class Meta: - db_table = 'teams_team' - - def __str__(self): - return f"Team {self.name}" - - -class UserProfile(models.Model): - user = models.OneToOneField( - settings.AUTH_USER_MODEL, - on_delete=models.CASCADE, - related_name='profile' - ) - logto_id = models.CharField(max_length=255, unique=True) - avatar_id = models.CharField(max_length=100, blank=True, null=True) - phone = models.CharField(max_length=20, blank=True, null=True) - active_team = models.ForeignKey(Team, on_delete=models.SET_NULL, null=True, blank=True, related_name='active_profiles') - created_at = models.DateTimeField(auto_now_add=True) - updated_at = models.DateTimeField(auto_now=True) - - class Meta: - db_table = 'teams_user_profile' - - def __str__(self): - return f"Profile {self.logto_id}" - -class TeamMember(models.Model): - ROLE_CHOICES = [ - ('OWNER', 'Владелец'), - ('ADMIN', 'Администратор'), - ('MANAGER', 'Менеджер'), - ('MEMBER', 'Участник'), - ] - - uuid = models.CharField(max_length=100, unique=True, default=uuid.uuid4) - team = models.ForeignKey(Team, on_delete=models.CASCADE, related_name='members') - user = models.ForeignKey( - settings.AUTH_USER_MODEL, - on_delete=models.CASCADE, - related_name='team_memberships', - null=True, - blank=True, - ) - role = models.CharField(max_length=50, choices=ROLE_CHOICES, default='MEMBER') - joined_at = models.DateTimeField(auto_now_add=True) - - class Meta: - db_table = 'teams_member' - unique_together = ['team', 'user'] - - def __str__(self): - return f"{self.team.name} - {self.user} ({self.role})" - -class TeamInvitation(models.Model): - INVITATION_STATUS_CHOICES = [ - ('PENDING', 'Ожидает ответа'), - ('ACCEPTED', 'Принято'), - ('DECLINED', 'Отклонено'), - ('EXPIRED', 'Истекло'), - ] - - ROLE_CHOICES = TeamMember.ROLE_CHOICES - - uuid = models.CharField(max_length=100, unique=True, default=uuid.uuid4) - team = models.ForeignKey(Team, on_delete=models.CASCADE, related_name='invitations') - email = models.EmailField() - role = models.CharField(max_length=50, choices=ROLE_CHOICES, default='MEMBER') - status = models.CharField(max_length=50, choices=INVITATION_STATUS_CHOICES, default='PENDING') - invited_by = models.CharField(max_length=255) - expires_at = models.DateTimeField() - created_at = models.DateTimeField(auto_now_add=True) - - class Meta: - db_table = 'teams_invitation' - unique_together = ['team', 'email'] - - def __str__(self): - return f"Приглашение в {self.team.name} для {self.email}" - - -class TeamInvitationToken(models.Model): - WORKFLOW_STATUS_CHOICES = [ - ('pending', 'Ожидает обработки'), - ('active', 'Активен'), - ('error', 'Ошибка'), - ] - - uuid = models.CharField(max_length=100, unique=True, default=uuid.uuid4) - invitation = models.ForeignKey(TeamInvitation, on_delete=models.CASCADE, related_name='tokens') - token_hash = models.CharField(max_length=255, unique=True) - workflow_status = models.CharField( - max_length=20, - choices=WORKFLOW_STATUS_CHOICES, - default='pending', - ) - expires_at = models.DateTimeField() - created_at = models.DateTimeField(auto_now_add=True) - - class Meta: - db_table = 'teams_invitation_token' - - def __str__(self): - return f"Token {self.uuid} for invitation {self.invitation_id}" - - -class TeamAddress(models.Model): - ADDRESS_STATUS_CHOICES = [ - ('pending', 'Ожидает обработки'), - ('active', 'Активен'), - ('error', 'Ошибка'), - ] - - uuid = models.CharField(max_length=100, unique=True, default=uuid.uuid4) - team = models.ForeignKey(Team, on_delete=models.CASCADE, related_name='addresses') - name = models.CharField(max_length=255) # "Офис", "Склад", "Производство" - address = models.TextField() - latitude = models.FloatField(null=True, blank=True) - longitude = models.FloatField(null=True, blank=True) - country_code = models.CharField(max_length=2, null=True, blank=True) # ISO 3166-1 alpha-2 - is_default = models.BooleanField(default=False) - status = models.CharField(max_length=20, choices=ADDRESS_STATUS_CHOICES, default='pending') - processed_at = models.DateTimeField(null=True, blank=True) - error_message = models.TextField(null=True, blank=True) - created_at = models.DateTimeField(auto_now_add=True) - updated_at = models.DateTimeField(auto_now=True) - - class Meta: - db_table = 'teams_address' - - def __str__(self): - return f"{self.team.name} - {self.name}" diff --git a/teams_app/permissions.py b/teams_app/permissions.py deleted file mode 100644 index d44f02d..0000000 --- a/teams_app/permissions.py +++ /dev/null @@ -1,74 +0,0 @@ -""" -Декоратор для проверки scopes в JWT токене. -Используется для защиты GraphQL резолверов. -""" -from functools import wraps -from graphql import GraphQLError - - -def require_scopes(*scopes: str): - """ - Декоратор для проверки наличия scopes в JWT токене. - - Использование: - @require_scopes("read:teams") - def resolve_team(self, info): - ... - - @require_scopes("read:teams", "write:teams") - def resolve_update_team(self, info): - ... - """ - def decorator(func): - # Сохраняем scopes в метаданных для возможности сбора всех scopes - if not hasattr(func, '_required_scopes'): - func._required_scopes = [] - func._required_scopes.extend(scopes) - - @wraps(func) - def wrapper(self, info, *args, **kwargs): - # Получаем scopes из контекста (должны быть добавлены в middleware) - user_scopes = set(getattr(info.context, 'scopes', []) or []) - - missing = set(scopes) - user_scopes - if missing: - raise GraphQLError(f"Missing required scopes: {', '.join(missing)}") - - return func(self, info, *args, **kwargs) - - # Переносим метаданные на wrapper - wrapper._required_scopes = func._required_scopes - return wrapper - return decorator - - -def collect_scopes_from_schema(schema) -> set: - """ - Собирает все scopes из схемы для синхронизации с Logto. - - Использование: - from .schema import schema - scopes = collect_scopes_from_schema(schema) - # {'read:team', 'invite:member', ...} - """ - scopes = set() - - # Query resolvers - if hasattr(schema, 'query') and schema.query: - query_type = schema.query - for field_name in dir(query_type): - if field_name.startswith('resolve_'): - resolver = getattr(query_type, field_name, None) - if resolver and hasattr(resolver, '_required_scopes'): - scopes.update(resolver._required_scopes) - - # Mutation resolvers - if hasattr(schema, 'mutation') and schema.mutation: - mutation_type = schema.mutation - for field_name, field in mutation_type._meta.fields.items(): - if hasattr(field, 'type') and hasattr(field.type, 'mutate'): - mutate = field.type.mutate - if hasattr(mutate, '_required_scopes'): - scopes.update(mutate._required_scopes) - - return scopes diff --git a/teams_app/schemas/__pycache__/m2m_schema.cpython-313.pyc b/teams_app/schemas/__pycache__/m2m_schema.cpython-313.pyc deleted file mode 100644 index 0e7a60ffaa98918a7bb8c2b28b5aff7a46f36b04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18693 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 b2JmCvK_I>!zZ$=F?5- Tuple[str, str]: - """ - Start the team_created workflow in Temporal and return (workflow_id, run_id). - """ - client = await Client.connect(TEMPORAL_ADDRESS, namespace=TEMPORAL_NAMESPACE) - - # We re-use team.uuid as workflow_id to keep idempotency. - handle = await client.start_workflow( - "team_created_workflow", # workflow name registered in worker - { - "team_id": team.uuid, - "team_name": team.name, - "owner_id": getattr(getattr(team.owner, "profile", None), "logto_id", "") or getattr(team.owner, "username", ""), - "logto_org_id": team.logto_org_id or "", - }, - id=team.uuid, - task_queue=TEMPORAL_TASK_QUEUE, - ) - return handle.id, handle.run_id - - -def start_team_created(team: Team) -> Tuple[str, str]: - """ - Sync wrapper for Django mutation handlers. - """ - try: - return asyncio.run(_start_team_created_async(team)) - except Exception: - logger.exception("Failed to start Temporal workflow for team %s", team.uuid) - raise - - -async def _start_address_workflow_async( - team_uuid: str, - name: str, - address: str, - latitude: float | None = None, - longitude: float | None = None, - country_code: str | None = None, - is_default: bool = False, -) -> Tuple[str, str]: - """ - Start the create_address workflow in Temporal. - Returns (workflow_id, run_id). - """ - client = await Client.connect(TEMPORAL_ADDRESS, namespace=TEMPORAL_NAMESPACE) - - workflow_id = f"address-{uuid.uuid4()}" - - handle = await client.start_workflow( - "create_address", - { - "workflow_id": workflow_id, - "team_uuid": team_uuid, - "name": name, - "address": address, - "latitude": latitude, - "longitude": longitude, - "country_code": country_code, - "is_default": is_default, - }, - id=workflow_id, - task_queue=TEMPORAL_TASK_QUEUE, - ) - - logger.info("Started address workflow %s for team %s", workflow_id, team_uuid) - return handle.id, handle.result_run_id - - -def start_address_workflow( - team_uuid: str, - name: str, - address: str, - latitude: float | None = None, - longitude: float | None = None, - country_code: str | None = None, - is_default: bool = False, -) -> Tuple[str, str]: - """ - Sync wrapper for starting address workflow. - """ - try: - return asyncio.run(_start_address_workflow_async( - team_uuid=team_uuid, - name=name, - address=address, - latitude=latitude, - longitude=longitude, - country_code=country_code, - is_default=is_default, - )) - except Exception: - logger.exception("Failed to start address workflow for team %s", team_uuid) - raise - - -async def _start_invite_workflow_async( - team_uuid: str, - email: str, - role: str, - invited_by: str, - expires_at: str, -) -> Tuple[str, str]: - """ - Start the invite_user workflow in Temporal. - Returns (workflow_id, run_id). - """ - client = await Client.connect(TEMPORAL_ADDRESS, namespace=TEMPORAL_NAMESPACE) - - workflow_id = f"invite-{uuid.uuid4()}" - - handle = await client.start_workflow( - "invite_user", - { - "team_uuid": team_uuid, - "email": email, - "role": role, - "invited_by": invited_by, - "expires_at": expires_at, - }, - id=workflow_id, - task_queue=TEMPORAL_TASK_QUEUE, - ) - - logger.info("Started invite workflow %s for %s", workflow_id, email) - return handle.id, handle.result_run_id - - -def start_invite_workflow( - team_uuid: str, - email: str, - role: str, - invited_by: str, - expires_at: str, -) -> Tuple[str, str]: - """ - Sync wrapper for starting invite workflow. - """ - try: - return asyncio.run(_start_invite_workflow_async( - team_uuid=team_uuid, - email=email, - role=role, - invited_by=invited_by, - expires_at=expires_at, - )) - except Exception: - logger.exception("Failed to start invite workflow for %s", email) - raise diff --git a/teams_app/tests.py b/teams_app/tests.py deleted file mode 100644 index acf7551..0000000 --- a/teams_app/tests.py +++ /dev/null @@ -1,98 +0,0 @@ -from django.test import TestCase -from graphene.test import Client -from teams_app.schema import schema - -class TeamsGraphQLTestCase(TestCase): - def setUp(self): - self.client = Client(schema) - - def test_get_user_teams_with_params(self): - """Тест getUserTeams с userId""" - query = ''' - { - getUserTeams(userId: "demo-user") { - id - name - ownerId - logtoOrgId - createdAt - updatedAt - } - } - ''' - result = self.client.execute(query) - print(f"\n=== getUserTeams WITH PARAMS ===") - print(f"Result: {result}") - - if result.get('errors'): - print(f"ERRORS: {result['errors']}") - - if result.get('data'): - teams = result['data']['getUserTeams'] - print(f"Found {len(teams)} teams") - for team in teams: - print(f"Team: {team.get('name')} - {team.get('id')}") - - # Проверки - self.assertIsNone(result.get('errors')) - self.assertIn('getUserTeams', result['data']) - - def test_get_user_teams_no_params(self): - """Тест getUserTeams без параметров""" - query = ''' - { - getUserTeams { - id - name - } - } - ''' - result = self.client.execute(query) - print(f"\n=== getUserTeams NO PARAMS ===") - print(f"Result: {result}") - - if result.get('errors'): - print(f"ERRORS: {result['errors']}") - - if result.get('data'): - teams = result['data']['getUserTeams'] - print(f"Found {len(teams)} teams") - - def test_schema_fields(self): - """Тест что схема содержит нужные поля""" - query = ''' - { - __type(name: "Team") { - fields { - name - type { - name - } - } - } - } - ''' - result = self.client.execute(query) - print(f"\n=== TEAM SCHEMA FIELDS ===") - - if result.get('data') and result['data']['__type']: - fields = result['data']['__type']['fields'] - field_names = [f['name'] for f in fields] - print(f"Team fields: {field_names}") - - required_fields = ['id', 'name', 'ownerId'] - for field in required_fields: - if field in field_names: - print(f"✅ {field} - OK") - else: - print(f"❌ {field} - MISSING") - - def test_invalid_query(self): - """Тест неправильного запроса""" - query = '{ nonExistentField }' - result = self.client.execute(query) - print(f"\n=== INVALID QUERY TEST ===") - print(f"Result: {result}") - - # Должна быть ошибка - self.assertIsNotNone(result.get('errors')) diff --git a/teams_app/views.py b/teams_app/views.py deleted file mode 100644 index 3effa15..0000000 --- a/teams_app/views.py +++ /dev/null @@ -1,97 +0,0 @@ -import json -import jwt -from django.conf import settings -from django.http import JsonResponse -from django.views.decorators.csrf import csrf_exempt -from jwt import InvalidTokenError - -from .auth import get_bearer_token, scopes_from_payload, validator - - -@csrf_exempt -def test_jwt(request): - """Тестовый endpoint для проверки JWT токена с подписью.""" - - try: - token = get_bearer_token(request) - except InvalidTokenError as exc: - return JsonResponse({"status": "error", "error": str(exc)}, status=403) - - response = {"token_length": len(token), "token_preview": f"{token[:32]}...{token[-32:]}"} - - try: - audience = getattr(settings, "LOGTO_TEAMS_AUDIENCE", None) - payload = validator.decode(token, audience=audience) - response.update( - { - "status": "ok", - "header": jwt.get_unverified_header(token), - "payload": payload, - "user_id": payload.get("sub"), - "team_uuid": payload.get("team_uuid"), - "scopes": scopes_from_payload(payload), - } - ) - return JsonResponse(response, json_dumps_params={"indent": 2}) - except InvalidTokenError as exc: - response["status"] = "invalid" - response["error"] = str(exc) - return JsonResponse(response, status=403, json_dumps_params={"indent": 2}) - - -# GraphQL Views - authentication handled by GRAPHENE MIDDLEWARE - -from graphene_django.views import GraphQLView - -from .graphql_middleware import ( - M2MNoAuthMiddleware, - PublicNoAuthMiddleware, - TeamJWTMiddleware, - UserJWTMiddleware, -) - - -def _is_introspection_query(request): - """Проверяет, является ли запрос introspection (для GraphQL codegen)""" - if request.method != 'POST': - return False - try: - body = json.loads(request.body.decode('utf-8')) - query = body.get('query', '') - return '__schema' in query or '__type' in query - except Exception: - return False - - -class PublicGraphQLView(GraphQLView): - """GraphQL view for public operations (no authentication).""" - - def __init__(self, *args, **kwargs): - kwargs['middleware'] = [PublicNoAuthMiddleware()] - super().__init__(*args, **kwargs) - - -class UserGraphQLView(GraphQLView): - """GraphQL view for user-level operations (ID Token).""" - - def __init__(self, *args, **kwargs): - kwargs['middleware'] = [UserJWTMiddleware()] - super().__init__(*args, **kwargs) - - -class TeamGraphQLView(GraphQLView): - """GraphQL view for team-level operations (Access Token).""" - - def __init__(self, *args, **kwargs): - kwargs['middleware'] = [TeamJWTMiddleware()] - super().__init__(*args, **kwargs) - - -class M2MGraphQLView(GraphQLView): - """GraphQL view for M2M (machine-to-machine) operations. - No authentication required - used by internal services (Temporal, etc.) - """ - - def __init__(self, *args, **kwargs): - kwargs['middleware'] = [M2MNoAuthMiddleware()] - super().__init__(*args, **kwargs) diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..6e3ad2c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "Node16", + "moduleResolution": "Node16", + "outDir": "dist", + "rootDir": "src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "declaration": true, + "sourceMap": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +}