From 44bb9264d86af4156ee21920bc629541e218fcb8 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 12:29:25 +0200 Subject: [PATCH 001/410] docs: add JSON:API, Typer --- backend/docs/index.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/backend/docs/index.md b/backend/docs/index.md index 79beafc8..aff785cf 100644 --- a/backend/docs/index.md +++ b/backend/docs/index.md @@ -5,9 +5,12 @@ [![coverage](./tests/coverage/coverage.svg)](./tests/coverage/index.html) -kwai API is the backend for the kwai sports club management system. +This is the backend for the kwai sports club management system. This system +contains a [JSON:API](https://jsonapi.org/) REST API, a CLI and an event bus. -All server side code is written with Python using [FastAPI](https://fastapi.tiangolo.com/) as web framework. +All server side code is written with Python using [FastAPI](https://fastapi.tiangolo.com/) for the REST API +and [Typer](https://typer.tiangolo.com/) for the CLI. +Currently, the event bus is custom code. ## Install From 148cfce1713ac5713f64ae037cb2b1d0a7050900 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 12:37:58 +0200 Subject: [PATCH 002/410] docs: add note about backend as working directory --- backend/docs/index.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/docs/index.md b/backend/docs/index.md index aff785cf..82e25062 100644 --- a/backend/docs/index.md +++ b/backend/docs/index.md @@ -90,8 +90,10 @@ The backend is written in Python. The following tools are used to develop kwai: There are pre-commit hooks defined for formatting and linting the code. Use Poetry to create the pre-commit hooks: +> Use the backend folder as working directory for the poetry commands. + ```` -poetry -C ./backend/src/pyproject.toml pre-commit install +poetry run pre-commit install ```` ### Testing From 7e370e77f0029408189ed3225abf30ee420134e3 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 12:38:27 +0200 Subject: [PATCH 003/410] ci: add /backend/.venv/ to git ignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 757d1347..74f677fb 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ __pycache__ /frontend/apps/portal/images/*.jpg *.tsbuildinfo stats.html +/backend/.venv/ From f55779259c948a832afe96c7ea7703357031a7dc Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 17:13:33 +0200 Subject: [PATCH 004/410] ci: move poetry to backend folder --- backend/{src => }/poetry.lock | 0 backend/{src => }/poetry.toml | 0 backend/{src => }/pyproject.toml | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename backend/{src => }/poetry.lock (100%) rename backend/{src => }/poetry.toml (100%) rename backend/{src => }/pyproject.toml (100%) diff --git a/backend/src/poetry.lock b/backend/poetry.lock similarity index 100% rename from backend/src/poetry.lock rename to backend/poetry.lock diff --git a/backend/src/poetry.toml b/backend/poetry.toml similarity index 100% rename from backend/src/poetry.toml rename to backend/poetry.toml diff --git a/backend/src/pyproject.toml b/backend/pyproject.toml similarity index 100% rename from backend/src/pyproject.toml rename to backend/pyproject.toml From bcf780e05aefd540e7a8a493722a6d48847fb877 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 17:20:51 +0200 Subject: [PATCH 005/410] ci: add mermaid plugin --- mkdocs.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mkdocs.yml b/mkdocs.yml index 2fe8bc92..b69937dd 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -34,6 +34,11 @@ markdown_extensions: toc_depth: 4 - admonition - codehilite + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format plugins: - monorepo From f4ea17caa3b9b9a6f5e0383fc66d3c3778f7362e Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 17:21:17 +0200 Subject: [PATCH 006/410] docs: update path to commands --- backend/docs/cli.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/backend/docs/cli.md b/backend/docs/cli.md index fbc2aece..466b642d 100644 --- a/backend/docs/cli.md +++ b/backend/docs/cli.md @@ -1,10 +1,10 @@ # Command Line Interface -A command line interface (CLI) is provided to help managing the kwai system. To run the cli, use the kwai_cli.py +A command line interface (CLI) is provided to help managing the kwai system. To run the cli, use the kwai_cli.py script: `kwai_cli.py --help` -::: kwai.cli.bus +::: kwai.cli.commands.bus options: show_root_full_path: False show_signature: False @@ -12,7 +12,7 @@ script: - show - test -::: kwai.cli.db +::: kwai.cli.commands.db options: show_root_full_path: False show_signature: False @@ -20,10 +20,9 @@ script: - show - test -::: kwai.cli.identity +::: kwai.cli.commands.identity options: show_root_full_path: False show_signature: False members: - create - From b37759d4b9b5a1239f541212b603e8a773c3dfe5 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 17:21:43 +0200 Subject: [PATCH 007/410] docs: start writing about the architecture --- backend/docs/architecture.md | 51 ++++++++++++++++++++++++++++++++++++ backend/mkdocs.yml | 1 + 2 files changed, 52 insertions(+) create mode 100644 backend/docs/architecture.md diff --git a/backend/docs/architecture.md b/backend/docs/architecture.md new file mode 100644 index 00000000..caf63a18 --- /dev/null +++ b/backend/docs/architecture.md @@ -0,0 +1,51 @@ +Architecture +============ + +Kwai tries to follow the [clean architecture](http://cleancoder.com) principles. The [frontend]() is already a +separated layer. The backend code is using the domain driven design (DDD) for modeling the software. + +One of the rules of clean architecture is that when you don't own or control something, then keep it on the +outside of your design or wrap it. This means for example, that the domain code isn't allowed to contain FastAPI code +or database related code. The code for the API is on the outside because it's the entry point of a call to the system. +Presenters are not used yet, but they will be introduced in an upcoming version. The repository pattern keeps the +database code on the outside. Interfaces are used to protect the inside from the outside. + +The [pendulum](https://pendulum.eustace.io/) library is used for processing dates and timestamps. Because kwai doesn't +own this code, the pendulum code is wrapped into value objects (Timestamp, Date, ...). If the pendulum package is +outdated, we only need to change these value objects. + +> This is also the reason why [Pydantic](https://docs.pydantic.dev/latest/) isn't used for entities or value objects. +> Pydantic is great for validation and serialization, but we don't want Pydantic to become a dependency of the kwai +> domain. + +Dependency injection containers are only used on the outside. There should not be any magic code in the domain. +So, dependency injection can only be used in the API entry code, the CLI entry code, ... From there on, the dependency +should be passed as an argument (and passing it down should be done using an interface). + +Actors +====== + +Visitor +------- + +Member +------ + +Coach +----- + +A coach is a member of the club. A coach can create/view/update/delete trainings. A coach can also registers +participants for a training. When participants are registered, a training can't be deleted anymore. + +````mermaid +sequenceDiagram + actor Coach + Coach->>Trainings: View + Coach->>Trainings: Create + Coach->>Trainings: Update + Coach->>Trainings: Delete + Coach->>Trainings: Register participants +```` + +Admin +----- diff --git a/backend/mkdocs.yml b/backend/mkdocs.yml index 9c13b578..0f7c7a3c 100644 --- a/backend/mkdocs.yml +++ b/backend/mkdocs.yml @@ -4,6 +4,7 @@ docs_dir: docs nav: - index.md + - architecture.md - API: - auth: api/api_auth.md - cli.md From 19b9f411889cbf797e51d6edbab0cea6dd4233c8 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 17:33:03 +0200 Subject: [PATCH 008/410] refactor: rename test into preview --- backend/src/kwai/modules/club/import_members.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/src/kwai/modules/club/import_members.py b/backend/src/kwai/modules/club/import_members.py index e3ff5e08..59e41597 100644 --- a/backend/src/kwai/modules/club/import_members.py +++ b/backend/src/kwai/modules/club/import_members.py @@ -48,7 +48,7 @@ def to_message(self) -> str: class ImportMembersCommand: """Input for the use case "ImportMembers".""" - test: bool = True + preview: bool = True class ImportMembers: @@ -86,7 +86,9 @@ async def execute( async for import_result in self._importer.import_(): match import_result: case member_importer.OkResult(): - member = await self._save_member(import_result.member, command.test) + member = await self._save_member( + import_result.member, command.preview + ) yield OkResult( file_upload=file_upload_entity, row=import_result.row, From 3e28ae6cf8c3b3d9e50f640b59c6c333dada30a5 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 17:40:42 +0200 Subject: [PATCH 009/410] refactor: rename test into preview --- backend/src/kwai/modules/club/import_members.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/kwai/modules/club/import_members.py b/backend/src/kwai/modules/club/import_members.py index 59e41597..b49834ac 100644 --- a/backend/src/kwai/modules/club/import_members.py +++ b/backend/src/kwai/modules/club/import_members.py @@ -101,15 +101,15 @@ async def execute( message=import_result.message, ) - async def _save_member(self, member: MemberEntity, test: bool) -> MemberEntity: + async def _save_member(self, member: MemberEntity, preview: bool) -> MemberEntity: """Create or update the member.""" existing_member = await self._get_member(member) if existing_member is not None: updated_member = self._update_member(existing_member, member) - if not test: + if not preview: await self._member_repo.update(updated_member) return updated_member - if not test: + if not preview: return await self._member_repo.create(member) return member From 2df8cf9e1537fae53a56a07944a2a44d39c1410c Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 17:50:17 +0200 Subject: [PATCH 010/410] ci: add --fix arg to ruff --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 52df109f..d686c2e4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,7 +26,7 @@ repos: hooks: - id: ruff types: [python] - args: [--ignore=D102] + args: [--ignore=D102, --fix] - repo: https://github.com/gitleaks/gitleaks rev: v8.18.2 hooks: From 398df1fddc600f49ada2627038eafe0e8caf3e66 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 17:50:40 +0200 Subject: [PATCH 011/410] ci: update ruff options --- backend/pyproject.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/pyproject.toml b/backend/pyproject.toml index e82d0429..5fadcf5e 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -84,10 +84,10 @@ module = "deepdiff.*" ignore_missing_imports = true [tool.ruff] -select = ["E", "W", "F", "C", "B", "D", "I", "N"] -fixable = ["I"] -ignore = ["D107", "D203", "D213", "D406", "D407", "E501", "N818", "B008"] -target-version = "py310" +lint.select = ["E", "W", "F", "C", "B", "D", "I", "N"] +lint.fixable = ["I"] +lint.ignore = ["D107", "D203", "D213", "D406", "D407", "E501", "N818", "B008"] +target-version = "py312" [tool.ruff.pydocstyle] convention = "google" From b759ab9f53a8ce3b584944c3f2c3f5e929d7142e Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 17:54:49 +0200 Subject: [PATCH 012/410] ci: fix ruff settings --- backend/pyproject.toml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 5fadcf5e..03179135 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -84,11 +84,13 @@ module = "deepdiff.*" ignore_missing_imports = true [tool.ruff] -lint.select = ["E", "W", "F", "C", "B", "D", "I", "N"] -lint.fixable = ["I"] -lint.ignore = ["D107", "D203", "D213", "D406", "D407", "E501", "N818", "B008"] target-version = "py312" +[tool.ruff.lint] +select = ["E", "W", "F", "C", "B", "D", "I", "N"] +fixable = ["I"] +ignore = ["D107", "D203", "D213", "D406", "D407", "E501", "N818", "B008"] + [tool.ruff.pydocstyle] convention = "google" From c78593fac42c0ca2b6f1c3768c069699c00f646b Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 17:54:59 +0200 Subject: [PATCH 013/410] refactor: add domain package --- backend/src/kwai/api/v1/club/schemas/country.py | 2 +- backend/src/kwai/api/v1/club/schemas/member.py | 2 +- backend/src/kwai/api/v1/club/schemas/person.py | 2 +- backend/src/kwai/modules/club/domain/__init__.py | 1 + .../kwai/modules/club/{members => domain}/contact.py | 0 .../kwai/modules/club/{members => domain}/country.py | 0 .../modules/club/{members => domain}/file_upload.py | 0 .../kwai/modules/club/{members => domain}/member.py | 3 ++- .../kwai/modules/club/{members => domain}/person.py | 4 ++-- backend/src/kwai/modules/club/get_member.py | 2 +- backend/src/kwai/modules/club/import_members.py | 4 ++-- .../kwai/modules/club/members/contact_db_repository.py | 2 +- .../kwai/modules/club/members/contact_repository.py | 2 +- .../kwai/modules/club/members/country_db_repository.py | 2 +- .../kwai/modules/club/members/country_repository.py | 2 +- .../modules/club/members/file_upload_db_repository.py | 2 +- .../modules/club/members/file_upload_repository.py | 3 ++- .../modules/club/members/flemish_member_importer.py | 6 +++--- .../src/kwai/modules/club/members/member_db_query.py | 2 +- .../kwai/modules/club/members/member_db_repository.py | 2 +- .../src/kwai/modules/club/members/member_importer.py | 6 +++--- backend/src/kwai/modules/club/members/member_query.py | 2 +- .../src/kwai/modules/club/members/member_repository.py | 2 +- backend/src/kwai/modules/club/members/member_tables.py | 10 +++++----- .../kwai/modules/club/members/person_db_repository.py | 2 +- .../src/kwai/modules/club/members/person_repository.py | 2 +- backend/src/kwai/modules/club/members/value_objects.py | 2 +- backend/src/tests/api/v1/club/schemas/conftest.py | 7 +++---- backend/src/tests/api/v1/club/schemas/test_contact.py | 3 +-- backend/src/tests/api/v1/club/schemas/test_country.py | 3 +-- backend/src/tests/api/v1/club/schemas/test_member.py | 5 ++--- backend/src/tests/api/v1/club/schemas/test_person.py | 3 +-- backend/src/tests/fixtures/club/contacts.py | 5 ++--- backend/src/tests/fixtures/club/countries.py | 3 +-- backend/src/tests/fixtures/club/members.py | 5 ++--- backend/src/tests/fixtures/club/persons.py | 7 +++---- .../src/tests/modules/club/members/domain/__init__.py | 1 + .../club/members/{ => domain}/test_birthdate.py | 1 - .../modules/club/members/{ => domain}/test_contact.py | 5 ++--- .../modules/club/members/test_country_db_repository.py | 3 +-- .../club/members/test_file_upload_db_repository.py | 3 +-- .../tests/modules/club/members/test_member_db_query.py | 3 +-- 42 files changed, 58 insertions(+), 68 deletions(-) create mode 100644 backend/src/kwai/modules/club/domain/__init__.py rename backend/src/kwai/modules/club/{members => domain}/contact.py (100%) rename backend/src/kwai/modules/club/{members => domain}/country.py (100%) rename backend/src/kwai/modules/club/{members => domain}/file_upload.py (100%) rename backend/src/kwai/modules/club/{members => domain}/member.py (97%) rename backend/src/kwai/modules/club/{members => domain}/person.py (95%) create mode 100644 backend/src/tests/modules/club/members/domain/__init__.py rename backend/src/tests/modules/club/members/{ => domain}/test_birthdate.py (99%) rename backend/src/tests/modules/club/members/{ => domain}/test_contact.py (91%) diff --git a/backend/src/kwai/api/v1/club/schemas/country.py b/backend/src/kwai/api/v1/club/schemas/country.py index 56ec07e1..b3a6947d 100644 --- a/backend/src/kwai/api/v1/club/schemas/country.py +++ b/backend/src/kwai/api/v1/club/schemas/country.py @@ -6,7 +6,7 @@ from kwai.api.v1.club.schemas.resources import CountryResourceIdentifier from kwai.core.json_api import Document, ResourceData -from kwai.modules.club.members.country import CountryEntity +from kwai.modules.club.domain.country import CountryEntity class CountryAttributes(BaseModel): diff --git a/backend/src/kwai/api/v1/club/schemas/member.py b/backend/src/kwai/api/v1/club/schemas/member.py index 28f68122..347cf311 100644 --- a/backend/src/kwai/api/v1/club/schemas/member.py +++ b/backend/src/kwai/api/v1/club/schemas/member.py @@ -15,7 +15,7 @@ PersonResourceIdentifier, ) from kwai.core.json_api import Document, Relationship, ResourceData, ResourceMeta -from kwai.modules.club.members.member import MemberEntity +from kwai.modules.club.domain.member import MemberEntity class MemberAttributes(BaseModel): diff --git a/backend/src/kwai/api/v1/club/schemas/person.py b/backend/src/kwai/api/v1/club/schemas/person.py index aa15daf7..829bfd1c 100644 --- a/backend/src/kwai/api/v1/club/schemas/person.py +++ b/backend/src/kwai/api/v1/club/schemas/person.py @@ -12,7 +12,7 @@ PersonResourceIdentifier, ) from kwai.core.json_api import Document, Relationship, ResourceData, ResourceMeta -from kwai.modules.club.members.person import PersonEntity +from kwai.modules.club.domain.person import PersonEntity class PersonAttributes(BaseModel): diff --git a/backend/src/kwai/modules/club/domain/__init__.py b/backend/src/kwai/modules/club/domain/__init__.py new file mode 100644 index 00000000..42179d38 --- /dev/null +++ b/backend/src/kwai/modules/club/domain/__init__.py @@ -0,0 +1 @@ +"""Package for entities and value objects.""" diff --git a/backend/src/kwai/modules/club/members/contact.py b/backend/src/kwai/modules/club/domain/contact.py similarity index 100% rename from backend/src/kwai/modules/club/members/contact.py rename to backend/src/kwai/modules/club/domain/contact.py diff --git a/backend/src/kwai/modules/club/members/country.py b/backend/src/kwai/modules/club/domain/country.py similarity index 100% rename from backend/src/kwai/modules/club/members/country.py rename to backend/src/kwai/modules/club/domain/country.py diff --git a/backend/src/kwai/modules/club/members/file_upload.py b/backend/src/kwai/modules/club/domain/file_upload.py similarity index 100% rename from backend/src/kwai/modules/club/members/file_upload.py rename to backend/src/kwai/modules/club/domain/file_upload.py diff --git a/backend/src/kwai/modules/club/members/member.py b/backend/src/kwai/modules/club/domain/member.py similarity index 97% rename from backend/src/kwai/modules/club/members/member.py rename to backend/src/kwai/modules/club/domain/member.py index 657ad03c..56c4bba0 100644 --- a/backend/src/kwai/modules/club/members/member.py +++ b/backend/src/kwai/modules/club/domain/member.py @@ -1,9 +1,10 @@ """Module for defining the Member entity.""" + from kwai.core.domain.entity import Entity from kwai.core.domain.value_objects.identifier import IntIdentifier from kwai.core.domain.value_objects.traceable_time import TraceableTime from kwai.core.domain.value_objects.unique_id import UniqueId -from kwai.modules.club.members.person import PersonEntity +from kwai.modules.club.domain.person import PersonEntity from kwai.modules.club.members.value_objects import License MemberIdentifier = IntIdentifier diff --git a/backend/src/kwai/modules/club/members/person.py b/backend/src/kwai/modules/club/domain/person.py similarity index 95% rename from backend/src/kwai/modules/club/members/person.py rename to backend/src/kwai/modules/club/domain/person.py index c4381502..4a7830b5 100644 --- a/backend/src/kwai/modules/club/members/person.py +++ b/backend/src/kwai/modules/club/domain/person.py @@ -4,8 +4,8 @@ from kwai.core.domain.value_objects.identifier import IntIdentifier from kwai.core.domain.value_objects.name import Name from kwai.core.domain.value_objects.traceable_time import TraceableTime -from kwai.modules.club.members.contact import ContactEntity -from kwai.modules.club.members.country import CountryEntity +from kwai.modules.club.domain.contact import ContactEntity +from kwai.modules.club.domain.country import CountryEntity from kwai.modules.club.members.value_objects import Birthdate, Gender PersonIdentifier = IntIdentifier diff --git a/backend/src/kwai/modules/club/get_member.py b/backend/src/kwai/modules/club/get_member.py index 6959cb84..0361ec63 100644 --- a/backend/src/kwai/modules/club/get_member.py +++ b/backend/src/kwai/modules/club/get_member.py @@ -3,7 +3,7 @@ from dataclasses import dataclass from kwai.core.domain.value_objects.unique_id import UniqueId -from kwai.modules.club.members.member import MemberEntity +from kwai.modules.club.domain.member import MemberEntity from kwai.modules.club.members.member_repository import MemberRepository diff --git a/backend/src/kwai/modules/club/import_members.py b/backend/src/kwai/modules/club/import_members.py index b49834ac..fec8ead3 100644 --- a/backend/src/kwai/modules/club/import_members.py +++ b/backend/src/kwai/modules/club/import_members.py @@ -6,10 +6,10 @@ from kwai.core.domain.entity import Entity from kwai.core.domain.use_case import UseCaseResult +from kwai.modules.club.domain.file_upload import FileUploadEntity +from kwai.modules.club.domain.member import MemberEntity from kwai.modules.club.members import member_importer -from kwai.modules.club.members.file_upload import FileUploadEntity from kwai.modules.club.members.file_upload_repository import FileUploadRepository -from kwai.modules.club.members.member import MemberEntity from kwai.modules.club.members.member_repository import ( MemberNotFoundException, MemberRepository, diff --git a/backend/src/kwai/modules/club/members/contact_db_repository.py b/backend/src/kwai/modules/club/members/contact_db_repository.py index 270e073d..d6260879 100644 --- a/backend/src/kwai/modules/club/members/contact_db_repository.py +++ b/backend/src/kwai/modules/club/members/contact_db_repository.py @@ -7,7 +7,7 @@ from kwai.core.db.database import Database from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.entity import Entity -from kwai.modules.club.members.contact import ContactEntity, ContactIdentifier +from kwai.modules.club.domain.contact import ContactEntity, ContactIdentifier from kwai.modules.club.members.contact_repository import ( ContactNotFoundException, ContactRepository, diff --git a/backend/src/kwai/modules/club/members/contact_repository.py b/backend/src/kwai/modules/club/members/contact_repository.py index 11973b60..39f0caab 100644 --- a/backend/src/kwai/modules/club/members/contact_repository.py +++ b/backend/src/kwai/modules/club/members/contact_repository.py @@ -2,7 +2,7 @@ from abc import ABC, abstractmethod -from kwai.modules.club.members.contact import ContactEntity, ContactIdentifier +from kwai.modules.club.domain.contact import ContactEntity, ContactIdentifier class ContactNotFoundException(Exception): diff --git a/backend/src/kwai/modules/club/members/country_db_repository.py b/backend/src/kwai/modules/club/members/country_db_repository.py index 02c7d678..892144db 100644 --- a/backend/src/kwai/modules/club/members/country_db_repository.py +++ b/backend/src/kwai/modules/club/members/country_db_repository.py @@ -4,7 +4,7 @@ from kwai.core.db.database import Database from kwai.core.domain.entity import Entity -from kwai.modules.club.members.country import CountryEntity, CountryIdentifier +from kwai.modules.club.domain.country import CountryEntity, CountryIdentifier from kwai.modules.club.members.country_repository import ( CountryNotFoundException, CountryRepository, diff --git a/backend/src/kwai/modules/club/members/country_repository.py b/backend/src/kwai/modules/club/members/country_repository.py index 1dcd0810..1584889b 100644 --- a/backend/src/kwai/modules/club/members/country_repository.py +++ b/backend/src/kwai/modules/club/members/country_repository.py @@ -2,7 +2,7 @@ from abc import ABC, abstractmethod -from kwai.modules.club.members.country import CountryEntity +from kwai.modules.club.domain.country import CountryEntity class CountryNotFoundException(Exception): diff --git a/backend/src/kwai/modules/club/members/file_upload_db_repository.py b/backend/src/kwai/modules/club/members/file_upload_db_repository.py index f6937b3c..f737fea0 100644 --- a/backend/src/kwai/modules/club/members/file_upload_db_repository.py +++ b/backend/src/kwai/modules/club/members/file_upload_db_repository.py @@ -2,7 +2,7 @@ from kwai.core.db.database import Database from kwai.core.domain.entity import Entity -from kwai.modules.club.members.file_upload import FileUploadEntity, FileUploadIdentifier +from kwai.modules.club.domain.file_upload import FileUploadEntity, FileUploadIdentifier from kwai.modules.club.members.file_upload_repository import FileUploadRepository from kwai.modules.club.members.member_tables import FileUploadRow diff --git a/backend/src/kwai/modules/club/members/file_upload_repository.py b/backend/src/kwai/modules/club/members/file_upload_repository.py index a7fe55b9..c003101c 100644 --- a/backend/src/kwai/modules/club/members/file_upload_repository.py +++ b/backend/src/kwai/modules/club/members/file_upload_repository.py @@ -1,7 +1,8 @@ """Module that defines an interface for a file upload repository.""" + from abc import ABC, abstractmethod -from kwai.modules.club.members.file_upload import FileUploadEntity +from kwai.modules.club.domain.file_upload import FileUploadEntity class FileUploadRepository(ABC): diff --git a/backend/src/kwai/modules/club/members/flemish_member_importer.py b/backend/src/kwai/modules/club/members/flemish_member_importer.py index 82540f83..b5cc3662 100644 --- a/backend/src/kwai/modules/club/members/flemish_member_importer.py +++ b/backend/src/kwai/modules/club/members/flemish_member_importer.py @@ -10,19 +10,19 @@ ) from kwai.core.domain.value_objects.name import Name from kwai.core.domain.value_objects.owner import Owner -from kwai.modules.club.members.contact import ContactEntity +from kwai.modules.club.domain.contact import ContactEntity +from kwai.modules.club.domain.member import MemberEntity +from kwai.modules.club.domain.person import PersonEntity from kwai.modules.club.members.country_repository import ( CountryNotFoundException, CountryRepository, ) -from kwai.modules.club.members.member import MemberEntity from kwai.modules.club.members.member_importer import ( FailureResult, MemberImporter, OkResult, Result, ) -from kwai.modules.club.members.person import PersonEntity from kwai.modules.club.members.value_objects import Address, Birthdate, Gender, License diff --git a/backend/src/kwai/modules/club/members/member_db_query.py b/backend/src/kwai/modules/club/members/member_db_query.py index 55ab7129..0b9d608f 100644 --- a/backend/src/kwai/modules/club/members/member_db_query.py +++ b/backend/src/kwai/modules/club/members/member_db_query.py @@ -9,7 +9,7 @@ from kwai.core.db.database_query import DatabaseQuery from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.value_objects.unique_id import UniqueId -from kwai.modules.club.members.member import MemberEntity, MemberIdentifier +from kwai.modules.club.domain.member import MemberEntity, MemberIdentifier from kwai.modules.club.members.member_query import MemberQuery from kwai.modules.club.members.member_tables import ( ContactRow, diff --git a/backend/src/kwai/modules/club/members/member_db_repository.py b/backend/src/kwai/modules/club/members/member_db_repository.py index 07d08d34..81e5053a 100644 --- a/backend/src/kwai/modules/club/members/member_db_repository.py +++ b/backend/src/kwai/modules/club/members/member_db_repository.py @@ -4,7 +4,7 @@ from kwai.core.db.database import Database from kwai.core.domain.entity import Entity -from kwai.modules.club.members.member import MemberEntity, MemberIdentifier +from kwai.modules.club.domain.member import MemberEntity, MemberIdentifier from kwai.modules.club.members.member_db_query import MemberDbQuery, MemberQueryRow from kwai.modules.club.members.member_query import MemberQuery from kwai.modules.club.members.member_repository import ( diff --git a/backend/src/kwai/modules/club/members/member_importer.py b/backend/src/kwai/modules/club/members/member_importer.py index a4e1007e..e1bc3a88 100644 --- a/backend/src/kwai/modules/club/members/member_importer.py +++ b/backend/src/kwai/modules/club/members/member_importer.py @@ -7,10 +7,10 @@ from async_lru import alru_cache from kwai.core.domain.value_objects.owner import Owner -from kwai.modules.club.members.country import CountryEntity +from kwai.modules.club.domain.country import CountryEntity +from kwai.modules.club.domain.file_upload import FileUploadEntity +from kwai.modules.club.domain.member import MemberEntity from kwai.modules.club.members.country_repository import CountryRepository -from kwai.modules.club.members.file_upload import FileUploadEntity -from kwai.modules.club.members.member import MemberEntity @dataclass(kw_only=True, frozen=True, slots=True) diff --git a/backend/src/kwai/modules/club/members/member_query.py b/backend/src/kwai/modules/club/members/member_query.py index 3d27e6dd..bcd4e72d 100644 --- a/backend/src/kwai/modules/club/members/member_query.py +++ b/backend/src/kwai/modules/club/members/member_query.py @@ -5,7 +5,7 @@ from kwai.core.domain.repository.query import Query from kwai.core.domain.value_objects.unique_id import UniqueId -from kwai.modules.club.members.member import MemberIdentifier +from kwai.modules.club.domain.member import MemberIdentifier class MemberQuery(Query, ABC): diff --git a/backend/src/kwai/modules/club/members/member_repository.py b/backend/src/kwai/modules/club/members/member_repository.py index c1bf81ce..7a334339 100644 --- a/backend/src/kwai/modules/club/members/member_repository.py +++ b/backend/src/kwai/modules/club/members/member_repository.py @@ -3,7 +3,7 @@ from abc import ABC, abstractmethod from typing import AsyncGenerator -from kwai.modules.club.members.member import MemberEntity +from kwai.modules.club.domain.member import MemberEntity from kwai.modules.club.members.member_query import MemberQuery diff --git a/backend/src/kwai/modules/club/members/member_tables.py b/backend/src/kwai/modules/club/members/member_tables.py index b2ceca2c..be4282f0 100644 --- a/backend/src/kwai/modules/club/members/member_tables.py +++ b/backend/src/kwai/modules/club/members/member_tables.py @@ -11,11 +11,11 @@ from kwai.core.domain.value_objects.timestamp import Timestamp from kwai.core.domain.value_objects.traceable_time import TraceableTime from kwai.core.domain.value_objects.unique_id import UniqueId -from kwai.modules.club.members.contact import ContactEntity, ContactIdentifier -from kwai.modules.club.members.country import CountryEntity, CountryIdentifier -from kwai.modules.club.members.file_upload import FileUploadEntity -from kwai.modules.club.members.member import MemberEntity, MemberIdentifier -from kwai.modules.club.members.person import PersonEntity, PersonIdentifier +from kwai.modules.club.domain.contact import ContactEntity, ContactIdentifier +from kwai.modules.club.domain.country import CountryEntity, CountryIdentifier +from kwai.modules.club.domain.file_upload import FileUploadEntity +from kwai.modules.club.domain.member import MemberEntity, MemberIdentifier +from kwai.modules.club.domain.person import PersonEntity, PersonIdentifier from kwai.modules.club.members.value_objects import ( Address, Birthdate, diff --git a/backend/src/kwai/modules/club/members/person_db_repository.py b/backend/src/kwai/modules/club/members/person_db_repository.py index eb55a89b..b317ff14 100644 --- a/backend/src/kwai/modules/club/members/person_db_repository.py +++ b/backend/src/kwai/modules/club/members/person_db_repository.py @@ -7,9 +7,9 @@ from kwai.core.db.database import Database from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.entity import Entity +from kwai.modules.club.domain.person import PersonEntity, PersonIdentifier from kwai.modules.club.members.contact_db_repository import ContactDbRepository from kwai.modules.club.members.member_tables import ContactRow, CountryRow, PersonRow -from kwai.modules.club.members.person import PersonEntity, PersonIdentifier from kwai.modules.club.members.person_repository import ( PersonNotFoundException, PersonRepository, diff --git a/backend/src/kwai/modules/club/members/person_repository.py b/backend/src/kwai/modules/club/members/person_repository.py index d5de5d4f..6f81ecfe 100644 --- a/backend/src/kwai/modules/club/members/person_repository.py +++ b/backend/src/kwai/modules/club/members/person_repository.py @@ -2,7 +2,7 @@ from abc import ABC, abstractmethod -from kwai.modules.club.members.person import PersonEntity, PersonIdentifier +from kwai.modules.club.domain.person import PersonEntity, PersonIdentifier class PersonNotFoundException(Exception): diff --git a/backend/src/kwai/modules/club/members/value_objects.py b/backend/src/kwai/modules/club/members/value_objects.py index dd5e2058..eda85759 100644 --- a/backend/src/kwai/modules/club/members/value_objects.py +++ b/backend/src/kwai/modules/club/members/value_objects.py @@ -4,7 +4,7 @@ from enum import Enum from kwai.core.domain.value_objects.date import Date -from kwai.modules.club.members.country import CountryEntity +from kwai.modules.club.domain.country import CountryEntity @dataclass(kw_only=True, frozen=True, slots=True) diff --git a/backend/src/tests/api/v1/club/schemas/conftest.py b/backend/src/tests/api/v1/club/schemas/conftest.py index 2df39e99..1b183bea 100644 --- a/backend/src/tests/api/v1/club/schemas/conftest.py +++ b/backend/src/tests/api/v1/club/schemas/conftest.py @@ -3,13 +3,12 @@ from typing import Any import pytest - from kwai.core.domain.value_objects.date import Date from kwai.core.domain.value_objects.email_address import EmailAddress from kwai.core.domain.value_objects.name import Name -from kwai.modules.club.members.contact import ContactEntity, ContactIdentifier -from kwai.modules.club.members.country import CountryEntity, CountryIdentifier -from kwai.modules.club.members.person import PersonEntity, PersonIdentifier +from kwai.modules.club.domain.contact import ContactEntity, ContactIdentifier +from kwai.modules.club.domain.country import CountryEntity, CountryIdentifier +from kwai.modules.club.domain.person import PersonEntity, PersonIdentifier from kwai.modules.club.members.value_objects import Address, Birthdate, Gender diff --git a/backend/src/tests/api/v1/club/schemas/test_contact.py b/backend/src/tests/api/v1/club/schemas/test_contact.py index c0f80933..43c57c4d 100644 --- a/backend/src/tests/api/v1/club/schemas/test_contact.py +++ b/backend/src/tests/api/v1/club/schemas/test_contact.py @@ -4,9 +4,8 @@ from typing import Any from deepdiff import DeepDiff - from kwai.api.v1.club.schemas.contact import ContactDocument -from kwai.modules.club.members.contact import ContactEntity +from kwai.modules.club.domain.contact import ContactEntity def test_create_contact_document( diff --git a/backend/src/tests/api/v1/club/schemas/test_country.py b/backend/src/tests/api/v1/club/schemas/test_country.py index b7dbcbff..d6175ed1 100644 --- a/backend/src/tests/api/v1/club/schemas/test_country.py +++ b/backend/src/tests/api/v1/club/schemas/test_country.py @@ -4,9 +4,8 @@ from typing import Any from deepdiff import DeepDiff - from kwai.api.v1.club.schemas.country import CountryDocument -from kwai.modules.club.members.country import CountryEntity +from kwai.modules.club.domain.country import CountryEntity def test_create_country_document( diff --git a/backend/src/tests/api/v1/club/schemas/test_member.py b/backend/src/tests/api/v1/club/schemas/test_member.py index a76d6b58..c750e72f 100644 --- a/backend/src/tests/api/v1/club/schemas/test_member.py +++ b/backend/src/tests/api/v1/club/schemas/test_member.py @@ -5,11 +5,10 @@ import pytest from deepdiff import DeepDiff - from kwai.api.v1.club.schemas.member import MemberDocument from kwai.core.domain.value_objects.date import Date -from kwai.modules.club.members.member import MemberEntity, MemberIdentifier -from kwai.modules.club.members.person import PersonEntity +from kwai.modules.club.domain.member import MemberEntity, MemberIdentifier +from kwai.modules.club.domain.person import PersonEntity from kwai.modules.club.members.value_objects import License diff --git a/backend/src/tests/api/v1/club/schemas/test_person.py b/backend/src/tests/api/v1/club/schemas/test_person.py index d27b6168..a633e43f 100644 --- a/backend/src/tests/api/v1/club/schemas/test_person.py +++ b/backend/src/tests/api/v1/club/schemas/test_person.py @@ -4,9 +4,8 @@ from typing import Any from deepdiff import DeepDiff - from kwai.api.v1.club.schemas.person import PersonDocument -from kwai.modules.club.members.person import PersonEntity +from kwai.modules.club.domain.person import PersonEntity def test_create_person_document( diff --git a/backend/src/tests/fixtures/club/contacts.py b/backend/src/tests/fixtures/club/contacts.py index 05f6e76e..b1c0fda1 100644 --- a/backend/src/tests/fixtures/club/contacts.py +++ b/backend/src/tests/fixtures/club/contacts.py @@ -10,13 +10,12 @@ ) import pytest - from kwai.core.db.database import Database from kwai.core.db.uow import UnitOfWork from kwai.core.domain.value_objects.email_address import EmailAddress -from kwai.modules.club.members.contact import ContactEntity +from kwai.modules.club.domain.contact import ContactEntity +from kwai.modules.club.domain.country import CountryEntity from kwai.modules.club.members.contact_db_repository import ContactDbRepository -from kwai.modules.club.members.country import CountryEntity from kwai.modules.club.members.value_objects import Address diff --git a/backend/src/tests/fixtures/club/countries.py b/backend/src/tests/fixtures/club/countries.py index 549d14a7..eb2046af 100644 --- a/backend/src/tests/fixtures/club/countries.py +++ b/backend/src/tests/fixtures/club/countries.py @@ -9,10 +9,9 @@ ) import pytest - from kwai.core.db.database import Database from kwai.core.db.uow import UnitOfWork -from kwai.modules.club.members.country import CountryEntity +from kwai.modules.club.domain.country import CountryEntity from kwai.modules.club.members.country_db_repository import CountryDbRepository from kwai.modules.club.members.country_repository import CountryNotFoundException diff --git a/backend/src/tests/fixtures/club/members.py b/backend/src/tests/fixtures/club/members.py index 04978275..c04b35e4 100644 --- a/backend/src/tests/fixtures/club/members.py +++ b/backend/src/tests/fixtures/club/members.py @@ -3,13 +3,12 @@ from typing import Callable, TypeAlias import pytest - from kwai.core.db.database import Database from kwai.core.db.uow import UnitOfWork from kwai.core.domain.value_objects.date import Date -from kwai.modules.club.members.member import MemberEntity +from kwai.modules.club.domain.member import MemberEntity +from kwai.modules.club.domain.person import PersonEntity from kwai.modules.club.members.member_db_repository import MemberDbRepository -from kwai.modules.club.members.person import PersonEntity from kwai.modules.club.members.value_objects import License MemberFixtureFactory: TypeAlias = Callable[[License | None], MemberEntity] diff --git a/backend/src/tests/fixtures/club/persons.py b/backend/src/tests/fixtures/club/persons.py index 2244cc2e..c17f1cf0 100644 --- a/backend/src/tests/fixtures/club/persons.py +++ b/backend/src/tests/fixtures/club/persons.py @@ -1,14 +1,13 @@ """Module for defining fixtures for persons.""" import pytest - from kwai.core.db.database import Database from kwai.core.db.uow import UnitOfWork from kwai.core.domain.value_objects.date import Date from kwai.core.domain.value_objects.name import Name -from kwai.modules.club.members.contact import ContactEntity -from kwai.modules.club.members.country import CountryEntity -from kwai.modules.club.members.person import PersonEntity +from kwai.modules.club.domain.contact import ContactEntity +from kwai.modules.club.domain.country import CountryEntity +from kwai.modules.club.domain.person import PersonEntity from kwai.modules.club.members.person_db_repository import PersonDbRepository from kwai.modules.club.members.value_objects import Birthdate, Gender diff --git a/backend/src/tests/modules/club/members/domain/__init__.py b/backend/src/tests/modules/club/members/domain/__init__.py new file mode 100644 index 00000000..b862f7c7 --- /dev/null +++ b/backend/src/tests/modules/club/members/domain/__init__.py @@ -0,0 +1 @@ +"""Package for testing the club domain package.""" diff --git a/backend/src/tests/modules/club/members/test_birthdate.py b/backend/src/tests/modules/club/members/domain/test_birthdate.py similarity index 99% rename from backend/src/tests/modules/club/members/test_birthdate.py rename to backend/src/tests/modules/club/members/domain/test_birthdate.py index d22d22af..dd18a51b 100644 --- a/backend/src/tests/modules/club/members/test_birthdate.py +++ b/backend/src/tests/modules/club/members/domain/test_birthdate.py @@ -1,7 +1,6 @@ """Module for testing the Birthdate value object.""" import pendulum - from kwai.core.domain.value_objects.date import Date from kwai.modules.club.members.value_objects import Birthdate diff --git a/backend/src/tests/modules/club/members/test_contact.py b/backend/src/tests/modules/club/members/domain/test_contact.py similarity index 91% rename from backend/src/tests/modules/club/members/test_contact.py rename to backend/src/tests/modules/club/members/domain/test_contact.py index 2d0735fa..3a5f32ae 100644 --- a/backend/src/tests/modules/club/members/test_contact.py +++ b/backend/src/tests/modules/club/members/domain/test_contact.py @@ -1,10 +1,9 @@ """Module that defines tests for the ContactEntity.""" import pytest - from kwai.core.domain.value_objects.email_address import EmailAddress -from kwai.modules.club.members.contact import ContactEntity -from kwai.modules.club.members.country import CountryEntity, CountryIdentifier +from kwai.modules.club.domain.contact import ContactEntity +from kwai.modules.club.domain.country import CountryEntity, CountryIdentifier from kwai.modules.club.members.value_objects import Address diff --git a/backend/src/tests/modules/club/members/test_country_db_repository.py b/backend/src/tests/modules/club/members/test_country_db_repository.py index ae594a09..c91054e0 100644 --- a/backend/src/tests/modules/club/members/test_country_db_repository.py +++ b/backend/src/tests/modules/club/members/test_country_db_repository.py @@ -1,9 +1,8 @@ """Module for testing the country db repository.""" import pytest - from kwai.core.db.database import Database -from kwai.modules.club.members.country import CountryEntity +from kwai.modules.club.domain.country import CountryEntity from kwai.modules.club.members.country_db_repository import CountryDbRepository from kwai.modules.club.members.country_repository import ( CountryNotFoundException, diff --git a/backend/src/tests/modules/club/members/test_file_upload_db_repository.py b/backend/src/tests/modules/club/members/test_file_upload_db_repository.py index 797285b5..81fb0512 100644 --- a/backend/src/tests/modules/club/members/test_file_upload_db_repository.py +++ b/backend/src/tests/modules/club/members/test_file_upload_db_repository.py @@ -1,10 +1,9 @@ """Module for testing the file upload repository.""" import pytest - from kwai.core.db.database import Database from kwai.core.domain.value_objects.owner import Owner -from kwai.modules.club.members.file_upload import FileUploadEntity +from kwai.modules.club.domain.file_upload import FileUploadEntity from kwai.modules.club.members.file_upload_db_repository import FileUploadDbRepository pytestmark = pytest.mark.db diff --git a/backend/src/tests/modules/club/members/test_member_db_query.py b/backend/src/tests/modules/club/members/test_member_db_query.py index 37db0a43..2cc676b9 100644 --- a/backend/src/tests/modules/club/members/test_member_db_query.py +++ b/backend/src/tests/modules/club/members/test_member_db_query.py @@ -1,10 +1,9 @@ """Module for testing the members database query.""" import pytest - from kwai.core.db.database import Database from kwai.core.domain.value_objects.unique_id import UniqueId -from kwai.modules.club.members.member import MemberIdentifier +from kwai.modules.club.domain.member import MemberIdentifier from kwai.modules.club.members.member_db_query import MemberDbQuery from kwai.modules.club.members.member_query import MemberQuery From 716bd00d5ea5bf73284e96ba808a135d346ba30a Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 19:52:22 +0200 Subject: [PATCH 014/410] ci: fix ruff docstyle setting --- backend/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 03179135..2b198824 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -91,7 +91,7 @@ select = ["E", "W", "F", "C", "B", "D", "I", "N"] fixable = ["I"] ignore = ["D107", "D203", "D213", "D406", "D407", "E501", "N818", "B008"] -[tool.ruff.pydocstyle] +[tool.ruff.lint.pydocstyle] convention = "google" [build-system] From 16c60a599da7ca967381aa46603e2aef937471da Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 19:52:30 +0200 Subject: [PATCH 015/410] refactor: rename member_tables.py into _member_tables.py --- .../club/members/{member_tables.py => _member_tables.py} | 0 .../src/kwai/modules/club/members/contact_db_repository.py | 2 +- .../src/kwai/modules/club/members/country_db_repository.py | 2 +- .../kwai/modules/club/members/file_upload_db_repository.py | 2 +- backend/src/kwai/modules/club/members/member_db_query.py | 4 ++-- backend/src/kwai/modules/club/members/member_db_repository.py | 2 +- backend/src/kwai/modules/club/members/person_db_repository.py | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) rename backend/src/kwai/modules/club/members/{member_tables.py => _member_tables.py} (100%) diff --git a/backend/src/kwai/modules/club/members/member_tables.py b/backend/src/kwai/modules/club/members/_member_tables.py similarity index 100% rename from backend/src/kwai/modules/club/members/member_tables.py rename to backend/src/kwai/modules/club/members/_member_tables.py diff --git a/backend/src/kwai/modules/club/members/contact_db_repository.py b/backend/src/kwai/modules/club/members/contact_db_repository.py index d6260879..499de47f 100644 --- a/backend/src/kwai/modules/club/members/contact_db_repository.py +++ b/backend/src/kwai/modules/club/members/contact_db_repository.py @@ -8,11 +8,11 @@ from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.entity import Entity from kwai.modules.club.domain.contact import ContactEntity, ContactIdentifier +from kwai.modules.club.members._member_tables import ContactRow, CountryRow from kwai.modules.club.members.contact_repository import ( ContactNotFoundException, ContactRepository, ) -from kwai.modules.club.members.member_tables import ContactRow, CountryRow @dataclass(kw_only=True, frozen=True, slots=True) diff --git a/backend/src/kwai/modules/club/members/country_db_repository.py b/backend/src/kwai/modules/club/members/country_db_repository.py index 892144db..e45e9d85 100644 --- a/backend/src/kwai/modules/club/members/country_db_repository.py +++ b/backend/src/kwai/modules/club/members/country_db_repository.py @@ -5,11 +5,11 @@ from kwai.core.db.database import Database from kwai.core.domain.entity import Entity from kwai.modules.club.domain.country import CountryEntity, CountryIdentifier +from kwai.modules.club.members._member_tables import CountryRow from kwai.modules.club.members.country_repository import ( CountryNotFoundException, CountryRepository, ) -from kwai.modules.club.members.member_tables import CountryRow class CountryDbRepository(CountryRepository): diff --git a/backend/src/kwai/modules/club/members/file_upload_db_repository.py b/backend/src/kwai/modules/club/members/file_upload_db_repository.py index f737fea0..ded02f6c 100644 --- a/backend/src/kwai/modules/club/members/file_upload_db_repository.py +++ b/backend/src/kwai/modules/club/members/file_upload_db_repository.py @@ -3,8 +3,8 @@ from kwai.core.db.database import Database from kwai.core.domain.entity import Entity from kwai.modules.club.domain.file_upload import FileUploadEntity, FileUploadIdentifier +from kwai.modules.club.members._member_tables import FileUploadRow from kwai.modules.club.members.file_upload_repository import FileUploadRepository -from kwai.modules.club.members.member_tables import FileUploadRow class FileUploadDbRepository(FileUploadRepository): diff --git a/backend/src/kwai/modules/club/members/member_db_query.py b/backend/src/kwai/modules/club/members/member_db_query.py index 0b9d608f..10ab28f8 100644 --- a/backend/src/kwai/modules/club/members/member_db_query.py +++ b/backend/src/kwai/modules/club/members/member_db_query.py @@ -10,13 +10,13 @@ from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.club.domain.member import MemberEntity, MemberIdentifier -from kwai.modules.club.members.member_query import MemberQuery -from kwai.modules.club.members.member_tables import ( +from kwai.modules.club.members._member_tables import ( ContactRow, CountryRow, MemberRow, PersonRow, ) +from kwai.modules.club.members.member_query import MemberQuery @dataclass(kw_only=True, frozen=True, slots=True) diff --git a/backend/src/kwai/modules/club/members/member_db_repository.py b/backend/src/kwai/modules/club/members/member_db_repository.py index 81e5053a..1dbf0d6e 100644 --- a/backend/src/kwai/modules/club/members/member_db_repository.py +++ b/backend/src/kwai/modules/club/members/member_db_repository.py @@ -5,13 +5,13 @@ from kwai.core.db.database import Database from kwai.core.domain.entity import Entity from kwai.modules.club.domain.member import MemberEntity, MemberIdentifier +from kwai.modules.club.members._member_tables import MemberRow from kwai.modules.club.members.member_db_query import MemberDbQuery, MemberQueryRow from kwai.modules.club.members.member_query import MemberQuery from kwai.modules.club.members.member_repository import ( MemberNotFoundException, MemberRepository, ) -from kwai.modules.club.members.member_tables import MemberRow from kwai.modules.club.members.person_db_repository import PersonDbRepository diff --git a/backend/src/kwai/modules/club/members/person_db_repository.py b/backend/src/kwai/modules/club/members/person_db_repository.py index b317ff14..b10fc9ee 100644 --- a/backend/src/kwai/modules/club/members/person_db_repository.py +++ b/backend/src/kwai/modules/club/members/person_db_repository.py @@ -8,8 +8,8 @@ from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.entity import Entity from kwai.modules.club.domain.person import PersonEntity, PersonIdentifier +from kwai.modules.club.members._member_tables import ContactRow, CountryRow, PersonRow from kwai.modules.club.members.contact_db_repository import ContactDbRepository -from kwai.modules.club.members.member_tables import ContactRow, CountryRow, PersonRow from kwai.modules.club.members.person_repository import ( PersonNotFoundException, PersonRepository, From 547b7820625dd756c2a8a4c7099388ad2690c8a2 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 19:56:35 +0200 Subject: [PATCH 016/410] refactor: add domain package --- backend/src/kwai/api/v1/club/schemas/contact.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/kwai/api/v1/club/schemas/contact.py b/backend/src/kwai/api/v1/club/schemas/contact.py index 2092707c..4a2a5fee 100644 --- a/backend/src/kwai/api/v1/club/schemas/contact.py +++ b/backend/src/kwai/api/v1/club/schemas/contact.py @@ -13,7 +13,7 @@ CountryResourceIdentifier, ) from kwai.core.json_api import Document, Relationship, ResourceData, ResourceMeta -from kwai.modules.club.members.contact import ContactEntity +from kwai.modules.club.domain.contact import ContactEntity class ContactAttributes(BaseModel): From 76f8f655221d5925f00c792e31d5673cb39bee87 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 21:42:30 +0200 Subject: [PATCH 017/410] refactor: move value_objects to domain --- backend/src/kwai/modules/club/domain/contact.py | 2 +- backend/src/kwai/modules/club/domain/member.py | 2 +- backend/src/kwai/modules/club/domain/person.py | 2 +- .../src/kwai/modules/club/{members => domain}/value_objects.py | 0 backend/src/kwai/modules/club/members/_member_tables.py | 2 +- .../src/kwai/modules/club/members/flemish_member_importer.py | 2 +- backend/src/kwai/modules/club/repositories/__init__.py | 1 + backend/src/tests/api/v1/club/schemas/conftest.py | 2 +- backend/src/tests/api/v1/club/schemas/test_member.py | 2 +- backend/src/tests/fixtures/club/contacts.py | 2 +- backend/src/tests/fixtures/club/members.py | 2 +- backend/src/tests/fixtures/club/persons.py | 2 +- .../src/tests/modules/club/members/domain/test_birthdate.py | 2 +- backend/src/tests/modules/club/members/domain/test_contact.py | 2 +- .../tests/modules/club/members/test_flemish_member_importer.py | 3 +-- backend/src/tests/modules/club/test_get_members.py | 3 +-- 16 files changed, 15 insertions(+), 16 deletions(-) rename backend/src/kwai/modules/club/{members => domain}/value_objects.py (100%) create mode 100644 backend/src/kwai/modules/club/repositories/__init__.py diff --git a/backend/src/kwai/modules/club/domain/contact.py b/backend/src/kwai/modules/club/domain/contact.py index ba7ef04f..3634c9a4 100644 --- a/backend/src/kwai/modules/club/domain/contact.py +++ b/backend/src/kwai/modules/club/domain/contact.py @@ -4,7 +4,7 @@ from kwai.core.domain.value_objects.email_address import EmailAddress from kwai.core.domain.value_objects.identifier import IntIdentifier from kwai.core.domain.value_objects.traceable_time import TraceableTime -from kwai.modules.club.members.value_objects import Address +from kwai.modules.club.domain.value_objects import Address ContactIdentifier = IntIdentifier diff --git a/backend/src/kwai/modules/club/domain/member.py b/backend/src/kwai/modules/club/domain/member.py index 56c4bba0..e6aaa886 100644 --- a/backend/src/kwai/modules/club/domain/member.py +++ b/backend/src/kwai/modules/club/domain/member.py @@ -5,7 +5,7 @@ from kwai.core.domain.value_objects.traceable_time import TraceableTime from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.club.domain.person import PersonEntity -from kwai.modules.club.members.value_objects import License +from kwai.modules.club.domain.value_objects import License MemberIdentifier = IntIdentifier diff --git a/backend/src/kwai/modules/club/domain/person.py b/backend/src/kwai/modules/club/domain/person.py index 4a7830b5..1ab08dd1 100644 --- a/backend/src/kwai/modules/club/domain/person.py +++ b/backend/src/kwai/modules/club/domain/person.py @@ -6,7 +6,7 @@ from kwai.core.domain.value_objects.traceable_time import TraceableTime from kwai.modules.club.domain.contact import ContactEntity from kwai.modules.club.domain.country import CountryEntity -from kwai.modules.club.members.value_objects import Birthdate, Gender +from kwai.modules.club.domain.value_objects import Birthdate, Gender PersonIdentifier = IntIdentifier diff --git a/backend/src/kwai/modules/club/members/value_objects.py b/backend/src/kwai/modules/club/domain/value_objects.py similarity index 100% rename from backend/src/kwai/modules/club/members/value_objects.py rename to backend/src/kwai/modules/club/domain/value_objects.py diff --git a/backend/src/kwai/modules/club/members/_member_tables.py b/backend/src/kwai/modules/club/members/_member_tables.py index be4282f0..0a663ed5 100644 --- a/backend/src/kwai/modules/club/members/_member_tables.py +++ b/backend/src/kwai/modules/club/members/_member_tables.py @@ -16,7 +16,7 @@ from kwai.modules.club.domain.file_upload import FileUploadEntity from kwai.modules.club.domain.member import MemberEntity, MemberIdentifier from kwai.modules.club.domain.person import PersonEntity, PersonIdentifier -from kwai.modules.club.members.value_objects import ( +from kwai.modules.club.domain.value_objects import ( Address, Birthdate, Gender, diff --git a/backend/src/kwai/modules/club/members/flemish_member_importer.py b/backend/src/kwai/modules/club/members/flemish_member_importer.py index b5cc3662..0154671a 100644 --- a/backend/src/kwai/modules/club/members/flemish_member_importer.py +++ b/backend/src/kwai/modules/club/members/flemish_member_importer.py @@ -13,6 +13,7 @@ from kwai.modules.club.domain.contact import ContactEntity from kwai.modules.club.domain.member import MemberEntity from kwai.modules.club.domain.person import PersonEntity +from kwai.modules.club.domain.value_objects import Address, Birthdate, Gender, License from kwai.modules.club.members.country_repository import ( CountryNotFoundException, CountryRepository, @@ -23,7 +24,6 @@ OkResult, Result, ) -from kwai.modules.club.members.value_objects import Address, Birthdate, Gender, License class FlemishMemberImporter(MemberImporter): diff --git a/backend/src/kwai/modules/club/repositories/__init__.py b/backend/src/kwai/modules/club/repositories/__init__.py new file mode 100644 index 00000000..c6660d92 --- /dev/null +++ b/backend/src/kwai/modules/club/repositories/__init__.py @@ -0,0 +1 @@ +"""Package for all the repositories.""" diff --git a/backend/src/tests/api/v1/club/schemas/conftest.py b/backend/src/tests/api/v1/club/schemas/conftest.py index 1b183bea..3fb686d7 100644 --- a/backend/src/tests/api/v1/club/schemas/conftest.py +++ b/backend/src/tests/api/v1/club/schemas/conftest.py @@ -9,7 +9,7 @@ from kwai.modules.club.domain.contact import ContactEntity, ContactIdentifier from kwai.modules.club.domain.country import CountryEntity, CountryIdentifier from kwai.modules.club.domain.person import PersonEntity, PersonIdentifier -from kwai.modules.club.members.value_objects import Address, Birthdate, Gender +from kwai.modules.club.domain.value_objects import Address, Birthdate, Gender @pytest.fixture diff --git a/backend/src/tests/api/v1/club/schemas/test_member.py b/backend/src/tests/api/v1/club/schemas/test_member.py index c750e72f..cbb236b8 100644 --- a/backend/src/tests/api/v1/club/schemas/test_member.py +++ b/backend/src/tests/api/v1/club/schemas/test_member.py @@ -9,7 +9,7 @@ from kwai.core.domain.value_objects.date import Date from kwai.modules.club.domain.member import MemberEntity, MemberIdentifier from kwai.modules.club.domain.person import PersonEntity -from kwai.modules.club.members.value_objects import License +from kwai.modules.club.domain.value_objects import License @pytest.fixture diff --git a/backend/src/tests/fixtures/club/contacts.py b/backend/src/tests/fixtures/club/contacts.py index b1c0fda1..0ed93b15 100644 --- a/backend/src/tests/fixtures/club/contacts.py +++ b/backend/src/tests/fixtures/club/contacts.py @@ -15,8 +15,8 @@ from kwai.core.domain.value_objects.email_address import EmailAddress from kwai.modules.club.domain.contact import ContactEntity from kwai.modules.club.domain.country import CountryEntity +from kwai.modules.club.domain.value_objects import Address from kwai.modules.club.members.contact_db_repository import ContactDbRepository -from kwai.modules.club.members.value_objects import Address class AddressType(TypedDict): diff --git a/backend/src/tests/fixtures/club/members.py b/backend/src/tests/fixtures/club/members.py index c04b35e4..329a46c0 100644 --- a/backend/src/tests/fixtures/club/members.py +++ b/backend/src/tests/fixtures/club/members.py @@ -8,8 +8,8 @@ from kwai.core.domain.value_objects.date import Date from kwai.modules.club.domain.member import MemberEntity from kwai.modules.club.domain.person import PersonEntity +from kwai.modules.club.domain.value_objects import License from kwai.modules.club.members.member_db_repository import MemberDbRepository -from kwai.modules.club.members.value_objects import License MemberFixtureFactory: TypeAlias = Callable[[License | None], MemberEntity] diff --git a/backend/src/tests/fixtures/club/persons.py b/backend/src/tests/fixtures/club/persons.py index c17f1cf0..6164c7c5 100644 --- a/backend/src/tests/fixtures/club/persons.py +++ b/backend/src/tests/fixtures/club/persons.py @@ -8,8 +8,8 @@ from kwai.modules.club.domain.contact import ContactEntity from kwai.modules.club.domain.country import CountryEntity from kwai.modules.club.domain.person import PersonEntity +from kwai.modules.club.domain.value_objects import Birthdate, Gender from kwai.modules.club.members.person_db_repository import PersonDbRepository -from kwai.modules.club.members.value_objects import Birthdate, Gender @pytest.fixture diff --git a/backend/src/tests/modules/club/members/domain/test_birthdate.py b/backend/src/tests/modules/club/members/domain/test_birthdate.py index dd18a51b..d422b0fe 100644 --- a/backend/src/tests/modules/club/members/domain/test_birthdate.py +++ b/backend/src/tests/modules/club/members/domain/test_birthdate.py @@ -2,7 +2,7 @@ import pendulum from kwai.core.domain.value_objects.date import Date -from kwai.modules.club.members.value_objects import Birthdate +from kwai.modules.club.domain.value_objects import Birthdate def test_age(): diff --git a/backend/src/tests/modules/club/members/domain/test_contact.py b/backend/src/tests/modules/club/members/domain/test_contact.py index 3a5f32ae..9c989db9 100644 --- a/backend/src/tests/modules/club/members/domain/test_contact.py +++ b/backend/src/tests/modules/club/members/domain/test_contact.py @@ -4,7 +4,7 @@ from kwai.core.domain.value_objects.email_address import EmailAddress from kwai.modules.club.domain.contact import ContactEntity from kwai.modules.club.domain.country import CountryEntity, CountryIdentifier -from kwai.modules.club.members.value_objects import Address +from kwai.modules.club.domain.value_objects import Address @pytest.fixture diff --git a/backend/src/tests/modules/club/members/test_flemish_member_importer.py b/backend/src/tests/modules/club/members/test_flemish_member_importer.py index 6eb57229..5c0f13a5 100644 --- a/backend/src/tests/modules/club/members/test_flemish_member_importer.py +++ b/backend/src/tests/modules/club/members/test_flemish_member_importer.py @@ -3,13 +3,12 @@ from pathlib import Path import pytest - from kwai.core.db.database import Database from kwai.core.domain.value_objects.owner import Owner +from kwai.modules.club.domain.value_objects import Gender from kwai.modules.club.members.country_db_repository import CountryDbRepository from kwai.modules.club.members.flemish_member_importer import FlemishMemberImporter from kwai.modules.club.members.member_importer import Result -from kwai.modules.club.members.value_objects import Gender pytestmark = pytest.mark.db diff --git a/backend/src/tests/modules/club/test_get_members.py b/backend/src/tests/modules/club/test_get_members.py index 9d29f721..37fb722f 100644 --- a/backend/src/tests/modules/club/test_get_members.py +++ b/backend/src/tests/modules/club/test_get_members.py @@ -1,13 +1,12 @@ """Module for testing the use case 'Get Members'.""" import pytest - from kwai.core.db.database import Database from kwai.core.domain.value_objects.date import Date +from kwai.modules.club.domain.value_objects import License from kwai.modules.club.get_members import GetMembers, GetMembersCommand from kwai.modules.club.members.member_db_repository import MemberDbRepository from kwai.modules.club.members.member_repository import MemberRepository -from kwai.modules.club.members.value_objects import License @pytest.fixture From 4d5ae42374354750c7e24d8df580d1ec784b02b3 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 21:44:28 +0200 Subject: [PATCH 018/410] refactor: move repositories --- backend/src/kwai/api/v1/club/endpoints/members.py | 6 +++--- .../src/kwai/api/v1/club/endpoints/upload_members.py | 10 ++++++---- backend/src/kwai/modules/club/get_member.py | 2 +- backend/src/kwai/modules/club/get_members.py | 2 +- backend/src/kwai/modules/club/import_members.py | 6 +++--- .../club/{members => repositories}/_member_tables.py | 0 .../{members => repositories}/contact_db_repository.py | 4 ++-- .../{members => repositories}/contact_repository.py | 0 .../{members => repositories}/country_db_repository.py | 4 ++-- .../{members => repositories}/country_repository.py | 0 .../file_upload_db_repository.py | 4 ++-- .../file_upload_repository.py | 0 .../flemish_member_importer.py | 4 ++-- .../club/{members => repositories}/member_db_query.py | 4 ++-- .../{members => repositories}/member_db_repository.py | 10 +++++----- .../club/{members => repositories}/member_importer.py | 2 +- .../club/{members => repositories}/member_query.py | 0 .../{members => repositories}/member_repository.py | 2 +- .../{members => repositories}/person_db_repository.py | 10 +++++++--- .../{members => repositories}/person_repository.py | 0 backend/src/tests/fixtures/club/contacts.py | 2 +- backend/src/tests/fixtures/club/countries.py | 4 ++-- backend/src/tests/fixtures/club/members.py | 2 +- backend/src/tests/fixtures/club/persons.py | 2 +- .../modules/club/members/test_contact_db_repository.py | 5 ++--- .../modules/club/members/test_country_db_repository.py | 4 ++-- .../club/members/test_file_upload_db_repository.py | 4 +++- .../club/members/test_flemish_member_importer.py | 6 +++--- .../tests/modules/club/members/test_member_db_query.py | 4 ++-- .../modules/club/members/test_member_db_repository.py | 5 ++--- .../modules/club/members/test_person_db_repository.py | 5 ++--- backend/src/tests/modules/club/test_get_member.py | 5 ++--- backend/src/tests/modules/club/test_get_members.py | 4 ++-- backend/src/tests/modules/club/test_import_members.py | 10 ++++++---- 34 files changed, 69 insertions(+), 63 deletions(-) rename backend/src/kwai/modules/club/{members => repositories}/_member_tables.py (100%) rename backend/src/kwai/modules/club/{members => repositories}/contact_db_repository.py (93%) rename backend/src/kwai/modules/club/{members => repositories}/contact_repository.py (100%) rename backend/src/kwai/modules/club/{members => repositories}/country_db_repository.py (91%) rename backend/src/kwai/modules/club/{members => repositories}/country_repository.py (100%) rename backend/src/kwai/modules/club/{members => repositories}/file_upload_db_repository.py (84%) rename backend/src/kwai/modules/club/{members => repositories}/file_upload_repository.py (100%) rename backend/src/kwai/modules/club/{members => repositories}/flemish_member_importer.py (97%) rename backend/src/kwai/modules/club/{members => repositories}/member_db_query.py (96%) rename backend/src/kwai/modules/club/{members => repositories}/member_db_repository.py (86%) rename backend/src/kwai/modules/club/{members => repositories}/member_importer.py (96%) rename backend/src/kwai/modules/club/{members => repositories}/member_query.py (100%) rename backend/src/kwai/modules/club/{members => repositories}/member_repository.py (96%) rename backend/src/kwai/modules/club/{members => repositories}/person_db_repository.py (91%) rename backend/src/kwai/modules/club/{members => repositories}/person_repository.py (100%) diff --git a/backend/src/kwai/api/v1/club/endpoints/members.py b/backend/src/kwai/api/v1/club/endpoints/members.py index 3c29fa97..87339862 100644 --- a/backend/src/kwai/api/v1/club/endpoints/members.py +++ b/backend/src/kwai/api/v1/club/endpoints/members.py @@ -2,15 +2,15 @@ from fastapi import APIRouter, Depends, HTTPException, Query, status from pydantic import BaseModel, Field +from tests.core.domain.test_entity import UserEntity from kwai.api.dependencies import create_database, get_current_user from kwai.api.v1.club.schemas.member import MemberDocument from kwai.core.json_api import Meta, PaginationModel from kwai.modules.club.get_member import GetMember, GetMemberCommand from kwai.modules.club.get_members import GetMembers, GetMembersCommand -from kwai.modules.club.members.member_db_repository import MemberDbRepository -from kwai.modules.club.members.member_repository import MemberNotFoundException -from tests.core.domain.test_entity import UserEntity +from kwai.modules.club.repositories.member_db_repository import MemberDbRepository +from kwai.modules.club.repositories.member_repository import MemberNotFoundException router = APIRouter() diff --git a/backend/src/kwai/api/v1/club/endpoints/upload_members.py b/backend/src/kwai/api/v1/club/endpoints/upload_members.py index 3c8a50ba..f2386951 100644 --- a/backend/src/kwai/api/v1/club/endpoints/upload_members.py +++ b/backend/src/kwai/api/v1/club/endpoints/upload_members.py @@ -19,10 +19,12 @@ ImportMembersCommand, OkResult, ) -from kwai.modules.club.members.country_db_repository import CountryDbRepository -from kwai.modules.club.members.file_upload_db_repository import FileUploadDbRepository -from kwai.modules.club.members.flemish_member_importer import FlemishMemberImporter -from kwai.modules.club.members.member_db_repository import MemberDbRepository +from kwai.modules.club.repositories.country_db_repository import CountryDbRepository +from kwai.modules.club.repositories.file_upload_db_repository import ( + FileUploadDbRepository, +) +from kwai.modules.club.repositories.flemish_member_importer import FlemishMemberImporter +from kwai.modules.club.repositories.member_db_repository import MemberDbRepository from kwai.modules.identity.users.user import UserEntity router = APIRouter() diff --git a/backend/src/kwai/modules/club/get_member.py b/backend/src/kwai/modules/club/get_member.py index 0361ec63..b4872052 100644 --- a/backend/src/kwai/modules/club/get_member.py +++ b/backend/src/kwai/modules/club/get_member.py @@ -4,7 +4,7 @@ from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.club.domain.member import MemberEntity -from kwai.modules.club.members.member_repository import MemberRepository +from kwai.modules.club.repositories.member_repository import MemberRepository @dataclass(kw_only=True, frozen=True, slots=True) diff --git a/backend/src/kwai/modules/club/get_members.py b/backend/src/kwai/modules/club/get_members.py index 848841fb..e0edd2b0 100644 --- a/backend/src/kwai/modules/club/get_members.py +++ b/backend/src/kwai/modules/club/get_members.py @@ -4,7 +4,7 @@ from kwai.core.domain.use_case import UseCaseBrowseResult from kwai.core.domain.value_objects.date import Date -from kwai.modules.club.members.member_repository import MemberRepository +from kwai.modules.club.repositories.member_repository import MemberRepository @dataclass(kw_only=True, frozen=True, slots=True) diff --git a/backend/src/kwai/modules/club/import_members.py b/backend/src/kwai/modules/club/import_members.py index fec8ead3..61e291b7 100644 --- a/backend/src/kwai/modules/club/import_members.py +++ b/backend/src/kwai/modules/club/import_members.py @@ -8,9 +8,9 @@ from kwai.core.domain.use_case import UseCaseResult from kwai.modules.club.domain.file_upload import FileUploadEntity from kwai.modules.club.domain.member import MemberEntity -from kwai.modules.club.members import member_importer -from kwai.modules.club.members.file_upload_repository import FileUploadRepository -from kwai.modules.club.members.member_repository import ( +from kwai.modules.club.repositories import member_importer +from kwai.modules.club.repositories.file_upload_repository import FileUploadRepository +from kwai.modules.club.repositories.member_repository import ( MemberNotFoundException, MemberRepository, ) diff --git a/backend/src/kwai/modules/club/members/_member_tables.py b/backend/src/kwai/modules/club/repositories/_member_tables.py similarity index 100% rename from backend/src/kwai/modules/club/members/_member_tables.py rename to backend/src/kwai/modules/club/repositories/_member_tables.py diff --git a/backend/src/kwai/modules/club/members/contact_db_repository.py b/backend/src/kwai/modules/club/repositories/contact_db_repository.py similarity index 93% rename from backend/src/kwai/modules/club/members/contact_db_repository.py rename to backend/src/kwai/modules/club/repositories/contact_db_repository.py index 499de47f..4ce65999 100644 --- a/backend/src/kwai/modules/club/members/contact_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/contact_db_repository.py @@ -8,8 +8,8 @@ from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.entity import Entity from kwai.modules.club.domain.contact import ContactEntity, ContactIdentifier -from kwai.modules.club.members._member_tables import ContactRow, CountryRow -from kwai.modules.club.members.contact_repository import ( +from kwai.modules.club.repositories._member_tables import ContactRow, CountryRow +from kwai.modules.club.repositories.contact_repository import ( ContactNotFoundException, ContactRepository, ) diff --git a/backend/src/kwai/modules/club/members/contact_repository.py b/backend/src/kwai/modules/club/repositories/contact_repository.py similarity index 100% rename from backend/src/kwai/modules/club/members/contact_repository.py rename to backend/src/kwai/modules/club/repositories/contact_repository.py diff --git a/backend/src/kwai/modules/club/members/country_db_repository.py b/backend/src/kwai/modules/club/repositories/country_db_repository.py similarity index 91% rename from backend/src/kwai/modules/club/members/country_db_repository.py rename to backend/src/kwai/modules/club/repositories/country_db_repository.py index e45e9d85..b7ca9e18 100644 --- a/backend/src/kwai/modules/club/members/country_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/country_db_repository.py @@ -5,8 +5,8 @@ from kwai.core.db.database import Database from kwai.core.domain.entity import Entity from kwai.modules.club.domain.country import CountryEntity, CountryIdentifier -from kwai.modules.club.members._member_tables import CountryRow -from kwai.modules.club.members.country_repository import ( +from kwai.modules.club.repositories._member_tables import CountryRow +from kwai.modules.club.repositories.country_repository import ( CountryNotFoundException, CountryRepository, ) diff --git a/backend/src/kwai/modules/club/members/country_repository.py b/backend/src/kwai/modules/club/repositories/country_repository.py similarity index 100% rename from backend/src/kwai/modules/club/members/country_repository.py rename to backend/src/kwai/modules/club/repositories/country_repository.py diff --git a/backend/src/kwai/modules/club/members/file_upload_db_repository.py b/backend/src/kwai/modules/club/repositories/file_upload_db_repository.py similarity index 84% rename from backend/src/kwai/modules/club/members/file_upload_db_repository.py rename to backend/src/kwai/modules/club/repositories/file_upload_db_repository.py index ded02f6c..ca0ae189 100644 --- a/backend/src/kwai/modules/club/members/file_upload_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/file_upload_db_repository.py @@ -3,8 +3,8 @@ from kwai.core.db.database import Database from kwai.core.domain.entity import Entity from kwai.modules.club.domain.file_upload import FileUploadEntity, FileUploadIdentifier -from kwai.modules.club.members._member_tables import FileUploadRow -from kwai.modules.club.members.file_upload_repository import FileUploadRepository +from kwai.modules.club.repositories._member_tables import FileUploadRow +from kwai.modules.club.repositories.file_upload_repository import FileUploadRepository class FileUploadDbRepository(FileUploadRepository): diff --git a/backend/src/kwai/modules/club/members/file_upload_repository.py b/backend/src/kwai/modules/club/repositories/file_upload_repository.py similarity index 100% rename from backend/src/kwai/modules/club/members/file_upload_repository.py rename to backend/src/kwai/modules/club/repositories/file_upload_repository.py diff --git a/backend/src/kwai/modules/club/members/flemish_member_importer.py b/backend/src/kwai/modules/club/repositories/flemish_member_importer.py similarity index 97% rename from backend/src/kwai/modules/club/members/flemish_member_importer.py rename to backend/src/kwai/modules/club/repositories/flemish_member_importer.py index 0154671a..07f481c3 100644 --- a/backend/src/kwai/modules/club/members/flemish_member_importer.py +++ b/backend/src/kwai/modules/club/repositories/flemish_member_importer.py @@ -14,11 +14,11 @@ from kwai.modules.club.domain.member import MemberEntity from kwai.modules.club.domain.person import PersonEntity from kwai.modules.club.domain.value_objects import Address, Birthdate, Gender, License -from kwai.modules.club.members.country_repository import ( +from kwai.modules.club.repositories.country_repository import ( CountryNotFoundException, CountryRepository, ) -from kwai.modules.club.members.member_importer import ( +from kwai.modules.club.repositories.member_importer import ( FailureResult, MemberImporter, OkResult, diff --git a/backend/src/kwai/modules/club/members/member_db_query.py b/backend/src/kwai/modules/club/repositories/member_db_query.py similarity index 96% rename from backend/src/kwai/modules/club/members/member_db_query.py rename to backend/src/kwai/modules/club/repositories/member_db_query.py index 10ab28f8..e6dea6c6 100644 --- a/backend/src/kwai/modules/club/members/member_db_query.py +++ b/backend/src/kwai/modules/club/repositories/member_db_query.py @@ -10,13 +10,13 @@ from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.club.domain.member import MemberEntity, MemberIdentifier -from kwai.modules.club.members._member_tables import ( +from kwai.modules.club.repositories._member_tables import ( ContactRow, CountryRow, MemberRow, PersonRow, ) -from kwai.modules.club.members.member_query import MemberQuery +from kwai.modules.club.repositories.member_query import MemberQuery @dataclass(kw_only=True, frozen=True, slots=True) diff --git a/backend/src/kwai/modules/club/members/member_db_repository.py b/backend/src/kwai/modules/club/repositories/member_db_repository.py similarity index 86% rename from backend/src/kwai/modules/club/members/member_db_repository.py rename to backend/src/kwai/modules/club/repositories/member_db_repository.py index 1dbf0d6e..31f3aee2 100644 --- a/backend/src/kwai/modules/club/members/member_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/member_db_repository.py @@ -5,14 +5,14 @@ from kwai.core.db.database import Database from kwai.core.domain.entity import Entity from kwai.modules.club.domain.member import MemberEntity, MemberIdentifier -from kwai.modules.club.members._member_tables import MemberRow -from kwai.modules.club.members.member_db_query import MemberDbQuery, MemberQueryRow -from kwai.modules.club.members.member_query import MemberQuery -from kwai.modules.club.members.member_repository import ( +from kwai.modules.club.repositories._member_tables import MemberRow +from kwai.modules.club.repositories.member_db_query import MemberDbQuery, MemberQueryRow +from kwai.modules.club.repositories.member_query import MemberQuery +from kwai.modules.club.repositories.member_repository import ( MemberNotFoundException, MemberRepository, ) -from kwai.modules.club.members.person_db_repository import PersonDbRepository +from kwai.modules.club.repositories.person_db_repository import PersonDbRepository class MemberDbRepository(MemberRepository): diff --git a/backend/src/kwai/modules/club/members/member_importer.py b/backend/src/kwai/modules/club/repositories/member_importer.py similarity index 96% rename from backend/src/kwai/modules/club/members/member_importer.py rename to backend/src/kwai/modules/club/repositories/member_importer.py index e1bc3a88..be90c6b9 100644 --- a/backend/src/kwai/modules/club/members/member_importer.py +++ b/backend/src/kwai/modules/club/repositories/member_importer.py @@ -10,7 +10,7 @@ from kwai.modules.club.domain.country import CountryEntity from kwai.modules.club.domain.file_upload import FileUploadEntity from kwai.modules.club.domain.member import MemberEntity -from kwai.modules.club.members.country_repository import CountryRepository +from kwai.modules.club.repositories.country_repository import CountryRepository @dataclass(kw_only=True, frozen=True, slots=True) diff --git a/backend/src/kwai/modules/club/members/member_query.py b/backend/src/kwai/modules/club/repositories/member_query.py similarity index 100% rename from backend/src/kwai/modules/club/members/member_query.py rename to backend/src/kwai/modules/club/repositories/member_query.py diff --git a/backend/src/kwai/modules/club/members/member_repository.py b/backend/src/kwai/modules/club/repositories/member_repository.py similarity index 96% rename from backend/src/kwai/modules/club/members/member_repository.py rename to backend/src/kwai/modules/club/repositories/member_repository.py index 7a334339..443ab4f2 100644 --- a/backend/src/kwai/modules/club/members/member_repository.py +++ b/backend/src/kwai/modules/club/repositories/member_repository.py @@ -4,7 +4,7 @@ from typing import AsyncGenerator from kwai.modules.club.domain.member import MemberEntity -from kwai.modules.club.members.member_query import MemberQuery +from kwai.modules.club.repositories.member_query import MemberQuery class MemberNotFoundException(Exception): diff --git a/backend/src/kwai/modules/club/members/person_db_repository.py b/backend/src/kwai/modules/club/repositories/person_db_repository.py similarity index 91% rename from backend/src/kwai/modules/club/members/person_db_repository.py rename to backend/src/kwai/modules/club/repositories/person_db_repository.py index b10fc9ee..0211ee1a 100644 --- a/backend/src/kwai/modules/club/members/person_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/person_db_repository.py @@ -8,9 +8,13 @@ from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.entity import Entity from kwai.modules.club.domain.person import PersonEntity, PersonIdentifier -from kwai.modules.club.members._member_tables import ContactRow, CountryRow, PersonRow -from kwai.modules.club.members.contact_db_repository import ContactDbRepository -from kwai.modules.club.members.person_repository import ( +from kwai.modules.club.repositories._member_tables import ( + ContactRow, + CountryRow, + PersonRow, +) +from kwai.modules.club.repositories.contact_db_repository import ContactDbRepository +from kwai.modules.club.repositories.person_repository import ( PersonNotFoundException, PersonRepository, ) diff --git a/backend/src/kwai/modules/club/members/person_repository.py b/backend/src/kwai/modules/club/repositories/person_repository.py similarity index 100% rename from backend/src/kwai/modules/club/members/person_repository.py rename to backend/src/kwai/modules/club/repositories/person_repository.py diff --git a/backend/src/tests/fixtures/club/contacts.py b/backend/src/tests/fixtures/club/contacts.py index 0ed93b15..8d4fb91d 100644 --- a/backend/src/tests/fixtures/club/contacts.py +++ b/backend/src/tests/fixtures/club/contacts.py @@ -16,7 +16,7 @@ from kwai.modules.club.domain.contact import ContactEntity from kwai.modules.club.domain.country import CountryEntity from kwai.modules.club.domain.value_objects import Address -from kwai.modules.club.members.contact_db_repository import ContactDbRepository +from kwai.modules.club.repositories.contact_db_repository import ContactDbRepository class AddressType(TypedDict): diff --git a/backend/src/tests/fixtures/club/countries.py b/backend/src/tests/fixtures/club/countries.py index eb2046af..ce6e1c13 100644 --- a/backend/src/tests/fixtures/club/countries.py +++ b/backend/src/tests/fixtures/club/countries.py @@ -12,8 +12,8 @@ from kwai.core.db.database import Database from kwai.core.db.uow import UnitOfWork from kwai.modules.club.domain.country import CountryEntity -from kwai.modules.club.members.country_db_repository import CountryDbRepository -from kwai.modules.club.members.country_repository import CountryNotFoundException +from kwai.modules.club.repositories.country_db_repository import CountryDbRepository +from kwai.modules.club.repositories.country_repository import CountryNotFoundException class CountryType(TypedDict): diff --git a/backend/src/tests/fixtures/club/members.py b/backend/src/tests/fixtures/club/members.py index 329a46c0..56b07fb4 100644 --- a/backend/src/tests/fixtures/club/members.py +++ b/backend/src/tests/fixtures/club/members.py @@ -9,7 +9,7 @@ from kwai.modules.club.domain.member import MemberEntity from kwai.modules.club.domain.person import PersonEntity from kwai.modules.club.domain.value_objects import License -from kwai.modules.club.members.member_db_repository import MemberDbRepository +from kwai.modules.club.repositories.member_db_repository import MemberDbRepository MemberFixtureFactory: TypeAlias = Callable[[License | None], MemberEntity] diff --git a/backend/src/tests/fixtures/club/persons.py b/backend/src/tests/fixtures/club/persons.py index 6164c7c5..cf8d1d28 100644 --- a/backend/src/tests/fixtures/club/persons.py +++ b/backend/src/tests/fixtures/club/persons.py @@ -9,7 +9,7 @@ from kwai.modules.club.domain.country import CountryEntity from kwai.modules.club.domain.person import PersonEntity from kwai.modules.club.domain.value_objects import Birthdate, Gender -from kwai.modules.club.members.person_db_repository import PersonDbRepository +from kwai.modules.club.repositories.person_db_repository import PersonDbRepository @pytest.fixture diff --git a/backend/src/tests/modules/club/members/test_contact_db_repository.py b/backend/src/tests/modules/club/members/test_contact_db_repository.py index 39f7b2d0..a7835575 100644 --- a/backend/src/tests/modules/club/members/test_contact_db_repository.py +++ b/backend/src/tests/modules/club/members/test_contact_db_repository.py @@ -1,12 +1,11 @@ """Module for testing the contact repository for a database.""" import pytest - from kwai.core.db.database import Database from kwai.core.db.uow import UnitOfWork from kwai.core.domain.entity import Entity -from kwai.modules.club.members.contact_db_repository import ContactDbRepository -from kwai.modules.club.members.contact_repository import ( +from kwai.modules.club.repositories.contact_db_repository import ContactDbRepository +from kwai.modules.club.repositories.contact_repository import ( ContactNotFoundException, ContactRepository, ) diff --git a/backend/src/tests/modules/club/members/test_country_db_repository.py b/backend/src/tests/modules/club/members/test_country_db_repository.py index c91054e0..7747a348 100644 --- a/backend/src/tests/modules/club/members/test_country_db_repository.py +++ b/backend/src/tests/modules/club/members/test_country_db_repository.py @@ -3,8 +3,8 @@ import pytest from kwai.core.db.database import Database from kwai.modules.club.domain.country import CountryEntity -from kwai.modules.club.members.country_db_repository import CountryDbRepository -from kwai.modules.club.members.country_repository import ( +from kwai.modules.club.repositories.country_db_repository import CountryDbRepository +from kwai.modules.club.repositories.country_repository import ( CountryNotFoundException, CountryRepository, ) diff --git a/backend/src/tests/modules/club/members/test_file_upload_db_repository.py b/backend/src/tests/modules/club/members/test_file_upload_db_repository.py index 81fb0512..f3c53863 100644 --- a/backend/src/tests/modules/club/members/test_file_upload_db_repository.py +++ b/backend/src/tests/modules/club/members/test_file_upload_db_repository.py @@ -4,7 +4,9 @@ from kwai.core.db.database import Database from kwai.core.domain.value_objects.owner import Owner from kwai.modules.club.domain.file_upload import FileUploadEntity -from kwai.modules.club.members.file_upload_db_repository import FileUploadDbRepository +from kwai.modules.club.repositories.file_upload_db_repository import ( + FileUploadDbRepository, +) pytestmark = pytest.mark.db diff --git a/backend/src/tests/modules/club/members/test_flemish_member_importer.py b/backend/src/tests/modules/club/members/test_flemish_member_importer.py index 5c0f13a5..b105c3ad 100644 --- a/backend/src/tests/modules/club/members/test_flemish_member_importer.py +++ b/backend/src/tests/modules/club/members/test_flemish_member_importer.py @@ -6,9 +6,9 @@ from kwai.core.db.database import Database from kwai.core.domain.value_objects.owner import Owner from kwai.modules.club.domain.value_objects import Gender -from kwai.modules.club.members.country_db_repository import CountryDbRepository -from kwai.modules.club.members.flemish_member_importer import FlemishMemberImporter -from kwai.modules.club.members.member_importer import Result +from kwai.modules.club.repositories.country_db_repository import CountryDbRepository +from kwai.modules.club.repositories.flemish_member_importer import FlemishMemberImporter +from kwai.modules.club.repositories.member_importer import Result pytestmark = pytest.mark.db diff --git a/backend/src/tests/modules/club/members/test_member_db_query.py b/backend/src/tests/modules/club/members/test_member_db_query.py index 2cc676b9..d467b3d6 100644 --- a/backend/src/tests/modules/club/members/test_member_db_query.py +++ b/backend/src/tests/modules/club/members/test_member_db_query.py @@ -4,8 +4,8 @@ from kwai.core.db.database import Database from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.club.domain.member import MemberIdentifier -from kwai.modules.club.members.member_db_query import MemberDbQuery -from kwai.modules.club.members.member_query import MemberQuery +from kwai.modules.club.repositories.member_db_query import MemberDbQuery +from kwai.modules.club.repositories.member_query import MemberQuery pytestmark = pytest.mark.db diff --git a/backend/src/tests/modules/club/members/test_member_db_repository.py b/backend/src/tests/modules/club/members/test_member_db_repository.py index a1c46122..e252704f 100644 --- a/backend/src/tests/modules/club/members/test_member_db_repository.py +++ b/backend/src/tests/modules/club/members/test_member_db_repository.py @@ -1,12 +1,11 @@ """Module for testing the member database repository.""" import pytest - from kwai.core.db.database import Database from kwai.core.db.uow import UnitOfWork from kwai.core.domain.entity import Entity -from kwai.modules.club.members.member_db_repository import MemberDbRepository -from kwai.modules.club.members.member_repository import ( +from kwai.modules.club.repositories.member_db_repository import MemberDbRepository +from kwai.modules.club.repositories.member_repository import ( MemberNotFoundException, MemberRepository, ) diff --git a/backend/src/tests/modules/club/members/test_person_db_repository.py b/backend/src/tests/modules/club/members/test_person_db_repository.py index 40885d21..dc2d9465 100644 --- a/backend/src/tests/modules/club/members/test_person_db_repository.py +++ b/backend/src/tests/modules/club/members/test_person_db_repository.py @@ -1,12 +1,11 @@ """Module for testing the person repository for a database.""" import pytest - from kwai.core.db.database import Database from kwai.core.db.uow import UnitOfWork from kwai.core.domain.entity import Entity -from kwai.modules.club.members.person_db_repository import PersonDbRepository -from kwai.modules.club.members.person_repository import ( +from kwai.modules.club.repositories.person_db_repository import PersonDbRepository +from kwai.modules.club.repositories.person_repository import ( PersonNotFoundException, PersonRepository, ) diff --git a/backend/src/tests/modules/club/test_get_member.py b/backend/src/tests/modules/club/test_get_member.py index 5ddf1645..64cfe421 100644 --- a/backend/src/tests/modules/club/test_get_member.py +++ b/backend/src/tests/modules/club/test_get_member.py @@ -1,11 +1,10 @@ """Module for testing the use case 'Get Member'.""" import pytest - from kwai.core.db.database import Database from kwai.modules.club.get_member import GetMember, GetMemberCommand -from kwai.modules.club.members.member_db_repository import MemberDbRepository -from kwai.modules.club.members.member_repository import MemberRepository +from kwai.modules.club.repositories.member_db_repository import MemberDbRepository +from kwai.modules.club.repositories.member_repository import MemberRepository @pytest.fixture diff --git a/backend/src/tests/modules/club/test_get_members.py b/backend/src/tests/modules/club/test_get_members.py index 37fb722f..bc771361 100644 --- a/backend/src/tests/modules/club/test_get_members.py +++ b/backend/src/tests/modules/club/test_get_members.py @@ -5,8 +5,8 @@ from kwai.core.domain.value_objects.date import Date from kwai.modules.club.domain.value_objects import License from kwai.modules.club.get_members import GetMembers, GetMembersCommand -from kwai.modules.club.members.member_db_repository import MemberDbRepository -from kwai.modules.club.members.member_repository import MemberRepository +from kwai.modules.club.repositories.member_db_repository import MemberDbRepository +from kwai.modules.club.repositories.member_repository import MemberRepository @pytest.fixture diff --git a/backend/src/tests/modules/club/test_import_members.py b/backend/src/tests/modules/club/test_import_members.py index ceceaca0..18210003 100644 --- a/backend/src/tests/modules/club/test_import_members.py +++ b/backend/src/tests/modules/club/test_import_members.py @@ -5,10 +5,12 @@ from kwai.core.db.database import Database from kwai.core.domain.value_objects.owner import Owner from kwai.modules.club.import_members import ImportMembers, ImportMembersCommand -from kwai.modules.club.members.country_db_repository import CountryDbRepository -from kwai.modules.club.members.file_upload_db_repository import FileUploadDbRepository -from kwai.modules.club.members.flemish_member_importer import FlemishMemberImporter -from kwai.modules.club.members.member_db_repository import MemberDbRepository +from kwai.modules.club.repositories.country_db_repository import CountryDbRepository +from kwai.modules.club.repositories.file_upload_db_repository import ( + FileUploadDbRepository, +) +from kwai.modules.club.repositories.flemish_member_importer import FlemishMemberImporter +from kwai.modules.club.repositories.member_db_repository import MemberDbRepository async def test_import_members(database: Database, owner: Owner): From 419cd412bef8392c387b8c0ede27ff0371a7ec80 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 21:44:56 +0200 Subject: [PATCH 019/410] refactor: removed unused package --- backend/src/kwai/modules/club/members/__init__.py | 1 - 1 file changed, 1 deletion(-) delete mode 100644 backend/src/kwai/modules/club/members/__init__.py diff --git a/backend/src/kwai/modules/club/members/__init__.py b/backend/src/kwai/modules/club/members/__init__.py deleted file mode 100644 index f103a4d4..00000000 --- a/backend/src/kwai/modules/club/members/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Package for all modules related to members.""" From 4ecb1c7fdfc3bf0d3f4e8da2f3dcd851b318c404 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 20 May 2024 21:46:43 +0200 Subject: [PATCH 020/410] refactor: move tests --- backend/src/tests/modules/club/{members => }/domain/__init__.py | 0 .../tests/modules/club/{members => }/domain/test_birthdate.py | 0 .../src/tests/modules/club/{members => }/domain/test_contact.py | 0 backend/src/tests/modules/club/repositories/__init__.py | 1 + .../club/{members => repositories}/data/flemish_members_test.csv | 0 .../club/{members => repositories}/test_contact_db_repository.py | 0 .../club/{members => repositories}/test_country_db_repository.py | 0 .../{members => repositories}/test_file_upload_db_repository.py | 0 .../{members => repositories}/test_flemish_member_importer.py | 0 .../club/{members => repositories}/test_member_db_query.py | 0 .../club/{members => repositories}/test_member_db_repository.py | 0 .../club/{members => repositories}/test_person_db_repository.py | 0 12 files changed, 1 insertion(+) rename backend/src/tests/modules/club/{members => }/domain/__init__.py (100%) rename backend/src/tests/modules/club/{members => }/domain/test_birthdate.py (100%) rename backend/src/tests/modules/club/{members => }/domain/test_contact.py (100%) create mode 100644 backend/src/tests/modules/club/repositories/__init__.py rename backend/src/tests/modules/club/{members => repositories}/data/flemish_members_test.csv (100%) rename backend/src/tests/modules/club/{members => repositories}/test_contact_db_repository.py (100%) rename backend/src/tests/modules/club/{members => repositories}/test_country_db_repository.py (100%) rename backend/src/tests/modules/club/{members => repositories}/test_file_upload_db_repository.py (100%) rename backend/src/tests/modules/club/{members => repositories}/test_flemish_member_importer.py (100%) rename backend/src/tests/modules/club/{members => repositories}/test_member_db_query.py (100%) rename backend/src/tests/modules/club/{members => repositories}/test_member_db_repository.py (100%) rename backend/src/tests/modules/club/{members => repositories}/test_person_db_repository.py (100%) diff --git a/backend/src/tests/modules/club/members/domain/__init__.py b/backend/src/tests/modules/club/domain/__init__.py similarity index 100% rename from backend/src/tests/modules/club/members/domain/__init__.py rename to backend/src/tests/modules/club/domain/__init__.py diff --git a/backend/src/tests/modules/club/members/domain/test_birthdate.py b/backend/src/tests/modules/club/domain/test_birthdate.py similarity index 100% rename from backend/src/tests/modules/club/members/domain/test_birthdate.py rename to backend/src/tests/modules/club/domain/test_birthdate.py diff --git a/backend/src/tests/modules/club/members/domain/test_contact.py b/backend/src/tests/modules/club/domain/test_contact.py similarity index 100% rename from backend/src/tests/modules/club/members/domain/test_contact.py rename to backend/src/tests/modules/club/domain/test_contact.py diff --git a/backend/src/tests/modules/club/repositories/__init__.py b/backend/src/tests/modules/club/repositories/__init__.py new file mode 100644 index 00000000..b36b2884 --- /dev/null +++ b/backend/src/tests/modules/club/repositories/__init__.py @@ -0,0 +1 @@ +"""Package for testing the club repositories.""" diff --git a/backend/src/tests/modules/club/members/data/flemish_members_test.csv b/backend/src/tests/modules/club/repositories/data/flemish_members_test.csv similarity index 100% rename from backend/src/tests/modules/club/members/data/flemish_members_test.csv rename to backend/src/tests/modules/club/repositories/data/flemish_members_test.csv diff --git a/backend/src/tests/modules/club/members/test_contact_db_repository.py b/backend/src/tests/modules/club/repositories/test_contact_db_repository.py similarity index 100% rename from backend/src/tests/modules/club/members/test_contact_db_repository.py rename to backend/src/tests/modules/club/repositories/test_contact_db_repository.py diff --git a/backend/src/tests/modules/club/members/test_country_db_repository.py b/backend/src/tests/modules/club/repositories/test_country_db_repository.py similarity index 100% rename from backend/src/tests/modules/club/members/test_country_db_repository.py rename to backend/src/tests/modules/club/repositories/test_country_db_repository.py diff --git a/backend/src/tests/modules/club/members/test_file_upload_db_repository.py b/backend/src/tests/modules/club/repositories/test_file_upload_db_repository.py similarity index 100% rename from backend/src/tests/modules/club/members/test_file_upload_db_repository.py rename to backend/src/tests/modules/club/repositories/test_file_upload_db_repository.py diff --git a/backend/src/tests/modules/club/members/test_flemish_member_importer.py b/backend/src/tests/modules/club/repositories/test_flemish_member_importer.py similarity index 100% rename from backend/src/tests/modules/club/members/test_flemish_member_importer.py rename to backend/src/tests/modules/club/repositories/test_flemish_member_importer.py diff --git a/backend/src/tests/modules/club/members/test_member_db_query.py b/backend/src/tests/modules/club/repositories/test_member_db_query.py similarity index 100% rename from backend/src/tests/modules/club/members/test_member_db_query.py rename to backend/src/tests/modules/club/repositories/test_member_db_query.py diff --git a/backend/src/tests/modules/club/members/test_member_db_repository.py b/backend/src/tests/modules/club/repositories/test_member_db_repository.py similarity index 100% rename from backend/src/tests/modules/club/members/test_member_db_repository.py rename to backend/src/tests/modules/club/repositories/test_member_db_repository.py diff --git a/backend/src/tests/modules/club/members/test_person_db_repository.py b/backend/src/tests/modules/club/repositories/test_person_db_repository.py similarity index 100% rename from backend/src/tests/modules/club/members/test_person_db_repository.py rename to backend/src/tests/modules/club/repositories/test_person_db_repository.py From 090b5bec62104eb55e0008644a676a39c07af86a Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 21 May 2024 21:23:54 +0200 Subject: [PATCH 021/410] ci: upgrade mypy --- backend/poetry.lock | 58 +++++++++++++++++++++--------------------- backend/pyproject.toml | 2 +- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/backend/poetry.lock b/backend/poetry.lock index 5195c6ce..230a9012 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -1441,38 +1441,38 @@ files = [ [[package]] name = "mypy" -version = "1.9.0" +version = "1.10.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f8a67616990062232ee4c3952f41c779afac41405806042a8126fe96e098419f"}, - {file = "mypy-1.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d357423fa57a489e8c47b7c85dfb96698caba13d66e086b412298a1a0ea3b0ed"}, - {file = "mypy-1.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49c87c15aed320de9b438ae7b00c1ac91cd393c1b854c2ce538e2a72d55df150"}, - {file = "mypy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:48533cdd345c3c2e5ef48ba3b0d3880b257b423e7995dada04248725c6f77374"}, - {file = "mypy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:4d3dbd346cfec7cb98e6cbb6e0f3c23618af826316188d587d1c1bc34f0ede03"}, - {file = "mypy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:653265f9a2784db65bfca694d1edd23093ce49740b2244cde583aeb134c008f3"}, - {file = "mypy-1.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a3c007ff3ee90f69cf0a15cbcdf0995749569b86b6d2f327af01fd1b8aee9dc"}, - {file = "mypy-1.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2418488264eb41f69cc64a69a745fad4a8f86649af4b1041a4c64ee61fc61129"}, - {file = "mypy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:68edad3dc7d70f2f17ae4c6c1b9471a56138ca22722487eebacfd1eb5321d612"}, - {file = "mypy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:85ca5fcc24f0b4aeedc1d02f93707bccc04733f21d41c88334c5482219b1ccb3"}, - {file = "mypy-1.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aceb1db093b04db5cd390821464504111b8ec3e351eb85afd1433490163d60cd"}, - {file = "mypy-1.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0235391f1c6f6ce487b23b9dbd1327b4ec33bb93934aa986efe8a9563d9349e6"}, - {file = "mypy-1.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4d5ddc13421ba3e2e082a6c2d74c2ddb3979c39b582dacd53dd5d9431237185"}, - {file = "mypy-1.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:190da1ee69b427d7efa8aa0d5e5ccd67a4fb04038c380237a0d96829cb157913"}, - {file = "mypy-1.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:fe28657de3bfec596bbeef01cb219833ad9d38dd5393fc649f4b366840baefe6"}, - {file = "mypy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e54396d70be04b34f31d2edf3362c1edd023246c82f1730bbf8768c28db5361b"}, - {file = "mypy-1.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5e6061f44f2313b94f920e91b204ec600982961e07a17e0f6cd83371cb23f5c2"}, - {file = "mypy-1.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a10926e5473c5fc3da8abb04119a1f5811a236dc3a38d92015cb1e6ba4cb9e"}, - {file = "mypy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b685154e22e4e9199fc95f298661deea28aaede5ae16ccc8cbb1045e716b3e04"}, - {file = "mypy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:5d741d3fc7c4da608764073089e5f58ef6352bedc223ff58f2f038c2c4698a89"}, - {file = "mypy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:587ce887f75dd9700252a3abbc9c97bbe165a4a630597845c61279cf32dfbf02"}, - {file = "mypy-1.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f88566144752999351725ac623471661c9d1cd8caa0134ff98cceeea181789f4"}, - {file = "mypy-1.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61758fabd58ce4b0720ae1e2fea5cfd4431591d6d590b197775329264f86311d"}, - {file = "mypy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e49499be624dead83927e70c756970a0bc8240e9f769389cdf5714b0784ca6bf"}, - {file = "mypy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:571741dc4194b4f82d344b15e8837e8c5fcc462d66d076748142327626a1b6e9"}, - {file = "mypy-1.9.0-py3-none-any.whl", hash = "sha256:a260627a570559181a9ea5de61ac6297aa5af202f06fd7ab093ce74e7181e43e"}, - {file = "mypy-1.9.0.tar.gz", hash = "sha256:3cc5da0127e6a478cddd906068496a97a7618a21ce9b54bde5bf7e539c7af974"}, + {file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, + {file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, + {file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, + {file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, + {file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, + {file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, + {file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, + {file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, + {file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, + {file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, + {file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, + {file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, + {file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, + {file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, + {file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, + {file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, + {file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, + {file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, + {file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, + {file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, + {file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, + {file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, + {file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, + {file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, + {file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, + {file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, + {file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, ] [package.dependencies] @@ -2982,4 +2982,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "0ed7f7d661cf7de2e3d5718340ecfbfc9226a7dd80d1cfb00d4d99c8377d9f1b" +content-hash = "2b12520a57ad5a38e9c51528adcc0bf89a8893ba3ffc9ac1a2861102b4ed1d82" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 2b198824..b8d0e2ea 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -33,7 +33,7 @@ optional = true [tool.poetry.group.dev.dependencies] pytest = "^8.1.1" black = {extras = ["d"], version = "^24.3.0"} -mypy = "^1.9.0" +mypy = "^1.10.0" ruff = "~0.3.4" pytest-sugar = "^1.0.0" httpx = "^0.26.0" From 596f89ef250e1ed616d610b6aec027bb0f50f8b4 Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 21 May 2024 21:25:45 +0200 Subject: [PATCH 022/410] refactor: introduce presenters --- .../src/kwai/api/v1/club/endpoints/members.py | 21 ++++----- backend/src/kwai/api/v1/club/presenters.py | 43 +++++++++++++++++++ backend/src/kwai/core/domain/presenter.py | 30 +++++++++++++ backend/src/kwai/modules/club/get_member.py | 10 +++-- backend/src/kwai/modules/club/get_members.py | 19 +++++--- 5 files changed, 102 insertions(+), 21 deletions(-) create mode 100644 backend/src/kwai/api/v1/club/presenters.py create mode 100644 backend/src/kwai/core/domain/presenter.py diff --git a/backend/src/kwai/api/v1/club/endpoints/members.py b/backend/src/kwai/api/v1/club/endpoints/members.py index 87339862..065cbb96 100644 --- a/backend/src/kwai/api/v1/club/endpoints/members.py +++ b/backend/src/kwai/api/v1/club/endpoints/members.py @@ -2,15 +2,16 @@ from fastapi import APIRouter, Depends, HTTPException, Query, status from pydantic import BaseModel, Field -from tests.core.domain.test_entity import UserEntity from kwai.api.dependencies import create_database, get_current_user +from kwai.api.v1.club.presenters import JsonApiMemberPresenter, JsonApiMembersPresenter from kwai.api.v1.club.schemas.member import MemberDocument -from kwai.core.json_api import Meta, PaginationModel +from kwai.core.json_api import PaginationModel from kwai.modules.club.get_member import GetMember, GetMemberCommand from kwai.modules.club.get_members import GetMembers, GetMembersCommand from kwai.modules.club.repositories.member_db_repository import MemberDbRepository from kwai.modules.club.repositories.member_repository import MemberNotFoundException +from kwai.modules.identity.users.user import UserEntity router = APIRouter() @@ -38,15 +39,10 @@ async def get_members( license_end_year=members_filter.license_end_year, license_end_month=members_filter.license_end_month, ) - count, member_iterator = await GetMembers(MemberDbRepository(db)).execute(command) - result = MemberDocument( - meta=Meta(count=count, offset=command.offset, limit=command.limit), data=[] - ) - async for member in member_iterator: - member_document = MemberDocument.create(member) - result.merge(member_document) + presenter = JsonApiMembersPresenter(offset=command.offset, limit=command.limit) + await GetMembers(MemberDbRepository(db), presenter).execute(command) - return result + return presenter.get_document() @router.get("/members/{uuid}") @@ -58,11 +54,12 @@ async def get_member( """Get a member with the given unique id.""" command = GetMemberCommand(uuid=uuid) + presenter = JsonApiMemberPresenter() try: - member = await GetMember(MemberDbRepository(db)).execute(command) + await GetMember(MemberDbRepository(db), presenter).execute(command) except MemberNotFoundException as ex: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=str(ex) ) from ex - return MemberDocument.create(member) + return presenter.get_document() diff --git a/backend/src/kwai/api/v1/club/presenters.py b/backend/src/kwai/api/v1/club/presenters.py new file mode 100644 index 00000000..e26bf602 --- /dev/null +++ b/backend/src/kwai/api/v1/club/presenters.py @@ -0,0 +1,43 @@ +"""Module that defines presenters for the club api.""" + +from kwai.api.v1.club.schemas.member import MemberDocument +from kwai.core.domain.presenter import IterableResult, Presenter +from kwai.core.json_api import Meta +from kwai.modules.club.domain.member import MemberEntity + + +class JsonApiPresenter[Document]: + """An interface for a presenter that generates a JSON:API document.""" + + def __init__(self): + self._document: Document = None + + def get_document(self) -> Document: + """Return the JSON:API document.""" + return self._document + + +class JsonApiMemberPresenter(JsonApiPresenter[MemberDocument], Presenter[MemberEntity]): + """A presenter that transform a member entity into a JSON:API document.""" + + def handle(self, member: MemberEntity) -> None: + self._document = MemberDocument.create(member) + + +class JsonApiMembersPresenter( + JsonApiPresenter[MemberDocument], Presenter[IterableResult[MemberEntity]] +): + """A presenter that transform an iterator for members into a JSON:API document.""" + + def __init__(self, offset: int = 0, limit: int = 0): + self._offset = offset + self._limit = limit + + async def handle(self, result: IterableResult[MemberEntity]) -> None: + self._document = MemberDocument( + meta=Meta(count=result.count, offset=self._offset, limit=self._limit), + data=[], + ) + async for member in result.iterator: + member_document = MemberDocument.create(member) + self._document.merge(member_document) diff --git a/backend/src/kwai/core/domain/presenter.py b/backend/src/kwai/core/domain/presenter.py new file mode 100644 index 00000000..118dc84d --- /dev/null +++ b/backend/src/kwai/core/domain/presenter.py @@ -0,0 +1,30 @@ +"""Module for defining a presenter.""" + +from abc import ABC, abstractmethod +from dataclasses import dataclass +from typing import AsyncIterator + + +@dataclass(frozen=True, kw_only=True, slots=True) +class IterableResult[T]: + """A dataclass used to represent a result with multiple entities.""" + + count: int + iterator: AsyncIterator[T] + + +class Presenter[T](ABC): + """An interface for a presenter. + + A presenter is used to transform an entity into another object. + + An example: convert to a JSON:API resource for returning the entity in a restful + API. + """ + + @abstractmethod + async def handle(self, use_case_result: T) -> None: + """Handle the entity. + + This method is responsible for converting the entity. + """ diff --git a/backend/src/kwai/modules/club/get_member.py b/backend/src/kwai/modules/club/get_member.py index b4872052..a8fa50f3 100644 --- a/backend/src/kwai/modules/club/get_member.py +++ b/backend/src/kwai/modules/club/get_member.py @@ -2,6 +2,7 @@ from dataclasses import dataclass +from kwai.core.domain.presenter import Presenter from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.club.domain.member import MemberEntity from kwai.modules.club.repositories.member_repository import MemberRepository @@ -21,15 +22,17 @@ class GetMemberCommand: class GetMember: """Use case 'Get Member'.""" - def __init__(self, repo: MemberRepository): + def __init__(self, repo: MemberRepository, presenter: Presenter[MemberEntity]): """Initialize the use case. Args: repo: The repository used to get the member. + presenter: The presenter used to handle the result of the use case. """ self._repo = repo + self._presenter = presenter - async def execute(self, command: GetMemberCommand) -> MemberEntity: + async def execute(self, command: GetMemberCommand) -> None: """Execute the use case. Args: @@ -44,4 +47,5 @@ async def execute(self, command: GetMemberCommand) -> MemberEntity: query = self._repo.create_query() query.filter_by_uuid(UniqueId.create_from_string(command.uuid)) - return await self._repo.get(query) + member = await self._repo.get(query) + self._presenter.handle(member) diff --git a/backend/src/kwai/modules/club/get_members.py b/backend/src/kwai/modules/club/get_members.py index e0edd2b0..cd4c23cc 100644 --- a/backend/src/kwai/modules/club/get_members.py +++ b/backend/src/kwai/modules/club/get_members.py @@ -2,8 +2,9 @@ from dataclasses import dataclass -from kwai.core.domain.use_case import UseCaseBrowseResult +from kwai.core.domain.presenter import IterableResult, Presenter from kwai.core.domain.value_objects.date import Date +from kwai.modules.club.domain.member import MemberEntity from kwai.modules.club.repositories.member_repository import MemberRepository @@ -29,15 +30,19 @@ class GetMembersCommand: class GetMembers: """Use case get members.""" - def __init__(self, repo: MemberRepository): + def __init__( + self, repo: MemberRepository, presenter: Presenter[IterableResult[MemberEntity]] + ): """Initialize use case. Args: repo: The repository for members. + presenter: The presenter for members. """ self._repo = repo + self._presenter = presenter - async def execute(self, command: GetMembersCommand) -> UseCaseBrowseResult: + async def execute(self, command: GetMembersCommand): """Execute the use case. Args: @@ -53,7 +58,9 @@ async def execute(self, command: GetMembersCommand) -> UseCaseBrowseResult: command.license_end_month, command.license_end_year or Date.today().year ) - return UseCaseBrowseResult( - count=await query.count(), - iterator=self._repo.get_all(query, command.limit, command.offset), + await self._presenter.handle( + IterableResult( + count=await query.count(), + iterator=self._repo.get_all(query, command.limit, command.offset), + ) ) From cbc576673191a668de9bfc9edd4db26ff622b393 Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 21 May 2024 21:32:52 +0200 Subject: [PATCH 023/410] refactor: add AsyncPresenter --- backend/src/kwai/api/v1/club/presenters.py | 4 ++-- backend/src/kwai/core/domain/presenter.py | 17 +++++++++++++++++ backend/src/kwai/modules/club/get_members.py | 6 ++++-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/backend/src/kwai/api/v1/club/presenters.py b/backend/src/kwai/api/v1/club/presenters.py index e26bf602..fe2ab324 100644 --- a/backend/src/kwai/api/v1/club/presenters.py +++ b/backend/src/kwai/api/v1/club/presenters.py @@ -1,7 +1,7 @@ """Module that defines presenters for the club api.""" from kwai.api.v1.club.schemas.member import MemberDocument -from kwai.core.domain.presenter import IterableResult, Presenter +from kwai.core.domain.presenter import AsyncPresenter, IterableResult, Presenter from kwai.core.json_api import Meta from kwai.modules.club.domain.member import MemberEntity @@ -25,7 +25,7 @@ def handle(self, member: MemberEntity) -> None: class JsonApiMembersPresenter( - JsonApiPresenter[MemberDocument], Presenter[IterableResult[MemberEntity]] + JsonApiPresenter[MemberDocument], AsyncPresenter[IterableResult[MemberEntity]] ): """A presenter that transform an iterator for members into a JSON:API document.""" diff --git a/backend/src/kwai/core/domain/presenter.py b/backend/src/kwai/core/domain/presenter.py index 118dc84d..cc88fb34 100644 --- a/backend/src/kwai/core/domain/presenter.py +++ b/backend/src/kwai/core/domain/presenter.py @@ -22,6 +22,23 @@ class Presenter[T](ABC): API. """ + @abstractmethod + def handle(self, use_case_result: T) -> None: + """Handle the entity. + + This method is responsible for converting the entity. + """ + + +class AsyncPresenter[T](ABC): + """An interface for an async presenter. + + A presenter is used to transform an entity into another object. + + An example: convert to a JSON:API resource for returning the entity in a restful + API. + """ + @abstractmethod async def handle(self, use_case_result: T) -> None: """Handle the entity. diff --git a/backend/src/kwai/modules/club/get_members.py b/backend/src/kwai/modules/club/get_members.py index cd4c23cc..5a808e6c 100644 --- a/backend/src/kwai/modules/club/get_members.py +++ b/backend/src/kwai/modules/club/get_members.py @@ -2,7 +2,7 @@ from dataclasses import dataclass -from kwai.core.domain.presenter import IterableResult, Presenter +from kwai.core.domain.presenter import AsyncPresenter, IterableResult from kwai.core.domain.value_objects.date import Date from kwai.modules.club.domain.member import MemberEntity from kwai.modules.club.repositories.member_repository import MemberRepository @@ -31,7 +31,9 @@ class GetMembers: """Use case get members.""" def __init__( - self, repo: MemberRepository, presenter: Presenter[IterableResult[MemberEntity]] + self, + repo: MemberRepository, + presenter: AsyncPresenter[IterableResult[MemberEntity]], ): """Initialize use case. From afdf92a75fe51cb072bed54fd62c16144c41b048 Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 22 May 2024 20:17:09 +0200 Subject: [PATCH 024/410] refactor: add limit and offset to IterableResult --- backend/src/kwai/api/v1/club/presenters.py | 6 +----- backend/src/kwai/core/domain/presenter.py | 2 ++ backend/src/kwai/modules/club/get_members.py | 2 ++ 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/src/kwai/api/v1/club/presenters.py b/backend/src/kwai/api/v1/club/presenters.py index fe2ab324..00f7158c 100644 --- a/backend/src/kwai/api/v1/club/presenters.py +++ b/backend/src/kwai/api/v1/club/presenters.py @@ -29,13 +29,9 @@ class JsonApiMembersPresenter( ): """A presenter that transform an iterator for members into a JSON:API document.""" - def __init__(self, offset: int = 0, limit: int = 0): - self._offset = offset - self._limit = limit - async def handle(self, result: IterableResult[MemberEntity]) -> None: self._document = MemberDocument( - meta=Meta(count=result.count, offset=self._offset, limit=self._limit), + meta=Meta(count=result.count, offset=result.offset, limit=result.limit), data=[], ) async for member in result.iterator: diff --git a/backend/src/kwai/core/domain/presenter.py b/backend/src/kwai/core/domain/presenter.py index cc88fb34..8885025b 100644 --- a/backend/src/kwai/core/domain/presenter.py +++ b/backend/src/kwai/core/domain/presenter.py @@ -10,6 +10,8 @@ class IterableResult[T]: """A dataclass used to represent a result with multiple entities.""" count: int + offset: int = 0 + limit: int = 0 iterator: AsyncIterator[T] diff --git a/backend/src/kwai/modules/club/get_members.py b/backend/src/kwai/modules/club/get_members.py index 5a808e6c..26716886 100644 --- a/backend/src/kwai/modules/club/get_members.py +++ b/backend/src/kwai/modules/club/get_members.py @@ -63,6 +63,8 @@ async def execute(self, command: GetMembersCommand): await self._presenter.handle( IterableResult( count=await query.count(), + limit=command.limit, + offset=command.offset, iterator=self._repo.get_all(query, command.limit, command.offset), ) ) From e95f28e4eb358d68de331f03358a3454d1f04c55 Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 22 May 2024 21:22:06 +0200 Subject: [PATCH 025/410] refactor: a presenter presents... --- backend/src/kwai/api/v1/club/presenters.py | 4 ++-- backend/src/kwai/core/domain/presenter.py | 14 ++++++++------ backend/src/kwai/modules/club/get_member.py | 2 +- backend/src/kwai/modules/club/get_members.py | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/backend/src/kwai/api/v1/club/presenters.py b/backend/src/kwai/api/v1/club/presenters.py index 00f7158c..b92edc4e 100644 --- a/backend/src/kwai/api/v1/club/presenters.py +++ b/backend/src/kwai/api/v1/club/presenters.py @@ -20,7 +20,7 @@ def get_document(self) -> Document: class JsonApiMemberPresenter(JsonApiPresenter[MemberDocument], Presenter[MemberEntity]): """A presenter that transform a member entity into a JSON:API document.""" - def handle(self, member: MemberEntity) -> None: + def present(self, member: MemberEntity) -> None: self._document = MemberDocument.create(member) @@ -29,7 +29,7 @@ class JsonApiMembersPresenter( ): """A presenter that transform an iterator for members into a JSON:API document.""" - async def handle(self, result: IterableResult[MemberEntity]) -> None: + async def present(self, result: IterableResult[MemberEntity]) -> None: self._document = MemberDocument( meta=Meta(count=result.count, offset=result.offset, limit=result.limit), data=[], diff --git a/backend/src/kwai/core/domain/presenter.py b/backend/src/kwai/core/domain/presenter.py index 8885025b..5b15eb51 100644 --- a/backend/src/kwai/core/domain/presenter.py +++ b/backend/src/kwai/core/domain/presenter.py @@ -18,15 +18,16 @@ class IterableResult[T]: class Presenter[T](ABC): """An interface for a presenter. - A presenter is used to transform an entity into another object. + A presenter is used to transform an entity into another object that can be used + in a view. An example: convert to a JSON:API resource for returning the entity in a restful API. """ @abstractmethod - def handle(self, use_case_result: T) -> None: - """Handle the entity. + def present(self, use_case_result: T) -> None: + """Present the entity. This method is responsible for converting the entity. """ @@ -35,15 +36,16 @@ def handle(self, use_case_result: T) -> None: class AsyncPresenter[T](ABC): """An interface for an async presenter. - A presenter is used to transform an entity into another object. + A presenter is used to transform an entity into another object that can be used + in a view. An example: convert to a JSON:API resource for returning the entity in a restful API. """ @abstractmethod - async def handle(self, use_case_result: T) -> None: - """Handle the entity. + async def present(self, use_case_result: T) -> None: + """Present the entity. This method is responsible for converting the entity. """ diff --git a/backend/src/kwai/modules/club/get_member.py b/backend/src/kwai/modules/club/get_member.py index a8fa50f3..bd736c4e 100644 --- a/backend/src/kwai/modules/club/get_member.py +++ b/backend/src/kwai/modules/club/get_member.py @@ -48,4 +48,4 @@ async def execute(self, command: GetMemberCommand) -> None: query.filter_by_uuid(UniqueId.create_from_string(command.uuid)) member = await self._repo.get(query) - self._presenter.handle(member) + self._presenter.present(member) diff --git a/backend/src/kwai/modules/club/get_members.py b/backend/src/kwai/modules/club/get_members.py index 26716886..9172252e 100644 --- a/backend/src/kwai/modules/club/get_members.py +++ b/backend/src/kwai/modules/club/get_members.py @@ -60,7 +60,7 @@ async def execute(self, command: GetMembersCommand): command.license_end_month, command.license_end_year or Date.today().year ) - await self._presenter.handle( + await self._presenter.present( IterableResult( count=await query.count(), limit=command.limit, From cd47e1ef26c891c1bfe5bfa8ab1db54cb22b7de3 Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 22 May 2024 21:22:26 +0200 Subject: [PATCH 026/410] refactor: limit/offset is handled in presenter --- backend/src/kwai/api/v1/club/endpoints/members.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/kwai/api/v1/club/endpoints/members.py b/backend/src/kwai/api/v1/club/endpoints/members.py index 065cbb96..f573eea3 100644 --- a/backend/src/kwai/api/v1/club/endpoints/members.py +++ b/backend/src/kwai/api/v1/club/endpoints/members.py @@ -39,7 +39,7 @@ async def get_members( license_end_year=members_filter.license_end_year, license_end_month=members_filter.license_end_month, ) - presenter = JsonApiMembersPresenter(offset=command.offset, limit=command.limit) + presenter = JsonApiMembersPresenter() await GetMembers(MemberDbRepository(db), presenter).execute(command) return presenter.get_document() From abc745a72c8ce9170e35926d692193d4f5c55998 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 24 May 2024 19:36:24 +0200 Subject: [PATCH 027/410] feat: add preview --- backend/migrations/20240525191900_upload_preview.sql | 5 +++++ backend/migrations/db/schema.sql | 4 +++- backend/src/kwai/modules/club/domain/file_upload.py | 10 +++++++++- .../kwai/modules/club/repositories/_member_tables.py | 2 ++ 4 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 backend/migrations/20240525191900_upload_preview.sql diff --git a/backend/migrations/20240525191900_upload_preview.sql b/backend/migrations/20240525191900_upload_preview.sql new file mode 100644 index 00000000..e7fa8796 --- /dev/null +++ b/backend/migrations/20240525191900_upload_preview.sql @@ -0,0 +1,5 @@ +-- migrate:up + +alter table imports add column preview tinyint(1) default 0 not null; + +-- migrate:down diff --git a/backend/migrations/db/schema.sql b/backend/migrations/db/schema.sql index 9e96d898..2fac7524 100644 --- a/backend/migrations/db/schema.sql +++ b/backend/migrations/db/schema.sql @@ -108,6 +108,7 @@ CREATE TABLE `imports` ( `user_id` int NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NULL DEFAULT NULL, + `preview` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; @@ -586,5 +587,6 @@ INSERT INTO `schema_migrations` (version) VALUES ('20230128205126'), ('20231110160912'), ('20240201192100'), - ('20240502185700'); + ('20240502185700'), + ('20240525191900'); UNLOCK TABLES; diff --git a/backend/src/kwai/modules/club/domain/file_upload.py b/backend/src/kwai/modules/club/domain/file_upload.py index 59911bc4..f0974740 100644 --- a/backend/src/kwai/modules/club/domain/file_upload.py +++ b/backend/src/kwai/modules/club/domain/file_upload.py @@ -20,6 +20,7 @@ def __init__( filename: str, owner: Owner, remark: str = "", + preview: bool = False, traceable_time: TraceableTime | None = None, ): """Initialize a file upload entity. @@ -28,8 +29,9 @@ def __init__( id_: The id of the upload. uuid: The unique id of the upload. filename: The name of the file. - remark: A remark about the upload. owner: The user who uploaded the file. + remark: A remark about the upload. + preview: Whether the upload is a preview. traceable_time: The creation and modification timestamp of the upload. """ super().__init__(id_ or FileUploadIdentifier()) @@ -37,6 +39,7 @@ def __init__( self._filename = filename self._owner = owner self._remark = remark + self._preview = preview self._traceable_time = traceable_time or TraceableTime() @property @@ -59,6 +62,11 @@ def uuid(self) -> UniqueId: """Return the uuid.""" return self._uuid + @property + def preview(self) -> bool: + """Return the preview.""" + return self._preview + @property def traceable_time(self) -> TraceableTime: """Return the creation/modification time.""" diff --git a/backend/src/kwai/modules/club/repositories/_member_tables.py b/backend/src/kwai/modules/club/repositories/_member_tables.py index 0a663ed5..e94aae27 100644 --- a/backend/src/kwai/modules/club/repositories/_member_tables.py +++ b/backend/src/kwai/modules/club/repositories/_member_tables.py @@ -90,6 +90,7 @@ class FileUploadRow(TableRow): uuid: str filename: str remark: str + preview: int user_id: int created_at: datetime updated_at: datetime | None @@ -106,6 +107,7 @@ def persist(cls, file_upload: FileUploadEntity) -> Self: uuid=str(file_upload.uuid), filename=file_upload.filename, remark=file_upload.remark, + preview=1 if file_upload.preview else 0, user_id=file_upload.owner.id.value, created_at=file_upload.traceable_time.created_at.timestamp, # type: ignore[arg-type] updated_at=file_upload.traceable_time.updated_at.timestamp, From 76e9414686bbb7c78b98bc6310092aeee945af07 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 24 May 2024 19:39:14 +0200 Subject: [PATCH 028/410] refactor: rename _member_tables.py into _tables.py --- .../modules/club/repositories/{_member_tables.py => _tables.py} | 0 .../src/kwai/modules/club/repositories/contact_db_repository.py | 2 +- .../src/kwai/modules/club/repositories/country_db_repository.py | 2 +- .../kwai/modules/club/repositories/file_upload_db_repository.py | 2 +- backend/src/kwai/modules/club/repositories/member_db_query.py | 2 +- .../src/kwai/modules/club/repositories/member_db_repository.py | 2 +- .../src/kwai/modules/club/repositories/person_db_repository.py | 2 +- 7 files changed, 6 insertions(+), 6 deletions(-) rename backend/src/kwai/modules/club/repositories/{_member_tables.py => _tables.py} (100%) diff --git a/backend/src/kwai/modules/club/repositories/_member_tables.py b/backend/src/kwai/modules/club/repositories/_tables.py similarity index 100% rename from backend/src/kwai/modules/club/repositories/_member_tables.py rename to backend/src/kwai/modules/club/repositories/_tables.py diff --git a/backend/src/kwai/modules/club/repositories/contact_db_repository.py b/backend/src/kwai/modules/club/repositories/contact_db_repository.py index 4ce65999..297dcf9d 100644 --- a/backend/src/kwai/modules/club/repositories/contact_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/contact_db_repository.py @@ -8,7 +8,7 @@ from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.entity import Entity from kwai.modules.club.domain.contact import ContactEntity, ContactIdentifier -from kwai.modules.club.repositories._member_tables import ContactRow, CountryRow +from kwai.modules.club.repositories._tables import ContactRow, CountryRow from kwai.modules.club.repositories.contact_repository import ( ContactNotFoundException, ContactRepository, diff --git a/backend/src/kwai/modules/club/repositories/country_db_repository.py b/backend/src/kwai/modules/club/repositories/country_db_repository.py index b7ca9e18..d578c3e5 100644 --- a/backend/src/kwai/modules/club/repositories/country_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/country_db_repository.py @@ -5,7 +5,7 @@ from kwai.core.db.database import Database from kwai.core.domain.entity import Entity from kwai.modules.club.domain.country import CountryEntity, CountryIdentifier -from kwai.modules.club.repositories._member_tables import CountryRow +from kwai.modules.club.repositories._tables import CountryRow from kwai.modules.club.repositories.country_repository import ( CountryNotFoundException, CountryRepository, diff --git a/backend/src/kwai/modules/club/repositories/file_upload_db_repository.py b/backend/src/kwai/modules/club/repositories/file_upload_db_repository.py index ca0ae189..8af26946 100644 --- a/backend/src/kwai/modules/club/repositories/file_upload_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/file_upload_db_repository.py @@ -3,7 +3,7 @@ from kwai.core.db.database import Database from kwai.core.domain.entity import Entity from kwai.modules.club.domain.file_upload import FileUploadEntity, FileUploadIdentifier -from kwai.modules.club.repositories._member_tables import FileUploadRow +from kwai.modules.club.repositories._tables import FileUploadRow from kwai.modules.club.repositories.file_upload_repository import FileUploadRepository diff --git a/backend/src/kwai/modules/club/repositories/member_db_query.py b/backend/src/kwai/modules/club/repositories/member_db_query.py index e6dea6c6..b6aa4f59 100644 --- a/backend/src/kwai/modules/club/repositories/member_db_query.py +++ b/backend/src/kwai/modules/club/repositories/member_db_query.py @@ -10,7 +10,7 @@ from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.club.domain.member import MemberEntity, MemberIdentifier -from kwai.modules.club.repositories._member_tables import ( +from kwai.modules.club.repositories._tables import ( ContactRow, CountryRow, MemberRow, diff --git a/backend/src/kwai/modules/club/repositories/member_db_repository.py b/backend/src/kwai/modules/club/repositories/member_db_repository.py index 31f3aee2..e3690c0c 100644 --- a/backend/src/kwai/modules/club/repositories/member_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/member_db_repository.py @@ -5,7 +5,7 @@ from kwai.core.db.database import Database from kwai.core.domain.entity import Entity from kwai.modules.club.domain.member import MemberEntity, MemberIdentifier -from kwai.modules.club.repositories._member_tables import MemberRow +from kwai.modules.club.repositories._tables import MemberRow from kwai.modules.club.repositories.member_db_query import MemberDbQuery, MemberQueryRow from kwai.modules.club.repositories.member_query import MemberQuery from kwai.modules.club.repositories.member_repository import ( diff --git a/backend/src/kwai/modules/club/repositories/person_db_repository.py b/backend/src/kwai/modules/club/repositories/person_db_repository.py index 0211ee1a..a61364eb 100644 --- a/backend/src/kwai/modules/club/repositories/person_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/person_db_repository.py @@ -8,7 +8,7 @@ from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.entity import Entity from kwai.modules.club.domain.person import PersonEntity, PersonIdentifier -from kwai.modules.club.repositories._member_tables import ( +from kwai.modules.club.repositories._tables import ( ContactRow, CountryRow, PersonRow, From f14fdd9df185fbacd7bc081605dc2dfd239d7e15 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 24 May 2024 19:39:14 +0200 Subject: [PATCH 029/410] refactor: rename _member_tables.py into _tables.py --- backend/src/kwai/modules/club/import_members.py | 2 +- .../club/repositories/{_member_tables.py => _tables.py} | 0 .../kwai/modules/club/repositories/contact_db_repository.py | 2 +- .../kwai/modules/club/repositories/country_db_repository.py | 2 +- .../modules/club/repositories/file_upload_db_repository.py | 2 +- .../src/kwai/modules/club/repositories/member_db_query.py | 2 +- .../kwai/modules/club/repositories/member_db_repository.py | 2 +- .../src/kwai/modules/club/repositories/member_importer.py | 6 ++++-- .../kwai/modules/club/repositories/person_db_repository.py | 2 +- 9 files changed, 11 insertions(+), 9 deletions(-) rename backend/src/kwai/modules/club/repositories/{_member_tables.py => _tables.py} (100%) diff --git a/backend/src/kwai/modules/club/import_members.py b/backend/src/kwai/modules/club/import_members.py index 61e291b7..6a41ed99 100644 --- a/backend/src/kwai/modules/club/import_members.py +++ b/backend/src/kwai/modules/club/import_members.py @@ -81,7 +81,7 @@ async def execute( FailureResult: When the row was not successfully imported. """ file_upload_entity = await self._file_upload_repo.create( - self._importer.create_file_upload_entity() + self._importer.create_file_upload_entity(command.preview) ) async for import_result in self._importer.import_(): match import_result: diff --git a/backend/src/kwai/modules/club/repositories/_member_tables.py b/backend/src/kwai/modules/club/repositories/_tables.py similarity index 100% rename from backend/src/kwai/modules/club/repositories/_member_tables.py rename to backend/src/kwai/modules/club/repositories/_tables.py diff --git a/backend/src/kwai/modules/club/repositories/contact_db_repository.py b/backend/src/kwai/modules/club/repositories/contact_db_repository.py index 4ce65999..297dcf9d 100644 --- a/backend/src/kwai/modules/club/repositories/contact_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/contact_db_repository.py @@ -8,7 +8,7 @@ from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.entity import Entity from kwai.modules.club.domain.contact import ContactEntity, ContactIdentifier -from kwai.modules.club.repositories._member_tables import ContactRow, CountryRow +from kwai.modules.club.repositories._tables import ContactRow, CountryRow from kwai.modules.club.repositories.contact_repository import ( ContactNotFoundException, ContactRepository, diff --git a/backend/src/kwai/modules/club/repositories/country_db_repository.py b/backend/src/kwai/modules/club/repositories/country_db_repository.py index b7ca9e18..d578c3e5 100644 --- a/backend/src/kwai/modules/club/repositories/country_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/country_db_repository.py @@ -5,7 +5,7 @@ from kwai.core.db.database import Database from kwai.core.domain.entity import Entity from kwai.modules.club.domain.country import CountryEntity, CountryIdentifier -from kwai.modules.club.repositories._member_tables import CountryRow +from kwai.modules.club.repositories._tables import CountryRow from kwai.modules.club.repositories.country_repository import ( CountryNotFoundException, CountryRepository, diff --git a/backend/src/kwai/modules/club/repositories/file_upload_db_repository.py b/backend/src/kwai/modules/club/repositories/file_upload_db_repository.py index ca0ae189..8af26946 100644 --- a/backend/src/kwai/modules/club/repositories/file_upload_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/file_upload_db_repository.py @@ -3,7 +3,7 @@ from kwai.core.db.database import Database from kwai.core.domain.entity import Entity from kwai.modules.club.domain.file_upload import FileUploadEntity, FileUploadIdentifier -from kwai.modules.club.repositories._member_tables import FileUploadRow +from kwai.modules.club.repositories._tables import FileUploadRow from kwai.modules.club.repositories.file_upload_repository import FileUploadRepository diff --git a/backend/src/kwai/modules/club/repositories/member_db_query.py b/backend/src/kwai/modules/club/repositories/member_db_query.py index e6dea6c6..b6aa4f59 100644 --- a/backend/src/kwai/modules/club/repositories/member_db_query.py +++ b/backend/src/kwai/modules/club/repositories/member_db_query.py @@ -10,7 +10,7 @@ from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.club.domain.member import MemberEntity, MemberIdentifier -from kwai.modules.club.repositories._member_tables import ( +from kwai.modules.club.repositories._tables import ( ContactRow, CountryRow, MemberRow, diff --git a/backend/src/kwai/modules/club/repositories/member_db_repository.py b/backend/src/kwai/modules/club/repositories/member_db_repository.py index 31f3aee2..e3690c0c 100644 --- a/backend/src/kwai/modules/club/repositories/member_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/member_db_repository.py @@ -5,7 +5,7 @@ from kwai.core.db.database import Database from kwai.core.domain.entity import Entity from kwai.modules.club.domain.member import MemberEntity, MemberIdentifier -from kwai.modules.club.repositories._member_tables import MemberRow +from kwai.modules.club.repositories._tables import MemberRow from kwai.modules.club.repositories.member_db_query import MemberDbQuery, MemberQueryRow from kwai.modules.club.repositories.member_query import MemberQuery from kwai.modules.club.repositories.member_repository import ( diff --git a/backend/src/kwai/modules/club/repositories/member_importer.py b/backend/src/kwai/modules/club/repositories/member_importer.py index be90c6b9..e1e85a18 100644 --- a/backend/src/kwai/modules/club/repositories/member_importer.py +++ b/backend/src/kwai/modules/club/repositories/member_importer.py @@ -56,9 +56,11 @@ def import_(self) -> AsyncGenerator[Result, None]: For each imported (or failed import) of a member, a result will be yielded. """ - def create_file_upload_entity(self) -> FileUploadEntity: + def create_file_upload_entity(self, preview: bool) -> FileUploadEntity: """Create a file upload entity.""" - return FileUploadEntity(filename=self._filename, owner=self._owner) + return FileUploadEntity( + filename=self._filename, owner=self._owner, preview=preview + ) @staticmethod @alru_cache diff --git a/backend/src/kwai/modules/club/repositories/person_db_repository.py b/backend/src/kwai/modules/club/repositories/person_db_repository.py index 0211ee1a..a61364eb 100644 --- a/backend/src/kwai/modules/club/repositories/person_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/person_db_repository.py @@ -8,7 +8,7 @@ from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.entity import Entity from kwai.modules.club.domain.person import PersonEntity, PersonIdentifier -from kwai.modules.club.repositories._member_tables import ( +from kwai.modules.club.repositories._tables import ( ContactRow, CountryRow, PersonRow, From da13732065788fad35872a9f26e66f3c5cf9355d Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 15:10:19 +0200 Subject: [PATCH 030/410] feat: JSON:API for an upload entity --- .../src/kwai/api/v1/club/schemas/upload.py | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 backend/src/kwai/api/v1/club/schemas/upload.py diff --git a/backend/src/kwai/api/v1/club/schemas/upload.py b/backend/src/kwai/api/v1/club/schemas/upload.py new file mode 100644 index 00000000..3504fd8d --- /dev/null +++ b/backend/src/kwai/api/v1/club/schemas/upload.py @@ -0,0 +1,46 @@ +"""Module for defining the JSON:API resource for an upload.""" + +from types import NoneType +from typing import Self + +from pydantic import BaseModel + +from kwai.api.v1.club.schemas.resources import ( + UploadResourceIdentifier, +) +from kwai.core.json_api import Document, ResourceData, ResourceMeta +from kwai.modules.club.domain.file_upload import FileUploadEntity + + +class UploadAttributes(BaseModel): + """Attributes for the upload JSON:API resource.""" + + filename: str + remark: str + preview: bool + + +class UploadResource( + UploadResourceIdentifier, ResourceData[UploadAttributes, NoneType] +): + """A JSON:API resource for an upload.""" + + +class UploadDocument(Document[UploadResource, NoneType]): + """A JSON:API document for an upload.""" + + @classmethod + def create(cls, upload: FileUploadEntity) -> Self: + """Create a document for an upload.""" + upload_resource = UploadResource( + id=str(upload.uuid), + attributes=UploadAttributes( + filename=upload.filename, remark=upload.remark, preview=upload.preview + ), + meta=ResourceMeta( + created_at=str(upload.traceable_time.created_at), + updated_at=str(upload.traceable_time.updated_at), + ), + ) + + return cls(data=upload_resource) From 9fde5d571977155eb51a2e178180106d9170fafe Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 15:10:36 +0200 Subject: [PATCH 031/410] chore: add MemberUploadRow --- .../kwai/modules/club/repositories/_tables.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/backend/src/kwai/modules/club/repositories/_tables.py b/backend/src/kwai/modules/club/repositories/_tables.py index e94aae27..120397c2 100644 --- a/backend/src/kwai/modules/club/repositories/_tables.py +++ b/backend/src/kwai/modules/club/repositories/_tables.py @@ -275,3 +275,22 @@ def persist(cls, member: MemberEntity) -> Self: created_at=member.traceable_time.created_at.timestamp, # type: ignore[arg-type] updated_at=member.traceable_time.updated_at.timestamp, ) + + +@dataclass(kw_only=True, frozen=True, slots=True) +class MemberUploadRow(TableRow): + """Represents a row of the judo member imports table.""" + + __table_name__ = "judo_member_imports" + + member_id: int + import_id: int + created_at: datetime + + @classmethod + def persist(cls, upload: FileUploadEntity, member: MemberEntity) -> Self: + return cls( + member_id=member.id.value, + import_id=upload.id.value, + created_at=datetime.now(UTC), + ) From 25d28b3d2f542042b585b07fc2b15a45f822b08b Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 15:10:54 +0200 Subject: [PATCH 032/410] chore: add save_member --- .../club/repositories/file_upload_db_repository.py | 10 ++++++++-- .../club/repositories/file_upload_repository.py | 11 +++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/backend/src/kwai/modules/club/repositories/file_upload_db_repository.py b/backend/src/kwai/modules/club/repositories/file_upload_db_repository.py index 8af26946..eb8b263f 100644 --- a/backend/src/kwai/modules/club/repositories/file_upload_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/file_upload_db_repository.py @@ -3,7 +3,8 @@ from kwai.core.db.database import Database from kwai.core.domain.entity import Entity from kwai.modules.club.domain.file_upload import FileUploadEntity, FileUploadIdentifier -from kwai.modules.club.repositories._tables import FileUploadRow +from kwai.modules.club.domain.member import MemberEntity +from kwai.modules.club.repositories._tables import FileUploadRow, MemberUploadRow from kwai.modules.club.repositories.file_upload_repository import FileUploadRepository @@ -22,5 +23,10 @@ async def create(self, file_upload: FileUploadEntity) -> FileUploadEntity: new_id = await self._database.insert( FileUploadRow.__table_name__, FileUploadRow.persist(file_upload) ) - await self._database.commit() return Entity.replace(file_upload, id_=FileUploadIdentifier(new_id)) + + async def save_member(self, file_upload: FileUploadEntity, member: MemberEntity): + await self._database.insert( + MemberUploadRow.__table_name__, + MemberUploadRow.persist(file_upload, member), + ) diff --git a/backend/src/kwai/modules/club/repositories/file_upload_repository.py b/backend/src/kwai/modules/club/repositories/file_upload_repository.py index c003101c..5fe282b8 100644 --- a/backend/src/kwai/modules/club/repositories/file_upload_repository.py +++ b/backend/src/kwai/modules/club/repositories/file_upload_repository.py @@ -3,6 +3,7 @@ from abc import ABC, abstractmethod from kwai.modules.club.domain.file_upload import FileUploadEntity +from kwai.modules.club.domain.member import MemberEntity class FileUploadRepository(ABC): @@ -19,3 +20,13 @@ async def create(self, file_upload: FileUploadEntity) -> FileUploadEntity: file_upload: A fileupload to save. """ raise NotImplementedError + + @abstractmethod + async def save_member(self, file_upload: FileUploadEntity, member: MemberEntity): + """Save a member imported from the file upload. + + Args: + file_upload: The file upload. + member: The member from the file upload. + """ + raise NotImplementedError From f3aa527277b5895274b7101c5f91b639cff15a3e Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 15:11:21 +0200 Subject: [PATCH 033/410] chore: add resource identifier for Upload resource --- backend/src/kwai/api/v1/club/schemas/resources.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/backend/src/kwai/api/v1/club/schemas/resources.py b/backend/src/kwai/api/v1/club/schemas/resources.py index c179e8df..c94f3004 100644 --- a/backend/src/kwai/api/v1/club/schemas/resources.py +++ b/backend/src/kwai/api/v1/club/schemas/resources.py @@ -27,3 +27,9 @@ class CountryResourceIdentifier(ResourceIdentifier): """A JSON:API resource identifier for a country.""" type: Literal["countries"] = "countries" + + +class UploadResourceIdentifier(ResourceIdentifier): + """A JSON:API resource identifier for a upload.""" + + type: Literal["uploads"] = "uploads" From 29a17d82cdf22d858d9c26d5738202c644aefccc Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 15:12:56 +0200 Subject: [PATCH 034/410] refactor: use presenter for member upload --- .../api/v1/club/endpoints/upload_members.py | 50 +++-------------- backend/src/kwai/api/v1/club/presenters.py | 44 +++++++++++++++ .../src/kwai/modules/club/import_members.py | 53 ++++++++++--------- .../tests/modules/club/test_import_members.py | 32 +++++++++-- 4 files changed, 108 insertions(+), 71 deletions(-) diff --git a/backend/src/kwai/api/v1/club/endpoints/upload_members.py b/backend/src/kwai/api/v1/club/endpoints/upload_members.py index f2386951..0fbe69a7 100644 --- a/backend/src/kwai/api/v1/club/endpoints/upload_members.py +++ b/backend/src/kwai/api/v1/club/endpoints/upload_members.py @@ -3,21 +3,19 @@ from pathlib import Path from typing import Annotated -from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status +from fastapi import APIRouter, Depends, File, HTTPException, Query, UploadFile, status from pydantic import BaseModel, Field from kwai.api.dependencies import create_database, get_current_user +from kwai.api.v1.club.presenters import JsonApiUploadMemberPresenter from kwai.api.v1.club.schemas.member import MemberDocument from kwai.core.db.database import Database from kwai.core.db.uow import UnitOfWork from kwai.core.functions import generate_filenames -from kwai.core.json_api import Meta from kwai.core.settings import Settings, get_settings from kwai.modules.club.import_members import ( - FailureResult, ImportMembers, ImportMembersCommand, - OkResult, ) from kwai.modules.club.repositories.country_db_repository import CountryDbRepository from kwai.modules.club.repositories.file_upload_db_repository import ( @@ -56,6 +54,7 @@ async def upload( settings: Annotated[Settings, Depends(get_settings)], database: Annotated[Database, Depends(create_database)], user: Annotated[UserEntity, Depends(get_current_user)], + preview: Annotated[bool, Query(description="Whether or not to preview")] = True, ) -> MemberDocument: """Upload a members csv file.""" if member_file.filename is None: @@ -72,8 +71,9 @@ async def upload( detail=f"Failed to upload members file: {ex}", ) from ex + presenter = JsonApiUploadMemberPresenter() async with UnitOfWork(database): - imported_member_generator = ImportMembers( + await ImportMembers( FlemishMemberImporter( str(member_filename), user.create_owner(), @@ -81,43 +81,9 @@ async def upload( ), FileUploadDbRepository(database), MemberDbRepository(database), - ).execute(ImportMembersCommand()) - - meta = Meta(count=0, offset=0, limit=0, errors=[]) - response = MemberDocument(meta=meta, data=[]) - upload_entity = None - async for result in imported_member_generator: - if upload_entity is None: - upload_entity = result.file_upload - - match result: - case OkResult(): - member_document = MemberDocument.create(result.member) - member_document.resource.meta.row = result.row - member_document.resource.meta.new = not result.member.has_id() - # A new member has related resources that are not saved yet, - # so give them temporarily the same id as the member. - if member_document.resource.meta.new: - member_document.resource.relationships.person.data.id = ( - member_document.resource.id - ) - for included in member_document.included: - if included.type == "persons": - included.relationships.contact.data.id = ( - member_document.resource.id - ) - if included.id == "0": - included.id = member_document.resource.id - meta.count += 1 - response.merge(member_document) - case FailureResult(): - meta.errors.append({"row": result.row, "message": result.to_message()}) - case _: - raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, - detail="Unexpected result returned", - ) - return response + presenter, + ).execute(ImportMembersCommand(preview=preview)) + return presenter.get_document() async def upload_file(uploaded_file, path: str): diff --git a/backend/src/kwai/api/v1/club/presenters.py b/backend/src/kwai/api/v1/club/presenters.py index b92edc4e..6f5ccef0 100644 --- a/backend/src/kwai/api/v1/club/presenters.py +++ b/backend/src/kwai/api/v1/club/presenters.py @@ -4,6 +4,11 @@ from kwai.core.domain.presenter import AsyncPresenter, IterableResult, Presenter from kwai.core.json_api import Meta from kwai.modules.club.domain.member import MemberEntity +from kwai.modules.club.import_members import ( + FailureMemberImportResult, + MemberImportResult, + OkMemberImportResult, +) class JsonApiPresenter[Document]: @@ -37,3 +42,42 @@ async def present(self, result: IterableResult[MemberEntity]) -> None: async for member in result.iterator: member_document = MemberDocument.create(member) self._document.merge(member_document) + + +class JsonApiUploadMemberPresenter( + JsonApiPresenter[MemberDocument], Presenter[MemberImportResult] +): + """A presenter that transform a file upload of a member into a JSON:API document.""" + + def __init__(self) -> None: + super().__init__() + self._meta = Meta(count=0, offset=0, limit=0, errors=[]) + + def present(self, result: MemberImportResult) -> None: + if self._document is None: + self._document = MemberDocument(data=[]) + + match result: + case OkMemberImportResult(): + member_document = MemberDocument.create(result.member) + member_document.resource.meta.row = result.row + member_document.resource.meta.new = not result.member.has_id() + # A new member has related resources that are not saved yet, + # so give them temporarily the same id as the member. + if member_document.resource.meta.new: + member_document.resource.relationships.person.data.id = ( + member_document.resource.id + ) + for included in member_document.included: + if included.type == "persons": + included.relationships.contact.data.id = ( + member_document.resource.id + ) + if included.id == "0": + included.id = member_document.resource.id + self._meta.count += 1 + self._document.merge(member_document) + case FailureMemberImportResult(): + self._meta.errors.append( + {"row": result.row, "message": result.to_message()} + ) diff --git a/backend/src/kwai/modules/club/import_members.py b/backend/src/kwai/modules/club/import_members.py index 6a41ed99..8d336d59 100644 --- a/backend/src/kwai/modules/club/import_members.py +++ b/backend/src/kwai/modules/club/import_members.py @@ -2,9 +2,9 @@ from abc import ABC from dataclasses import dataclass -from typing import AsyncGenerator from kwai.core.domain.entity import Entity +from kwai.core.domain.presenter import Presenter from kwai.core.domain.use_case import UseCaseResult from kwai.modules.club.domain.file_upload import FileUploadEntity from kwai.modules.club.domain.member import MemberEntity @@ -17,7 +17,7 @@ @dataclass(kw_only=True, slots=True, frozen=True) -class Result(UseCaseResult, ABC): +class MemberImportResult(UseCaseResult, ABC): """The result of the use case ImportMembers.""" file_upload: FileUploadEntity @@ -25,7 +25,7 @@ class Result(UseCaseResult, ABC): @dataclass(kw_only=True, slots=True, frozen=True) -class OkResult(Result): +class OkMemberImportResult(MemberImportResult): """A successful import of a member.""" member: MemberEntity @@ -35,7 +35,7 @@ def to_message(self) -> str: @dataclass(kw_only=True, slots=True, frozen=True) -class FailureResult(Result): +class FailureMemberImportResult(MemberImportResult): """An import of a member failed.""" message: str @@ -59,6 +59,7 @@ def __init__( importer: member_importer.MemberImporter, file_upload_repo: FileUploadRepository, member_repo: MemberRepository, + presenter: Presenter, ): """Initialize the use case. @@ -66,20 +67,15 @@ def __init__( importer: A class that is responsible for importing members from a resource. file_upload_repo: A repository for storing the file upload information. member_repo: A repository for managing members. + presenter: A presenter """ self._importer = importer self._file_upload_repo = file_upload_repo self._member_repo = member_repo + self._presenter = presenter - async def execute( - self, command: ImportMembersCommand - ) -> AsyncGenerator[Result, None]: - """Execute the use case. - - Yields: - OkResult: When the row was successfully imported. - FailureResult: When the row was not successfully imported. - """ + async def execute(self, command: ImportMembersCommand): + """Execute the use case.""" file_upload_entity = await self._file_upload_repo.create( self._importer.create_file_upload_entity(command.preview) ) @@ -87,30 +83,39 @@ async def execute( match import_result: case member_importer.OkResult(): member = await self._save_member( - import_result.member, command.preview + file_upload_entity, import_result.member, command.preview ) - yield OkResult( - file_upload=file_upload_entity, - row=import_result.row, - member=member, + self._presenter.present( + OkMemberImportResult( + file_upload=file_upload_entity, + row=import_result.row, + member=member, + ) ) case member_importer.FailureResult(): - yield FailureResult( - file_upload=file_upload_entity, - row=import_result.row, - message=import_result.message, + self._present.present( + FailureMemberImportResult( + file_upload=file_upload_entity, + row=import_result.row, + message=import_result.message, + ) ) - async def _save_member(self, member: MemberEntity, preview: bool) -> MemberEntity: + async def _save_member( + self, file_upload: FileUploadEntity, member: MemberEntity, preview: bool + ) -> MemberEntity: """Create or update the member.""" existing_member = await self._get_member(member) if existing_member is not None: updated_member = self._update_member(existing_member, member) if not preview: await self._member_repo.update(updated_member) + await self._file_upload_repo.save_member(file_upload, updated_member) return updated_member + if not preview: - return await self._member_repo.create(member) + member = await self._member_repo.create(member) + await self._file_upload_repo.save_member(file_upload, member) return member @classmethod diff --git a/backend/src/tests/modules/club/test_import_members.py b/backend/src/tests/modules/club/test_import_members.py index 18210003..bb149228 100644 --- a/backend/src/tests/modules/club/test_import_members.py +++ b/backend/src/tests/modules/club/test_import_members.py @@ -3,6 +3,7 @@ from pathlib import Path from kwai.core.db.database import Database +from kwai.core.domain.presenter import Presenter from kwai.core.domain.value_objects.owner import Owner from kwai.modules.club.import_members import ImportMembers, ImportMembersCommand from kwai.modules.club.repositories.country_db_repository import CountryDbRepository @@ -13,16 +14,37 @@ from kwai.modules.club.repositories.member_db_repository import MemberDbRepository +class DummyPresenter[MemberImportResult](Presenter): + """A dummy presenter.""" + + def __init__(self): + super().__init__() + self._count = 0 + + @property + def count(self): + """Return the count.""" + return self._count + + def present(self, use_case_result: MemberImportResult) -> None: + self._count += 1 + + async def test_import_members(database: Database, owner: Owner): """Test the use case Import Members.""" - filename = Path(__file__).parent / "members" / "data" / "flemish_members_test.csv" + filename = Path(__file__).parent / "data" / "flemish_members_test.csv" importer = FlemishMemberImporter( str(filename), owner, CountryDbRepository(database) ) command = ImportMembersCommand() - async for result in ImportMembers( - importer, FileUploadDbRepository(database), MemberDbRepository(database) - ).execute(command): - assert result.file_upload is not None, "There should be a fileupload result" + presenter = DummyPresenter() + await ImportMembers( + importer, + FileUploadDbRepository(database), + MemberDbRepository(database), + presenter, + ).execute(command) + + assert presenter.count > 0, "There should be a member uploaded." From 0e358689a0f884632631b27ca65d1d656915f706 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 15:13:06 +0200 Subject: [PATCH 035/410] refactor: date moved --- .../modules/club/{repositories => }/data/flemish_members_test.csv | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename backend/src/tests/modules/club/{repositories => }/data/flemish_members_test.csv (100%) diff --git a/backend/src/tests/modules/club/repositories/data/flemish_members_test.csv b/backend/src/tests/modules/club/data/flemish_members_test.csv similarity index 100% rename from backend/src/tests/modules/club/repositories/data/flemish_members_test.csv rename to backend/src/tests/modules/club/data/flemish_members_test.csv From 155d0245e381d5bcb98ffd4c8844f4b7c5b5d221 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 15:55:25 +0200 Subject: [PATCH 036/410] refactor: use presenters --- .../src/tests/modules/club/test_get_member.py | 24 ++++++++++++-- .../tests/modules/club/test_get_members.py | 33 +++++++++++++++---- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/backend/src/tests/modules/club/test_get_member.py b/backend/src/tests/modules/club/test_get_member.py index 64cfe421..71aebd5f 100644 --- a/backend/src/tests/modules/club/test_get_member.py +++ b/backend/src/tests/modules/club/test_get_member.py @@ -2,11 +2,29 @@ import pytest from kwai.core.db.database import Database +from kwai.core.domain.presenter import Presenter +from kwai.modules.club.domain.member import MemberEntity from kwai.modules.club.get_member import GetMember, GetMemberCommand from kwai.modules.club.repositories.member_db_repository import MemberDbRepository from kwai.modules.club.repositories.member_repository import MemberRepository +class TestPresenter(Presenter[MemberEntity]): + """A dummy presenter for checking the use case result.""" + + def __init__(self): + super().__init__() + self._entity = None + + @property + def entity(self): + """Return the entity.""" + return self._entity + + def present(self, use_case_result: MemberEntity) -> None: + self._entity = use_case_result + + @pytest.fixture def member_repo(database: Database) -> MemberRepository: """A fixture for a member repository.""" @@ -16,6 +34,8 @@ def member_repo(database: Database) -> MemberRepository: async def test_get_member(member_repo: MemberRepository, make_member_in_db): """Test the get member use case.""" member = await make_member_in_db() + presenter = TestPresenter() command = GetMemberCommand(uuid=str(member.uuid)) - result = await GetMember(member_repo).execute(command) - assert result.uuid == member.uuid, "The member should be found" + await GetMember(member_repo, presenter).execute(command) + assert presenter.entity is not None, "The member should exist" + assert presenter.entity.uuid == member.uuid, "The member should be found" diff --git a/backend/src/tests/modules/club/test_get_members.py b/backend/src/tests/modules/club/test_get_members.py index bc771361..9fc903a1 100644 --- a/backend/src/tests/modules/club/test_get_members.py +++ b/backend/src/tests/modules/club/test_get_members.py @@ -2,13 +2,31 @@ import pytest from kwai.core.db.database import Database +from kwai.core.domain.presenter import AsyncPresenter, IterableResult from kwai.core.domain.value_objects.date import Date +from kwai.modules.club.domain.member import MemberEntity from kwai.modules.club.domain.value_objects import License from kwai.modules.club.get_members import GetMembers, GetMembersCommand from kwai.modules.club.repositories.member_db_repository import MemberDbRepository from kwai.modules.club.repositories.member_repository import MemberRepository +class TestPresenter(AsyncPresenter[IterableResult[MemberEntity]]): + """A dummy presenter for checking the use case result.""" + + def __init__(self): + super().__init__() + self._count = 0 + + @property + def count(self): + """Return count.""" + return self._count + + async def present(self, use_case_result: IterableResult[MemberEntity]) -> None: + self._count += 1 + + @pytest.fixture def member_repo(database: Database) -> MemberRepository: """A fixture for a member repository.""" @@ -19,8 +37,9 @@ async def test_get_members(member_repo: MemberRepository, make_member_in_db): """Test get members.""" await make_member_in_db() command = GetMembersCommand() - result = await GetMembers(member_repo).execute(command) - assert result.count > 0, "There should be at least one member" + presenter = TestPresenter() + await GetMembers(member_repo, presenter).execute(command) + assert presenter.count > 0, "There should be at least one member" async def test_get_members_with_license_date( @@ -34,8 +53,9 @@ async def test_get_members_with_license_date( ) ) command = GetMembersCommand(license_end_year=2023, license_end_month=2) - result = await GetMembers(member_repo).execute(command) - assert result.count == 1, "There should only be one member" + presenter = TestPresenter() + await GetMembers(member_repo, presenter).execute(command) + assert presenter.count == 1, "There should only be one member" async def test_get_all_members( @@ -49,5 +69,6 @@ async def test_get_all_members( ) ) command = GetMembersCommand(active=False) - result = await GetMembers(member_repo).execute(command) - assert result.count > 0, "There should be at least one inactive member" + presenter = TestPresenter() + await GetMembers(member_repo, presenter).execute(command) + assert presenter.count > 0, "There should be at least one inactive member" From 44e15ae61379ce5e67936dd1ec1eb293496c65cb Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 15:55:39 +0200 Subject: [PATCH 037/410] refactor: move data (again) --- .../club/{ => repositories}/data/flemish_members_test.csv | 0 backend/src/tests/modules/club/test_import_members.py | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) rename backend/src/tests/modules/club/{ => repositories}/data/flemish_members_test.csv (100%) diff --git a/backend/src/tests/modules/club/data/flemish_members_test.csv b/backend/src/tests/modules/club/repositories/data/flemish_members_test.csv similarity index 100% rename from backend/src/tests/modules/club/data/flemish_members_test.csv rename to backend/src/tests/modules/club/repositories/data/flemish_members_test.csv diff --git a/backend/src/tests/modules/club/test_import_members.py b/backend/src/tests/modules/club/test_import_members.py index bb149228..0e2034d7 100644 --- a/backend/src/tests/modules/club/test_import_members.py +++ b/backend/src/tests/modules/club/test_import_members.py @@ -32,7 +32,9 @@ def present(self, use_case_result: MemberImportResult) -> None: async def test_import_members(database: Database, owner: Owner): """Test the use case Import Members.""" - filename = Path(__file__).parent / "data" / "flemish_members_test.csv" + filename = ( + Path(__file__).parent / "repositories" / "data" / "flemish_members_test.csv" + ) importer = FlemishMemberImporter( str(filename), owner, CountryDbRepository(database) From b9d9bfb6ebea3931278266fca8b548fbb1621732 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 15:59:02 +0200 Subject: [PATCH 038/410] fix: _present must be _presenter --- backend/src/kwai/modules/club/import_members.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/kwai/modules/club/import_members.py b/backend/src/kwai/modules/club/import_members.py index 8d336d59..375f6563 100644 --- a/backend/src/kwai/modules/club/import_members.py +++ b/backend/src/kwai/modules/club/import_members.py @@ -93,7 +93,7 @@ async def execute(self, command: ImportMembersCommand): ) ) case member_importer.FailureResult(): - self._present.present( + self._presenter.present( FailureMemberImportResult( file_upload=file_upload_entity, row=import_result.row, From 0f5ed3e6640ec87bb0e5a758a4723aaf64b06de2 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 18:42:54 +0200 Subject: [PATCH 039/410] feat: add Error model --- backend/src/kwai/core/json_api.py | 16 ++++++++++++++++ backend/src/tests/core/test_json_api.py | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/backend/src/kwai/core/json_api.py b/backend/src/kwai/core/json_api.py index a0971a0d..0953ffaa 100644 --- a/backend/src/kwai/core/json_api.py +++ b/backend/src/kwai/core/json_api.py @@ -87,12 +87,28 @@ class Meta(BaseModel): limit: int | None = None +class ErrorSource(BaseModel): + """Defines the model for an error source.""" + + pointer: str + + +class Error(BaseModel): + """Defines the model for a JSON:API error.""" + + status: str | None = None + source: ErrorSource | None = None + title: str | None = None + detail: str | None = None + + class Document(BaseModel, Generic[T_RESOURCE, T_INCLUDE]): """A JSON:API document.""" meta: Meta | SkipJsonSchema[None] = None data: T_RESOURCE | list[T_RESOURCE] included: set[T_INCLUDE] | SkipJsonSchema[None] = None + errors: list[Error] | SkipJsonSchema[None] = None @property def resource(self) -> T_RESOURCE: diff --git a/backend/src/tests/core/test_json_api.py b/backend/src/tests/core/test_json_api.py index 013b5b1c..47d5f988 100644 --- a/backend/src/tests/core/test_json_api.py +++ b/backend/src/tests/core/test_json_api.py @@ -1,13 +1,13 @@ """Module for testing the JSON:API models.""" + from types import NoneType from typing import Literal import pytest +from kwai.core.json_api import Document, ResourceData, ResourceIdentifier from pydantic import BaseModel from rich import json -from kwai.core.json_api import Document, ResourceData, ResourceIdentifier - class JudokaResourceIdentifier(ResourceIdentifier): """A JSON:API resource identifier for a judoka.""" From 012a0e23d097a57eaac6927cae9cb0077aeccf03 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 18:54:51 +0200 Subject: [PATCH 040/410] test: add test_error --- backend/src/tests/core/test_json_api.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/backend/src/tests/core/test_json_api.py b/backend/src/tests/core/test_json_api.py index 47d5f988..c5dc7384 100644 --- a/backend/src/tests/core/test_json_api.py +++ b/backend/src/tests/core/test_json_api.py @@ -4,7 +4,7 @@ from typing import Literal import pytest -from kwai.core.json_api import Document, ResourceData, ResourceIdentifier +from kwai.core.json_api import Document, Error, ResourceData, ResourceIdentifier from pydantic import BaseModel from rich import json @@ -72,3 +72,20 @@ def test_dump_json(judoka_resource: JudokaResource): assert ( json_doc["data"]["attributes"]["name"] == "Jigoro Kano" ), "The judoka should have a name." + + +def test_error(): + """Test the error of a JSON:API document.""" + json_doc = JudokaDocument( + data=[], + errors=[ + Error( + title="No judoka selected", + detail="There is no judoka selected for this tournament", + ) + ], + ) + json_doc = json.loads(json_doc.model_dump_json()) + print(json_doc) + assert "errors" in json_doc, "There should be a 'errors' in the document." + assert json_doc["errors"][0]["title"] == "No judoka selected" From a0dc2fece2d5c875bd46a94758bb13f46b972ef2 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 19:03:02 +0200 Subject: [PATCH 041/410] test: remove print --- backend/src/tests/core/test_json_api.py | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/tests/core/test_json_api.py b/backend/src/tests/core/test_json_api.py index c5dc7384..02b4109c 100644 --- a/backend/src/tests/core/test_json_api.py +++ b/backend/src/tests/core/test_json_api.py @@ -86,6 +86,5 @@ def test_error(): ], ) json_doc = json.loads(json_doc.model_dump_json()) - print(json_doc) assert "errors" in json_doc, "There should be a 'errors' in the document." assert json_doc["errors"][0]["title"] == "No judoka selected" From 3f453de4fdb141578168b75122e519a716bfafbd Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 19:10:59 +0200 Subject: [PATCH 042/410] refactor: remove None defaults from Error model --- backend/src/kwai/core/json_api.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/backend/src/kwai/core/json_api.py b/backend/src/kwai/core/json_api.py index 0953ffaa..5c19eafb 100644 --- a/backend/src/kwai/core/json_api.py +++ b/backend/src/kwai/core/json_api.py @@ -96,10 +96,10 @@ class ErrorSource(BaseModel): class Error(BaseModel): """Defines the model for a JSON:API error.""" - status: str | None = None + status: str = "" source: ErrorSource | None = None - title: str | None = None - detail: str | None = None + title: str = "" + detail: str = "" class Document(BaseModel, Generic[T_RESOURCE, T_INCLUDE]): @@ -151,6 +151,8 @@ def serialize(self, handler) -> dict[str, Any]: del result["included"] if self.meta is None: del result["meta"] + if not self.errors: + del result["errors"] return result def merge(self, other: "Document"): From 4934eec978f0fc2045bcf7cb8968bef7c4b98c9a Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 19:44:26 +0200 Subject: [PATCH 043/410] feat: add JsonApiError --- frontend/packages/kwai-api/src/index.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/frontend/packages/kwai-api/src/index.ts b/frontend/packages/kwai-api/src/index.ts index dc1f566d..5bdb2ea8 100644 --- a/frontend/packages/kwai-api/src/index.ts +++ b/frontend/packages/kwai-api/src/index.ts @@ -29,6 +29,16 @@ export const JsonApiData = JsonResourceIdentifier.extend({ }); export type JsonApiDataType = z.infer; +export const JsonApiError = z.object({ + status: z.string().default(''), + source: z.object({ + pointer: z.string(), + }).optional(), + title: z.string().default(''), + detail: z.string().default(''), +}); +export type JsonApiErrorType = z.infer; + export const JsonApiDocument = z.object({ meta: z.object({ count: z.number().optional(), @@ -37,6 +47,7 @@ export const JsonApiDocument = z.object({ }).optional(), data: z.union([JsonApiData, z.array(JsonApiData)]), included: z.array(JsonApiData).optional(), + errors: z.array(JsonApiError).optional(), }); export type JsonApiDocumentType = z.infer; From cd5964bbf6031b1f968270b86dfca79d12435186 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 19:45:02 +0200 Subject: [PATCH 044/410] chore: use errors --- backend/src/kwai/api/v1/club/presenters.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/backend/src/kwai/api/v1/club/presenters.py b/backend/src/kwai/api/v1/club/presenters.py index 6f5ccef0..4ff283bd 100644 --- a/backend/src/kwai/api/v1/club/presenters.py +++ b/backend/src/kwai/api/v1/club/presenters.py @@ -2,7 +2,7 @@ from kwai.api.v1.club.schemas.member import MemberDocument from kwai.core.domain.presenter import AsyncPresenter, IterableResult, Presenter -from kwai.core.json_api import Meta +from kwai.core.json_api import Error, ErrorSource, Meta from kwai.modules.club.domain.member import MemberEntity from kwai.modules.club.import_members import ( FailureMemberImportResult, @@ -51,12 +51,11 @@ class JsonApiUploadMemberPresenter( def __init__(self) -> None: super().__init__() - self._meta = Meta(count=0, offset=0, limit=0, errors=[]) + self._document = MemberDocument( + meta=Meta(count=0, offset=0, limit=0), data=[], errors=[] + ) def present(self, result: MemberImportResult) -> None: - if self._document is None: - self._document = MemberDocument(data=[]) - match result: case OkMemberImportResult(): member_document = MemberDocument.create(result.member) @@ -75,9 +74,12 @@ def present(self, result: MemberImportResult) -> None: ) if included.id == "0": included.id = member_document.resource.id - self._meta.count += 1 + self._document.meta.count += 1 self._document.merge(member_document) case FailureMemberImportResult(): - self._meta.errors.append( - {"row": result.row, "message": result.to_message()} + self._document.errors.append( + Error( + source=ErrorSource(pointer=str(result.row)), + detail=result.to_message(), + ) ) From fb9b69db2b2c7d7b895466ad44ffe812f745d7eb Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 19:52:38 +0200 Subject: [PATCH 045/410] refactor: remove text from message --- backend/src/kwai/modules/club/import_members.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/kwai/modules/club/import_members.py b/backend/src/kwai/modules/club/import_members.py index 375f6563..063886c8 100644 --- a/backend/src/kwai/modules/club/import_members.py +++ b/backend/src/kwai/modules/club/import_members.py @@ -41,7 +41,7 @@ class FailureMemberImportResult(MemberImportResult): message: str def to_message(self) -> str: - return f"Import failed for row {self.row}: {self.message}." + return self.message @dataclass(kw_only=True, slots=True, frozen=True) From 10af18a89ded6cb11bbdae806ee20d4c3853a276 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 19:53:59 +0200 Subject: [PATCH 046/410] refactor: use JSON:API error and create separate transform method --- frontend/apps/club/src/composables/useMember.ts | 10 ++++++---- .../club/src/pages/members/MembersUploadPage.vue | 13 ++++++++++--- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/frontend/apps/club/src/composables/useMember.ts b/frontend/apps/club/src/composables/useMember.ts index 6b47f6ad..dbffaeba 100644 --- a/frontend/apps/club/src/composables/useMember.ts +++ b/frontend/apps/club/src/composables/useMember.ts @@ -130,7 +130,10 @@ export const MemberDocumentSchema = JsonApiDocument.extend({ CountryResourceSchema, ]) ).default([]), -}).transform(doc => { +}); +type MemberDocument = z.infer; + +export const transform = (doc: MemberDocument) : Member | Members => { const mapModel = (data: MemberResource): Member => { const person = doc.included.find(included => included.type === PersonResourceSchema.shape.type.value && included.id === data.relationships.person.data.id) as PersonResource; const nationality = doc.included.find(included => included.type === CountryResourceSchema.shape.type.value && included.id === person.relationships.nationality.data.id) as CountryResource; @@ -186,8 +189,7 @@ export const MemberDocumentSchema = JsonApiDocument.extend({ }; } return mapModel(doc.data); -}); -type MemberDocument = z.input; +}; const getMembers = async({ offset = null, @@ -208,7 +210,7 @@ const getMembers = async({ return api.get().json().then(json => { const result = MemberDocumentSchema.safeParse(json); if (result.success) { - return result.data as Members; + return transform(result.data) as Members; } console.log(result.error); throw result.error; diff --git a/frontend/apps/club/src/pages/members/MembersUploadPage.vue b/frontend/apps/club/src/pages/members/MembersUploadPage.vue index dc4b9210..d2ca292a 100644 --- a/frontend/apps/club/src/pages/members/MembersUploadPage.vue +++ b/frontend/apps/club/src/pages/members/MembersUploadPage.vue @@ -8,8 +8,8 @@ import { KwaiCheckbox, } from '@kwai/ui'; import { type Ref, ref } from 'vue'; -import { useHttpApi } from '@kwai/api'; -import { MemberDocumentSchema, type Members } from '@root/composables/useMember'; +import { useHttpApi, type JsonApiErrorType } from '@kwai/api'; +import { MemberDocumentSchema, type Members, transform } from '@root/composables/useMember'; const { t } = useI18n({ useScope: 'global' }); @@ -20,13 +20,17 @@ const useMemberUpload = (files: File[]) => { formData.append('member_file', files[0]); await useHttpApi() .url('/v1/club/members/upload') + .query({ preview: preview.value }) .body(formData) .post() .json() .then(json => { const result = MemberDocumentSchema.safeParse(json); if (result.success) { - members.value = result.data as Members; + console.log(result.data); + errors.value = result.data.errors ?? []; + count.value = result.data.meta?.count ?? 0; + members.value = transform(result.data) as Members; } else { console.log(result.error); throw result.error; @@ -39,6 +43,8 @@ const useMemberUpload = (files: File[]) => { const members = ref(); const preview: Ref = ref(true); +const errors: Ref = ref([]); +const count = ref(0); const upload = (files: File[]) => { members.value = useMemberUpload(files); @@ -63,6 +69,7 @@ const upload = (files: File[]) => { Preview + {{ errors }} {{ members }} From bdda07ac37a40ce956a3fe7f204021451c514f95 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 25 May 2024 20:08:41 +0200 Subject: [PATCH 047/410] ci: ignore production configuration file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 74f677fb..f583e858 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ __pycache__ *.tsbuildinfo stats.html /backend/.venv/ +/frontend/packages/kwai-config/src/config.production.toml From 77c789c268d898f24293efa87b469d150375cac0 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sun, 26 May 2024 17:08:00 +0200 Subject: [PATCH 048/410] refactor: use Message from PrimeVue --- .../packages/kwai-ui/src/alerts/Alert.vue | 30 +++++++++++++------ .../kwai-ui/src/alerts/ErrorAlert.vue | 18 +++++------ .../packages/kwai-ui/src/alerts/InfoAlert.vue | 18 +++++------ .../kwai-ui/src/alerts/LoadingAlert.vue | 14 ++++----- .../kwai-ui/src/alerts/WarningAlert.vue | 10 +++---- 5 files changed, 48 insertions(+), 42 deletions(-) diff --git a/frontend/packages/kwai-ui/src/alerts/Alert.vue b/frontend/packages/kwai-ui/src/alerts/Alert.vue index e41bf47e..207f1629 100644 --- a/frontend/packages/kwai-ui/src/alerts/Alert.vue +++ b/frontend/packages/kwai-ui/src/alerts/Alert.vue @@ -1,11 +1,23 @@ - - + + diff --git a/frontend/packages/kwai-ui/src/alerts/ErrorAlert.vue b/frontend/packages/kwai-ui/src/alerts/ErrorAlert.vue index 64e54161..362f510e 100644 --- a/frontend/packages/kwai-ui/src/alerts/ErrorAlert.vue +++ b/frontend/packages/kwai-ui/src/alerts/ErrorAlert.vue @@ -1,15 +1,13 @@ + + - - diff --git a/frontend/packages/kwai-ui/src/alerts/InfoAlert.vue b/frontend/packages/kwai-ui/src/alerts/InfoAlert.vue index 89707302..7ea0d5b4 100644 --- a/frontend/packages/kwai-ui/src/alerts/InfoAlert.vue +++ b/frontend/packages/kwai-ui/src/alerts/InfoAlert.vue @@ -1,15 +1,13 @@ + + - - diff --git a/frontend/packages/kwai-ui/src/alerts/LoadingAlert.vue b/frontend/packages/kwai-ui/src/alerts/LoadingAlert.vue index 67043fb5..d601003d 100644 --- a/frontend/packages/kwai-ui/src/alerts/LoadingAlert.vue +++ b/frontend/packages/kwai-ui/src/alerts/LoadingAlert.vue @@ -1,13 +1,13 @@ + + - - diff --git a/frontend/packages/kwai-ui/src/alerts/WarningAlert.vue b/frontend/packages/kwai-ui/src/alerts/WarningAlert.vue index 42195709..c1ce94c3 100644 --- a/frontend/packages/kwai-ui/src/alerts/WarningAlert.vue +++ b/frontend/packages/kwai-ui/src/alerts/WarningAlert.vue @@ -1,15 +1,13 @@ From 67def243b6fc04f01cd908d1f9c3bb89c42666dd Mon Sep 17 00:00:00 2001 From: zumuta Date: Sun, 26 May 2024 18:40:23 +0200 Subject: [PATCH 049/410] refactor: use KwaiButton --- frontend/apps/club/src/components/ClubToolbar.vue | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/frontend/apps/club/src/components/ClubToolbar.vue b/frontend/apps/club/src/components/ClubToolbar.vue index c0215a3a..adcb0a1b 100644 --- a/frontend/apps/club/src/components/ClubToolbar.vue +++ b/frontend/apps/club/src/components/ClubToolbar.vue @@ -4,11 +4,10 @@ import { website } from '@kwai/config'; // eslint-disable-next-line import/no-absolute-path import logoUrl from '/logo.png'; import type { MenuItem } from '@kwai/ui'; -import { ToolbarLogo, ToolbarMenu } from '@kwai/ui'; +import { ToolbarLogo, ToolbarMenu, KwaiButton } from '@kwai/ui'; import { useRouter } from 'vue-router'; import { computed } from 'vue'; import { useI18n } from 'vue-i18n'; -import PrimaryButton from '@root/components/PrimaryButton.vue'; import { isLoggedIn, useHttpLogout } from '@kwai/api'; const { t } = useI18n({ useScope: 'global' }); @@ -54,14 +53,14 @@ const logout = () => {
- + Logout - +
- + Login - +
From a8e8a7bf87cbb33db772fba30d5d4ab5c3f31bb2 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sun, 26 May 2024 19:39:27 +0200 Subject: [PATCH 050/410] feat: preview of members upload --- frontend/apps/club/src/locales/nl.yaml | 8 ++ .../src/pages/members/MembersUploadPage.vue | 103 +++++++++++++++--- 2 files changed, 96 insertions(+), 15 deletions(-) diff --git a/frontend/apps/club/src/locales/nl.yaml b/frontend/apps/club/src/locales/nl.yaml index d91279bb..9cd9620e 100644 --- a/frontend/apps/club/src/locales/nl.yaml +++ b/frontend/apps/club/src/locales/nl.yaml @@ -11,3 +11,11 @@ members_upload: title: Opladen Leden description: | Via deze pagina kan u een bestand opladen met nieuwe of gewijzigde leden. + preview_description: | + Met preview kan je eerst controleren of het bestand correct verwerkt kan worden. + preview: Preview + error: + message: | + Opgelet er zijn fouten gevonden in het opgeladen bestand! + row: Rij + description: Omschrijving diff --git a/frontend/apps/club/src/pages/members/MembersUploadPage.vue b/frontend/apps/club/src/pages/members/MembersUploadPage.vue index d2ca292a..8798ac06 100644 --- a/frontend/apps/club/src/pages/members/MembersUploadPage.vue +++ b/frontend/apps/club/src/pages/members/MembersUploadPage.vue @@ -6,6 +6,7 @@ import { ContainerSectionTitle, KwaiFileUpload, KwaiCheckbox, + ErrorAlert, } from '@kwai/ui'; import { type Ref, ref } from 'vue'; import { useHttpApi, type JsonApiErrorType } from '@kwai/api'; @@ -14,7 +15,6 @@ import { MemberDocumentSchema, type Members, transform } from '@root/composables const { t } = useI18n({ useScope: 'global' }); const useMemberUpload = (files: File[]) => { - const members: Ref = ref(null); (async() => { const formData = new FormData(); formData.append('member_file', files[0]); @@ -27,7 +27,6 @@ const useMemberUpload = (files: File[]) => { .then(json => { const result = MemberDocumentSchema.safeParse(json); if (result.success) { - console.log(result.data); errors.value = result.data.errors ?? []; count.value = result.data.meta?.count ?? 0; members.value = transform(result.data) as Members; @@ -57,20 +56,94 @@ const upload = (files: File[]) => { {{ t('members_upload.title') }} - {{ t('members_upload.description') }} - +
+ {{ t('members_upload.description') }} +
+
+
+ +
+
+

+ {{ t('members_upload.preview_description') }} +

+ + + +
+
- - - - {{ errors }} - {{ members }} + + {{ t('members_upload.error.message') }} + + + + + + + + + + + + + + + + +
+ {{ t('members_upload.error.row') }} + + {{ t('members_upload.error.description') }} +
+ {{ index + 1 }} + + {{ member.person.lastName }} {{ member.person.firstName }} +
From 4d9d02c89ac86bade560ee7c803ef796d6e630c3 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 27 May 2024 19:35:34 +0200 Subject: [PATCH 051/410] fix: strip the email --- .../kwai/modules/club/repositories/flemish_member_importer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/kwai/modules/club/repositories/flemish_member_importer.py b/backend/src/kwai/modules/club/repositories/flemish_member_importer.py index 07f481c3..6a453640 100644 --- a/backend/src/kwai/modules/club/repositories/flemish_member_importer.py +++ b/backend/src/kwai/modules/club/repositories/flemish_member_importer.py @@ -68,7 +68,7 @@ async def import_(self) -> AsyncGenerator[Result, None]: emails = [] try: for email in row["email"].split(";"): - emails.append(EmailAddress(email)) + emails.append(EmailAddress(email.strip())) except InvalidEmailException as exc: yield FailureResult(row=row_index, message=str(exc)) continue From 8eccfc21f68a69eb32050769876ae1d2381a01e8 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 27 May 2024 19:49:30 +0200 Subject: [PATCH 052/410] refactor: use ContainerSection --- .../src/pages/members/MembersUploadPage.vue | 74 ++++++++++--------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/frontend/apps/club/src/pages/members/MembersUploadPage.vue b/frontend/apps/club/src/pages/members/MembersUploadPage.vue index 8798ac06..ff526e0b 100644 --- a/frontend/apps/club/src/pages/members/MembersUploadPage.vue +++ b/frontend/apps/club/src/pages/members/MembersUploadPage.vue @@ -79,10 +79,12 @@ const upload = (files: File[]) => { - - {{ t('members_upload.error.message') }} - - - - - - - - - - - - - - - - -
- {{ t('members_upload.error.row') }} - - {{ t('members_upload.error.description') }} -
- {{ index + 1 }} - - {{ member.person.lastName }} {{ member.person.firstName }} -
+ + + + + + + + + + + + + +
+ {{ t('members_upload.error.row') }} + + {{ t('members_upload.error.description') }} +
+ {{ index + 1 }} + + {{ member.person.lastName }} {{ member.person.firstName }} +
+ From 9a77944c13c108a61632e6a713e48c2ea84b3d59 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 27 May 2024 19:58:50 +0200 Subject: [PATCH 053/410] refactor: use ContainerSectionContent and add space-y-4 --- .../apps/club/src/pages/members/MembersUploadPage.vue | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/frontend/apps/club/src/pages/members/MembersUploadPage.vue b/frontend/apps/club/src/pages/members/MembersUploadPage.vue index ff526e0b..f2195825 100644 --- a/frontend/apps/club/src/pages/members/MembersUploadPage.vue +++ b/frontend/apps/club/src/pages/members/MembersUploadPage.vue @@ -51,7 +51,7 @@ const upload = (files: File[]) => { From 946b92ef7674ccf7675bdda67fa0fe0e0eea8b21 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 1 Jun 2024 18:50:38 +0200 Subject: [PATCH 067/410] fix: use route and set background color of menus --- .../packages/kwai-ui/src/nav/KwaiMenubar.vue | 40 +++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/frontend/packages/kwai-ui/src/nav/KwaiMenubar.vue b/frontend/packages/kwai-ui/src/nav/KwaiMenubar.vue index fa3d3d5a..09ff2568 100644 --- a/frontend/packages/kwai-ui/src/nav/KwaiMenubar.vue +++ b/frontend/packages/kwai-ui/src/nav/KwaiMenubar.vue @@ -6,10 +6,10 @@ import { computed } from 'vue'; interface Props { items: MenuItem[] } -const props = defineProps(); +const properties = defineProps(); const menuItems = computed(() => { - return props.items.map(item => ({ + return properties.items.map(item => ({ label: item.title, command: item.method, route: item.route, @@ -23,11 +23,45 @@ const menuItems = computed(() => { :model="menuItems" pt:root:class="bg-primary-500 text-primary-text w-full lg:px-6 lg:mx-auto lg:max-w-6xl" :pt-options="{ mergeSections: false, mergeProps: true }" - /> + > + + From 1d2caefde0d2bd5b66a71957005ec728d67f2c51 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 1 Jun 2024 18:51:11 +0200 Subject: [PATCH 068/410] fix: make sure the routes are sorted in order of definition --- frontend/apps/club/src/routes.ts | 12 +++++++++ frontend/packages/kwai-ui/src/nav/useMenu.ts | 27 ++++++++++++++++---- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/frontend/apps/club/src/routes.ts b/frontend/apps/club/src/routes.ts index f15f8068..cf139452 100644 --- a/frontend/apps/club/src/routes.ts +++ b/frontend/apps/club/src/routes.ts @@ -5,6 +5,7 @@ import NotAllowedPage from '@root/pages/not_allowed/NotAllowedPage.vue'; import MembersPage from '@root/pages/members/MembersPage.vue'; import ClubToolbar from '@root/components/ClubToolbar.vue'; import UploadMembersPage from '@root/pages/members/MembersUploadPage.vue'; +import TeamsPage from '@root/pages/teams/TeamsPage.vue'; const routes: RouteRecordRaw[] = [ { @@ -49,6 +50,17 @@ const routes: RouteRecordRaw[] = [ main: UploadMembersPage, }, }, + { + name: 'club.teams', + path: '/members/teams', + components: { + toolbar: ClubToolbar, + main: TeamsPage, + }, + meta: { + title: 'Teams', + }, + }, ], }, ]; diff --git a/frontend/packages/kwai-ui/src/nav/useMenu.ts b/frontend/packages/kwai-ui/src/nav/useMenu.ts index 2e97be55..8a3a28ea 100644 --- a/frontend/packages/kwai-ui/src/nav/useMenu.ts +++ b/frontend/packages/kwai-ui/src/nav/useMenu.ts @@ -11,15 +11,32 @@ export const useMenu = () => { return computed((): MenuItem[] => { const result: MenuItem[] = []; + const routeOrder: Record = {}; + let rank = 0; + for (const route of router.options.routes[0].children || []) { + if (!route.name) continue; + routeOrder[route.name as string] = rank++; + } + const routes = []; for (const route of router.getRoutes()) { if (route.meta.title) { - result.push({ - title: route.meta.title as string, - route, - disabled: false, - }); + routes.push(route); } } + routes.sort((a, b) => { + const menuA = routeOrder[a.name as string]; + const menuB = routeOrder[b.name as string]; + if (menuA < menuB) return -1; + if (menuA > menuB) return 1; + return 0; + }); + for (const route of routes) { + result.push({ + title: route.meta.title as string, + route, + disabled: false, + }); + } return result; }); }; From 15aadaebf27cd721b2e4c9123a316ee5f3637389 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sun, 2 Jun 2024 15:58:20 +0200 Subject: [PATCH 069/410] feat: add name property --- backend/src/kwai/modules/club/domain/member.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/backend/src/kwai/modules/club/domain/member.py b/backend/src/kwai/modules/club/domain/member.py index e6aaa886..7b271d5b 100644 --- a/backend/src/kwai/modules/club/domain/member.py +++ b/backend/src/kwai/modules/club/domain/member.py @@ -2,6 +2,7 @@ from kwai.core.domain.entity import Entity from kwai.core.domain.value_objects.identifier import IntIdentifier +from kwai.core.domain.value_objects.name import Name from kwai.core.domain.value_objects.traceable_time import TraceableTime from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.club.domain.person import PersonEntity @@ -61,6 +62,11 @@ def license(self) -> License: """Return the license.""" return self._license + @property + def name(self) -> Name: + """Return the name of the member.""" + return self.person.name + @property def person(self) -> PersonEntity: """Return the person.""" From 6d60233d660275dd60a65da066c35cc50d37564c Mon Sep 17 00:00:00 2001 From: zumuta Date: Sun, 2 Jun 2024 16:10:43 +0200 Subject: [PATCH 070/410] feat: add CoachEntity to club module --- backend/src/kwai/modules/club/domain/coach.py | 92 +++++++++++++++++++ .../kwai/modules/club/repositories/_tables.py | 32 +++++++ .../club/repositories/coach_db_repository.py | 23 +++++ .../club/repositories/coach_repository.py | 19 ++++ .../training/coaches/coach_db_repository.py | 11 +-- backend/src/tests/fixtures/club/coach.py | 51 ++++++++++ backend/src/tests/modules/club/conftest.py | 1 + .../repositories/test_coach_db_repository.py | 8 ++ 8 files changed, 231 insertions(+), 6 deletions(-) create mode 100644 backend/src/kwai/modules/club/domain/coach.py create mode 100644 backend/src/kwai/modules/club/repositories/coach_db_repository.py create mode 100644 backend/src/kwai/modules/club/repositories/coach_repository.py create mode 100644 backend/src/tests/fixtures/club/coach.py create mode 100644 backend/src/tests/modules/club/repositories/test_coach_db_repository.py diff --git a/backend/src/kwai/modules/club/domain/coach.py b/backend/src/kwai/modules/club/domain/coach.py new file mode 100644 index 00000000..8f18fa80 --- /dev/null +++ b/backend/src/kwai/modules/club/domain/coach.py @@ -0,0 +1,92 @@ +"""Module for defining a coach entity.""" + +from kwai.core.domain.entity import Entity +from kwai.core.domain.value_objects.identifier import IntIdentifier +from kwai.core.domain.value_objects.name import Name +from kwai.core.domain.value_objects.owner import Owner +from kwai.core.domain.value_objects.traceable_time import TraceableTime +from kwai.modules.club.domain.member import MemberEntity + +CoachIdentifier = IntIdentifier + + +class CoachEntity(Entity[CoachIdentifier]): + """A coach entity.""" + + def __init__( + self, + *, + id_: CoachIdentifier | None = None, + member: MemberEntity, + description: str = "", + diploma: str = "", + active: bool = True, + remark: str = "", + user: Owner | None = None, + traceable_time: TraceableTime | None = None, + ): + """Initialize a coach. + + Args: + id_ (CoachIdentifier): The id of the coach. + member: A coach is a member of the club. + description: The description (bio) of the coach. + diploma: The diploma of the coach. + active: Whether the coach is active. + remark: A remark about the coach. + user: A coach can also be a user of the system. + traceable_time: The creation and modification timestamp of the coach. + """ + super().__init__(id_ or CoachIdentifier()) + self._member = member + self._description = description + self._diploma = diploma + self._active = active + self._remark = remark + self._user = user + self._traceable_time = traceable_time or TraceableTime() + + @property + def is_active(self) -> bool: + """Is the coach active?""" + return self._active + + @property + def member(self) -> MemberEntity: + """Return the related member.""" + return self._member + + @property + def name(self) -> Name: + """Return the name of the coach.""" + return self._member.person.name + + @property + def diploma(self) -> str: + """Return the diploma of the coach.""" + return self._diploma + + @property + def description(self) -> str: + """Return the description of the coach.""" + return self._description + + @property + def remark(self) -> str: + """Return the remark of the coach.""" + return self._remark + + @property + def traceable_time(self) -> TraceableTime: + """Return the traceable_time.""" + return self._traceable_time + + @property + def uuid(self): + """Return the uuid of the coach.""" + return self._member.uuid + + @property + def user(self) -> Owner | None: + """Return the related user.""" + return self._user diff --git a/backend/src/kwai/modules/club/repositories/_tables.py b/backend/src/kwai/modules/club/repositories/_tables.py index 120397c2..263205e0 100644 --- a/backend/src/kwai/modules/club/repositories/_tables.py +++ b/backend/src/kwai/modules/club/repositories/_tables.py @@ -11,6 +11,7 @@ from kwai.core.domain.value_objects.timestamp import Timestamp from kwai.core.domain.value_objects.traceable_time import TraceableTime from kwai.core.domain.value_objects.unique_id import UniqueId +from kwai.modules.club.domain.coach import CoachEntity from kwai.modules.club.domain.contact import ContactEntity, ContactIdentifier from kwai.modules.club.domain.country import CountryEntity, CountryIdentifier from kwai.modules.club.domain.file_upload import FileUploadEntity @@ -294,3 +295,34 @@ def persist(cls, upload: FileUploadEntity, member: MemberEntity) -> Self: import_id=upload.id.value, created_at=datetime.now(UTC), ) + + +@dataclass(kw_only=True, frozen=True, slots=True) +class CoachRow(TableRow): + """Represents a row of the coach table.""" + + __table_name__ = "coaches" + + id: int + member_id: int + description: str + diploma: str + active: int + remark: str + user_id: int | None + created_at: datetime + updated_at: datetime | None + + @classmethod + def persist(cls, coach: CoachEntity) -> Self: + return cls( + id=coach.id.value, + member_id=coach.member.id.value, + description=coach.description, + diploma=coach.diploma, + active=1 if coach.is_active else 0, + remark=coach.remark, + user_id=None if coach.user is None else coach.user.id.value, + created_at=coach.traceable_time.created_at.timestamp, # type: ignore[arg-type] + updated_at=coach.traceable_time.updated_at.timestamp, + ) diff --git a/backend/src/kwai/modules/club/repositories/coach_db_repository.py b/backend/src/kwai/modules/club/repositories/coach_db_repository.py new file mode 100644 index 00000000..6bb32557 --- /dev/null +++ b/backend/src/kwai/modules/club/repositories/coach_db_repository.py @@ -0,0 +1,23 @@ +"""Module for defining a coach repository using a database.""" + +from kwai.core.db.database import Database +from kwai.core.domain.entity import Entity +from kwai.modules.club.domain.coach import CoachEntity, CoachIdentifier +from kwai.modules.club.repositories._tables import CoachRow +from kwai.modules.club.repositories.coach_repository import CoachRepository + + +class CoachDbRepository(CoachRepository): + """A coach repository using a database.""" + + def __init__(self, database: Database) -> None: + self._database = database + + async def create(self, coach: CoachEntity): + new_coach_id = await self._database.insert( + CoachRow.__table_name__, CoachRow.persist(coach) + ) + return Entity.replace(coach, id_=CoachIdentifier(new_coach_id)) + + async def delete(self, coach: CoachEntity): + await self._database.delete(coach.id.value, CoachRow.__table_name__) diff --git a/backend/src/kwai/modules/club/repositories/coach_repository.py b/backend/src/kwai/modules/club/repositories/coach_repository.py new file mode 100644 index 00000000..3f9e8ffc --- /dev/null +++ b/backend/src/kwai/modules/club/repositories/coach_repository.py @@ -0,0 +1,19 @@ +"""Module for defining an interface for a coach repository.""" + +from abc import ABC, abstractmethod + +from kwai.modules.club.domain.coach import CoachEntity + + +class CoachRepository(ABC): + """An interface for a coach repository.""" + + @abstractmethod + async def create(self, coach: CoachEntity): + """Save a new coach.""" + raise NotImplementedError + + @abstractmethod + async def delete(self, coach: CoachEntity): + """Delete an existing coach.""" + raise NotImplementedError diff --git a/backend/src/kwai/modules/training/coaches/coach_db_repository.py b/backend/src/kwai/modules/training/coaches/coach_db_repository.py index 723e54d5..446afd56 100644 --- a/backend/src/kwai/modules/training/coaches/coach_db_repository.py +++ b/backend/src/kwai/modules/training/coaches/coach_db_repository.py @@ -1,19 +1,18 @@ """Module that defines a coach repository for a database.""" + from typing import AsyncIterator from kwai.core.db.database import Database from kwai.modules.training.coaches.coach import CoachEntity, CoachIdentifier -from kwai.modules.training.coaches.coach_db_query import CoachDbQuery +from kwai.modules.training.coaches.coach_db_query import CoachDbQuery, CoachQueryRow from kwai.modules.training.coaches.coach_query import CoachQuery from kwai.modules.training.coaches.coach_repository import ( CoachNotFoundException, CoachRepository, ) from kwai.modules.training.coaches.coach_tables import ( - CoachesTable, CoachRow, PersonRow, - PersonsTable, ) @@ -43,17 +42,17 @@ async def get_by_id(self, id: CoachIdentifier) -> CoachEntity: if not row: raise CoachNotFoundException(f"Coach with id {id} not found.") - return _create_entity(CoachesTable(row), PersonsTable(row)) + return CoachQueryRow.map(row).create_entity() async def get_by_ids(self, *ids: CoachIdentifier) -> AsyncIterator[CoachEntity]: query = self.create_query().filter_by_ids(*ids) async for row in query.fetch(): - yield _create_entity(CoachesTable(row), PersonsTable(row)) + yield CoachQueryRow.map(row).create_entity() async def get_all( self, query: CoachQuery | None = None ) -> AsyncIterator[CoachEntity]: query = query or self.create_query() async for row in query.fetch(): - yield _create_entity(CoachesTable(row), PersonsTable(row)) + yield CoachQueryRow.map(row).create_entity() diff --git a/backend/src/tests/fixtures/club/coach.py b/backend/src/tests/fixtures/club/coach.py new file mode 100644 index 00000000..3c1a702f --- /dev/null +++ b/backend/src/tests/fixtures/club/coach.py @@ -0,0 +1,51 @@ +"""Module for defining fixtures for coaches.""" + +import pytest +from kwai.core.db.database import Database +from kwai.core.db.uow import UnitOfWork +from kwai.modules.club.domain.coach import CoachEntity +from kwai.modules.club.domain.member import MemberEntity +from kwai.modules.club.repositories.coach_db_repository import CoachDbRepository + + +@pytest.fixture +def make_coach(make_member): + """A factory fixture for a coach.""" + + def _make_coach( + member: MemberEntity | None = None, + active: bool = True, + ) -> CoachEntity: + member = member or make_member() + return CoachEntity(member=member or make_member(), active=active) + + return _make_coach + + +@pytest.fixture +def make_coach_in_db( + request, event_loop, database: Database, make_coach, make_member_in_db +): + """A factory fixture for a coach in a database.""" + + async def _make_coach_in_db( + coach: CoachEntity | None = None, member: MemberEntity | None = None + ): + member = member or await make_member_in_db() + coach = coach or make_coach(member=member) + repo = CoachDbRepository(database) + async with UnitOfWork(database): + coach = await repo.create(coach) + + def cleanup(): + async def acleanup(): + async with UnitOfWork(database): + await repo.delete(coach) + + event_loop.run_until_complete(acleanup()) + + request.addfinalizer(cleanup) + + return coach + + return _make_coach_in_db diff --git a/backend/src/tests/modules/club/conftest.py b/backend/src/tests/modules/club/conftest.py index 4824b39d..5811efc6 100644 --- a/backend/src/tests/modules/club/conftest.py +++ b/backend/src/tests/modules/club/conftest.py @@ -4,3 +4,4 @@ from tests.fixtures.club.contacts import * # noqa from tests.fixtures.club.persons import * # noqa from tests.fixtures.club.members import * # noqa +from tests.fixtures.club.coach import * # noqa diff --git a/backend/src/tests/modules/club/repositories/test_coach_db_repository.py b/backend/src/tests/modules/club/repositories/test_coach_db_repository.py new file mode 100644 index 00000000..054f2ea5 --- /dev/null +++ b/backend/src/tests/modules/club/repositories/test_coach_db_repository.py @@ -0,0 +1,8 @@ +"""Module for testing the coach database repository.""" + + +async def test_create_coach(make_coach_in_db, make_member_in_db): + """Test creating a coach.""" + coach = await make_coach_in_db() + assert coach is not None, "There should be a coach." + assert coach.id is not None, "Coach id should be provided." From 94af5a943ec9d0f7bc75d452ecbcbc28e6bd2ec5 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sun, 2 Jun 2024 16:11:24 +0200 Subject: [PATCH 071/410] refactor: add OwnerTableRow --- backend/src/kwai/core/db/rows.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/backend/src/kwai/core/db/rows.py b/backend/src/kwai/core/db/rows.py index 9a0d065d..b2f9b06b 100644 --- a/backend/src/kwai/core/db/rows.py +++ b/backend/src/kwai/core/db/rows.py @@ -4,6 +4,7 @@ from datetime import datetime from kwai.core.db.table import Table +from kwai.core.db.table_row import TableRow from kwai.core.domain.value_objects.identifier import IntIdentifier from kwai.core.domain.value_objects.name import Name from kwai.core.domain.value_objects.owner import Owner @@ -34,6 +35,26 @@ def create_owner(self) -> Owner: OwnersTable = Table("users", OwnerRow) +@dataclass(kw_only=True, frozen=True, slots=True) +class OwnerTableRow(TableRow): + """Represent the owner data.""" + + __table_name__ = "users" + + id: int + uuid: str + first_name: str + last_name: str + + def create_owner(self) -> Owner: + """Create an Author value object from row data.""" + return Owner( + id=IntIdentifier(self.id), + uuid=UniqueId.create_from_string(self.uuid), + name=Name(first_name=self.first_name, last_name=self.last_name), + ) + + @dataclass(kw_only=True, frozen=True, slots=True) class TextRow: """Represent a row for a content table. From 68c319f00674987ff0f16fbcef8459150b638251 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sun, 2 Jun 2024 16:11:50 +0200 Subject: [PATCH 072/410] fix: rename person_id back to member_id --- backend/migrations/20240601194900_member_id.sql | 6 ++++++ backend/migrations/db/schema.sql | 11 ++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 backend/migrations/20240601194900_member_id.sql diff --git a/backend/migrations/20240601194900_member_id.sql b/backend/migrations/20240601194900_member_id.sql new file mode 100644 index 00000000..b34822dd --- /dev/null +++ b/backend/migrations/20240601194900_member_id.sql @@ -0,0 +1,6 @@ +-- migrate:up + +alter table coaches rename column person_id to member_id; +alter table team_members rename column person_id to member_id; + +-- migrate:down diff --git a/backend/migrations/db/schema.sql b/backend/migrations/db/schema.sql index 2fac7524..86c6afaa 100644 --- a/backend/migrations/db/schema.sql +++ b/backend/migrations/db/schema.sql @@ -41,7 +41,7 @@ CREATE TABLE `applications` ( /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `coaches` ( `id` int unsigned NOT NULL AUTO_INCREMENT, - `person_id` int NOT NULL, + `member_id` int NOT NULL, `description` text, `diploma` varchar(255) DEFAULT NULL, `active` tinyint(1) NOT NULL DEFAULT '1', @@ -347,11 +347,11 @@ CREATE TABLE `team_categories` ( /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `team_members` ( `team_id` int NOT NULL, - `person_id` int NOT NULL, + `member_id` int NOT NULL, `active` tinyint(1) NOT NULL DEFAULT '1', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NULL DEFAULT NULL, - PRIMARY KEY (`team_id`,`person_id`) + PRIMARY KEY (`team_id`,`member_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; @@ -555,7 +555,7 @@ CREATE TABLE `users` ( `uuid` varchar(255) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NULL DEFAULT NULL, - `person_id` int DEFAULT NULL, + `member_id` int DEFAULT NULL, `revoked` tinyint(1) NOT NULL DEFAULT '0', `last_unsuccessful_login` datetime DEFAULT NULL, `admin` tinyint(1) NOT NULL DEFAULT '0', @@ -588,5 +588,6 @@ INSERT INTO `schema_migrations` (version) VALUES ('20231110160912'), ('20240201192100'), ('20240502185700'), - ('20240525191900'); + ('20240525191900'), + ('20240601194900'); UNLOCK TABLES; From 7009b8702b1c8e9b0d47b02187615e610f73bf5d Mon Sep 17 00:00:00 2001 From: zumuta Date: Sun, 2 Jun 2024 16:19:44 +0200 Subject: [PATCH 073/410] refactor: rename coach.py into coaches.py --- backend/src/tests/fixtures/club/{coach.py => coaches.py} | 0 backend/src/tests/modules/club/conftest.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename backend/src/tests/fixtures/club/{coach.py => coaches.py} (100%) diff --git a/backend/src/tests/fixtures/club/coach.py b/backend/src/tests/fixtures/club/coaches.py similarity index 100% rename from backend/src/tests/fixtures/club/coach.py rename to backend/src/tests/fixtures/club/coaches.py diff --git a/backend/src/tests/modules/club/conftest.py b/backend/src/tests/modules/club/conftest.py index 5811efc6..9004a6ce 100644 --- a/backend/src/tests/modules/club/conftest.py +++ b/backend/src/tests/modules/club/conftest.py @@ -4,4 +4,4 @@ from tests.fixtures.club.contacts import * # noqa from tests.fixtures.club.persons import * # noqa from tests.fixtures.club.members import * # noqa -from tests.fixtures.club.coach import * # noqa +from tests.fixtures.club.coaches import * # noqa From 06902969cd786c060fa6049ccc1ae110fc9f8437 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sun, 2 Jun 2024 17:03:45 +0200 Subject: [PATCH 074/410] refactor: start using TableRow --- .../training/coaches/coach_db_query.py | 51 ++++++++--- .../modules/training/coaches/coach_tables.py | 38 ++++---- .../trainings/training_coach_db_query.py | 89 +++++++++++++------ .../training/trainings/training_db_query.py | 8 +- .../trainings/training_db_repository.py | 24 +++-- .../training/trainings/training_tables.py | 8 +- backend/src/tests/conftest.py | 4 +- .../coaches/test_coaches_db_repository.py | 23 +++-- .../src/tests/modules/training/conftest.py | 15 ++-- .../training/teams/test_team_db_repository.py | 2 +- .../modules/training/test_create_training.py | 10 +-- .../test_create_training_definition.py | 1 - .../modules/training/test_delete_training.py | 1 - .../modules/training/test_get_coaches.py | 1 + .../modules/training/test_get_training.py | 2 +- .../training/test_get_training_definition.py | 2 +- .../training/test_get_training_definitions.py | 2 +- .../modules/training/test_get_trainings.py | 2 +- .../modules/training/test_update_training.py | 2 +- .../test_update_training_definition.py | 1 - .../trainings/test_training_coach_db_query.py | 1 - .../trainings/test_training_db_query.py | 2 +- .../trainings/test_training_db_repository.py | 2 +- .../test_training_definition_db_query.py | 1 - .../test_training_definition_db_repository.py | 1 - .../trainings/test_training_team_db_query.py | 1 - 26 files changed, 170 insertions(+), 124 deletions(-) diff --git a/backend/src/kwai/modules/training/coaches/coach_db_query.py b/backend/src/kwai/modules/training/coaches/coach_db_query.py index 3f408180..cbc35129 100644 --- a/backend/src/kwai/modules/training/coaches/coach_db_query.py +++ b/backend/src/kwai/modules/training/coaches/coach_db_query.py @@ -1,10 +1,36 @@ """Module that defines a database query for coaches.""" + +from dataclasses import dataclass + from sql_smith.functions import on from kwai.core.db.database_query import DatabaseQuery -from kwai.modules.training.coaches.coach import CoachIdentifier +from kwai.core.db.table_row import JoinedTableRow +from kwai.core.domain.value_objects.name import Name +from kwai.modules.training.coaches.coach import CoachEntity, CoachIdentifier from kwai.modules.training.coaches.coach_query import CoachQuery -from kwai.modules.training.coaches.coach_tables import CoachesTable, PersonsTable +from kwai.modules.training.coaches.coach_tables import ( + CoachRow, + MemberRow, + PersonRow, +) + + +@dataclass(kw_only=True, frozen=True, slots=True) +class CoachQueryRow(JoinedTableRow): + """A data transfer object for the coach query.""" + + member: MemberRow + person: PersonRow + coach: CoachRow + + def create_entity(self) -> CoachEntity: + """Create a coach entity from a row.""" + return CoachEntity( + id_=CoachIdentifier(self.coach.id), + name=Name(first_name=self.person.firstname, last_name=self.person.lastname), + active=self.coach.active == 1, + ) class CoachDbQuery(DatabaseQuery, CoachQuery): @@ -12,29 +38,30 @@ class CoachDbQuery(DatabaseQuery, CoachQuery): @property def count_column(self) -> str: - return CoachesTable.column("id") + return CoachRow.column("id") def init(self): - self._query.from_(CoachesTable.table_name).columns( - *(CoachesTable.aliases() + PersonsTable.aliases()) - ).join( - PersonsTable.table_name, - on(CoachesTable.column("person_id"), PersonsTable.column("id")), + self._query.from_(CoachRow.__table_name__).join( + MemberRow.__table_name__, + on(MemberRow.column("id"), CoachRow.column("member_id")), + ).inner_join( + PersonRow.__table_name__, + on(MemberRow.column("person_id"), PersonRow.column("id")), ) @property def columns(self): - return CoachesTable.aliases() + PersonsTable.aliases() + return CoachQueryRow.get_aliases() def filter_by_ids(self, *ids: CoachIdentifier) -> "CoachQuery": unpacked_ids = tuple(i.value for i in ids) - self._query.and_where(CoachesTable.field("id").in_(*unpacked_ids)) + self._query.and_where(CoachRow.field("id").in_(*unpacked_ids)) return self def filter_by_id(self, id_: CoachIdentifier) -> "CoachQuery": - self._query.and_where(CoachesTable.field("id").eq(id_.value)) + self._query.and_where(CoachRow.field("id").eq(id_.value)) return self def filter_by_active(self) -> "CoachQuery": - self._query.and_where(CoachesTable.field("active").eq(1)) + self._query.and_where(CoachRow.field("active").eq(1)) return self diff --git a/backend/src/kwai/modules/training/coaches/coach_tables.py b/backend/src/kwai/modules/training/coaches/coach_tables.py index 10c719c8..5cc439e3 100644 --- a/backend/src/kwai/modules/training/coaches/coach_tables.py +++ b/backend/src/kwai/modules/training/coaches/coach_tables.py @@ -1,38 +1,36 @@ """Module that defines all dataclasses for the tables containing coaches.""" + from dataclasses import dataclass -from kwai.core.db.table import Table -from kwai.core.domain.value_objects.name import Name -from kwai.modules.training.coaches.coach import CoachEntity, CoachIdentifier +from kwai.core.db.table_row import TableRow + + +@dataclass(kw_only=True, frozen=True, slots=True) +class MemberRow(TableRow): + """Represent a row of the members table.""" + + __table_name__ = "judo_members" + + id: int @dataclass(kw_only=True, frozen=True, slots=True) -class PersonRow: +class PersonRow(TableRow): """Represent a row of the persons table.""" + __table_name__ = "persons" + id: int lastname: str firstname: str -PersonsTable = Table("persons", PersonRow) - - @dataclass(kw_only=True, frozen=True, slots=True) -class CoachRow: +class CoachRow(TableRow): """Represent a row of the coaches table.""" + __table_name__ = "coaches" + id: int - person_id: int + member_id: int active: int - - def create_entity(self, person_row: PersonRow) -> CoachEntity: - """Create a coach entity from this row.""" - return CoachEntity( - id_=CoachIdentifier(self.id), - name=Name(first_name=person_row.firstname, last_name=person_row.lastname), - active=self.active == 1, - ) - - -CoachesTable = Table("coaches", CoachRow) diff --git a/backend/src/kwai/modules/training/trainings/training_coach_db_query.py b/backend/src/kwai/modules/training/trainings/training_coach_db_query.py index 060ac84e..d5ae47ee 100644 --- a/backend/src/kwai/modules/training/trainings/training_coach_db_query.py +++ b/backend/src/kwai/modules/training/trainings/training_coach_db_query.py @@ -1,39 +1,78 @@ """Module that defines a database query to get coaches of training(s).""" + from collections import defaultdict +from dataclasses import dataclass from sql_smith.functions import on from kwai.core.db.database_query import DatabaseQuery -from kwai.core.db.rows import OwnersTable -from kwai.modules.training.coaches.coach_tables import CoachesTable, PersonsTable +from kwai.core.db.rows import OwnersTable, OwnerTableRow +from kwai.core.db.table_row import JoinedTableRow +from kwai.core.domain.value_objects.name import Name +from kwai.modules.training.coaches.coach import CoachEntity, CoachIdentifier +from kwai.modules.training.coaches.coach_tables import ( + CoachRow, + MemberRow, + PersonRow, +) from kwai.modules.training.trainings.training import TrainingIdentifier -from kwai.modules.training.trainings.training_tables import TrainingCoachesTable +from kwai.modules.training.trainings.training_tables import ( + TrainingCoachRow, +) from kwai.modules.training.trainings.value_objects import TrainingCoach +@dataclass(kw_only=True, frozen=True, slots=True) +class TrainingCoachQueryRow(JoinedTableRow): + """A data transfer object for the training coach query.""" + + training_coach: TrainingCoachRow + member: MemberRow + person: PersonRow + coach: CoachRow + owner: OwnerTableRow + + def create_coach(self) -> TrainingCoach: + """Create a training coach from a row.""" + return TrainingCoach( + coach=CoachEntity( + id_=CoachIdentifier(self.coach.id), + name=Name( + first_name=self.person.firstname, last_name=self.person.lastname + ), + active=self.coach.active == 1, + ), + owner=self.owner.create_owner(), + present=self.training_coach.present == 1, + type=self.training_coach.coach_type, + payed=self.training_coach.payed == 1, + remark=( + "" if self.training_coach.remark is None else self.training_coach.remark + ), + ) + + class TrainingCoachDbQuery(DatabaseQuery): """A database query for getting coaches of training(s).""" def init(self): - self._query.from_(TrainingCoachesTable.table_name).left_join( - CoachesTable.table_name, - on(TrainingCoachesTable.column("coach_id"), CoachesTable.column("id")), + self._query.from_(TrainingCoachRow.__table_name__).left_join( + CoachRow.__table_name__, + on(TrainingCoachRow.column("coach_id"), CoachRow.column("id")), + ).join( + MemberRow.__table_name__, + on(CoachRow.column("member_id"), MemberRow.column("id")), ).join( - PersonsTable.table_name, - on(CoachesTable.column("person_id"), PersonsTable.column("id")), + PersonRow.__table_name__, + on(MemberRow.column("person_id"), PersonRow.column("id")), ).join( OwnersTable.table_name, - on(CoachesTable.column("user_id"), OwnersTable.column("id")), + on(CoachRow.column("user_id"), OwnerTableRow.column("id")), ) @property def columns(self): - return ( - TrainingCoachesTable.aliases() - + CoachesTable.aliases() - + PersonsTable.aliases() - + OwnersTable.aliases() - ) + return TrainingCoachQueryRow.get_aliases() def filter_by_trainings(self, *ids: TrainingIdentifier) -> "TrainingCoachDbQuery": """Filter by trainings. @@ -41,9 +80,7 @@ def filter_by_trainings(self, *ids: TrainingIdentifier) -> "TrainingCoachDbQuery Only the rows of the trainings with the given ids, will be returned. """ unpacked_ids = tuple(i.value for i in ids) - self._query.and_where( - TrainingCoachesTable.field("training_id").in_(*unpacked_ids) - ) + self._query.and_where(TrainingCoachRow.field("training_id").in_(*unpacked_ids)) return self async def fetch_coaches(self) -> dict[TrainingIdentifier, list[TrainingCoach]]: @@ -58,15 +95,9 @@ async def fetch_coaches(self) -> dict[TrainingIdentifier, list[TrainingCoach]]: """ result: dict[TrainingIdentifier, list[TrainingCoach]] = defaultdict(list) - async for record in self.fetch(): - training_coach = TrainingCoachesTable(record) - owner_row = OwnersTable(record).create_owner() - coach_row = CoachesTable(record) - person_row = PersonsTable(record) - result[TrainingIdentifier(training_coach.training_id)].append( - training_coach.create_coach( - coach_row.create_entity(person_row), - owner_row, - ) - ) + async for row in self.fetch(): + training_coach_row = TrainingCoachQueryRow.map(row) + result[ + TrainingIdentifier(training_coach_row.training_coach.training_id) + ].append(training_coach_row.create_coach()) return result diff --git a/backend/src/kwai/modules/training/trainings/training_db_query.py b/backend/src/kwai/modules/training/trainings/training_db_query.py index 4ca46f14..414a9c5d 100644 --- a/backend/src/kwai/modules/training/trainings/training_db_query.py +++ b/backend/src/kwai/modules/training/trainings/training_db_query.py @@ -15,7 +15,7 @@ from kwai.modules.training.trainings.training_definition import TrainingDefinitionEntity from kwai.modules.training.trainings.training_query import TrainingQuery from kwai.modules.training.trainings.training_tables import ( - TrainingCoachesTable, + TrainingCoachRow, TrainingContentsTable, TrainingDefinitionsTable, TrainingsTable, @@ -118,9 +118,9 @@ def filter_by_coach(self, coach: CoachEntity) -> "TrainingQuery": inner_select = ( self._database.create_query_factory() .select() - .columns(TrainingCoachesTable.column("training_id")) - .from_(TrainingCoachesTable.table_name) - .where(TrainingCoachesTable.field("coach_id").eq(coach.id.value)) + .columns(TrainingCoachRow.column("training_id")) + .from_(TrainingCoachRow.__table_name__) + .where(TrainingCoachRow.field("coach_id").eq(coach.id.value)) ) condition = TrainingsTable.field("id").in_(express("{}", inner_select)) self._query.and_where(group(condition)) diff --git a/backend/src/kwai/modules/training/trainings/training_db_repository.py b/backend/src/kwai/modules/training/trainings/training_db_repository.py index 0c59082c..289b4c6d 100644 --- a/backend/src/kwai/modules/training/trainings/training_db_repository.py +++ b/backend/src/kwai/modules/training/trainings/training_db_repository.py @@ -1,4 +1,5 @@ """Module for implementing a training repository for a database.""" + from typing import AsyncIterator from sql_smith.functions import alias, express, field @@ -18,7 +19,6 @@ TrainingRepository, ) from kwai.modules.training.trainings.training_tables import ( - TrainingCoachesTable, TrainingCoachRow, TrainingContentsTable, TrainingDefinitionsTable, @@ -117,17 +117,17 @@ async def get_all( training_query = TrainingCoachDbQuery(self._database).filter_by_trainings( *trainings.keys() ) - coaches: dict[ - TrainingIdentifier, list[TrainingCoach] - ] = await training_query.fetch_coaches() + coaches: dict[TrainingIdentifier, list[TrainingCoach]] = ( + await training_query.fetch_coaches() + ) # Get the teams of all trainings team_query = TrainingTeamDbQuery(self._database).filter_by_trainings( *trainings.keys() ) - teams: dict[ - TrainingIdentifier, list[TeamEntity] - ] = await team_query.fetch_teams() + teams: dict[TrainingIdentifier, list[TeamEntity]] = ( + await team_query.fetch_teams() + ) for training in trainings.values(): training_coaches = coaches.get(training.id, []) @@ -190,7 +190,7 @@ async def _insert_coaches(self, training: TrainingEntity): ] if training_coach_rows: await self._database.insert( - TrainingCoachesTable.table_name, *training_coach_rows + TrainingCoachRow.__table_name__, *training_coach_rows ) async def _insert_teams(self, training: TrainingEntity): @@ -207,7 +207,7 @@ async def _delete_coaches(self, training: TrainingEntity): """Delete coaches of the training.""" delete_coaches_query = ( self._database.create_query_factory() - .delete(TrainingCoachesTable.table_name) + .delete(TrainingCoachRow.__table_name__) .where(field("training_id").eq(training.id.value)) ) await self._database.execute(delete_coaches_query) @@ -258,10 +258,8 @@ async def reset_definition( delete_coaches = ( self._database.create_query_factory() - .delete(TrainingCoachesTable.table_name) - .and_where( - TrainingCoachesTable.field("training_id").in_(trainings_query) - ) + .delete(TrainingCoachRow.__table_name__) + .and_where(TrainingCoachRow.field("training_id").in_(trainings_query)) ) await self._database.execute(delete_coaches) diff --git a/backend/src/kwai/modules/training/trainings/training_tables.py b/backend/src/kwai/modules/training/trainings/training_tables.py index e8f5be37..9dcfac9f 100644 --- a/backend/src/kwai/modules/training/trainings/training_tables.py +++ b/backend/src/kwai/modules/training/trainings/training_tables.py @@ -5,6 +5,7 @@ from kwai.core.db.rows import TextRow from kwai.core.db.table import Table +from kwai.core.db.table_row import TableRow from kwai.core.domain.value_objects.owner import Owner from kwai.core.domain.value_objects.period import Period from kwai.core.domain.value_objects.text import LocaleText @@ -232,9 +233,11 @@ def persist( @dataclass(kw_only=True, frozen=True, slots=True) -class TrainingCoachRow: +class TrainingCoachRow(TableRow): """Represent a row of the training_coaches table.""" + __table_name__ = "training_coaches" + training_id: int coach_id: int coach_type: int @@ -272,9 +275,6 @@ def persist(cls, training, training_coach: TrainingCoach) -> "TrainingCoachRow": ) -TrainingCoachesTable = Table("training_coaches", TrainingCoachRow) - - @dataclass(kw_only=True, frozen=True, slots=True) class TrainingTeamRow: """Represent a row of the training_teams table.""" diff --git a/backend/src/tests/conftest.py b/backend/src/tests/conftest.py index 52c27b76..c723bb55 100644 --- a/backend/src/tests/conftest.py +++ b/backend/src/tests/conftest.py @@ -1,10 +1,9 @@ """Module for sharing fixtures in this module.""" + import asyncio from typing import AsyncIterator, Iterator import pytest -from redis.asyncio import Redis - from kwai.core.db.database import Database from kwai.core.domain.value_objects.email_address import EmailAddress from kwai.core.domain.value_objects.name import Name @@ -22,6 +21,7 @@ from kwai.modules.identity.users.user_account_db_repository import ( UserAccountDbRepository, ) +from redis.asyncio import Redis @pytest.fixture(scope="session") diff --git a/backend/src/tests/modules/training/coaches/test_coaches_db_repository.py b/backend/src/tests/modules/training/coaches/test_coaches_db_repository.py index aabcc80a..ce039871 100644 --- a/backend/src/tests/modules/training/coaches/test_coaches_db_repository.py +++ b/backend/src/tests/modules/training/coaches/test_coaches_db_repository.py @@ -1,40 +1,37 @@ """Module for testing the coach database repository.""" -import pytest +import pytest from kwai.core.db.database import Database from kwai.core.db.exceptions import QueryException -from kwai.modules.training.coaches.coach import CoachIdentifier from kwai.modules.training.coaches.coach_db_repository import CoachDbRepository -from kwai.modules.training.coaches.coach_repository import CoachNotFoundException -async def test_get_by_id(database: Database): +async def test_get_by_id(database: Database, make_coach_in_db): """Test get_by_id method.""" + coach = await make_coach_in_db() repo = CoachDbRepository(database) try: - await repo.get_by_id(CoachIdentifier(1)) - except CoachNotFoundException: - pass # Ok + await repo.get_by_id(coach.id) except QueryException as qe: pytest.fail(str(qe)) -async def test_get_by_ids(database: Database): +async def test_get_by_ids(database: Database, make_coach_in_db): """Test get_by_ids method.""" repo = CoachDbRepository(database) + coach_1 = await make_coach_in_db() + coach_2 = await make_coach_in_db() try: - { - coach.id: coach - async for coach in repo.get_by_ids(CoachIdentifier(1), CoachIdentifier(2)) - } + {coach.id: coach async for coach in repo.get_by_ids(coach_1.id, coach_2.id)} except QueryException as qe: pytest.fail(str(qe)) -async def test_get_all(database: Database): +async def test_get_all(database: Database, make_coach_in_db): """Test get_all method.""" + await make_coach_in_db() repo = CoachDbRepository(database) try: diff --git a/backend/src/tests/modules/training/conftest.py b/backend/src/tests/modules/training/conftest.py index f1384b1a..ff5fd007 100644 --- a/backend/src/tests/modules/training/conftest.py +++ b/backend/src/tests/modules/training/conftest.py @@ -6,7 +6,6 @@ from typing import Any import pytest - from kwai.core.db.database import Database from kwai.core.domain.value_objects.owner import Owner from kwai.core.domain.value_objects.period import Period @@ -15,15 +14,19 @@ from kwai.core.domain.value_objects.timestamp import Timestamp from kwai.core.domain.value_objects.weekday import Weekday from kwai.modules.training.coaches.coach_tables import ( - CoachesTable, CoachRow, PersonRow, - PersonsTable, ) from kwai.modules.training.teams.team_tables import TeamRow, TeamsTable from kwai.modules.training.trainings.training import TrainingEntity from kwai.modules.training.trainings.training_definition import TrainingDefinitionEntity +from tests.fixtures.club.coaches import * # noqa +from tests.fixtures.club.contacts import * # noqa +from tests.fixtures.club.countries import * # noqa +from tests.fixtures.club.members import * # noqa +from tests.fixtures.club.persons import * # noqa + Context = dict[str, list[Any]] @@ -47,7 +50,7 @@ async def seed_persons(database: Database, person_row: PersonRow, context: Conte """Seed the database with persons.""" # For now, we create the query, in the future a repository from the members # bounded context can be used. - query = database.create_query_factory().insert(PersonsTable.table_name) + query = database.create_query_factory().insert(PersonRow.__table_name__) person_dict = dataclasses.asdict(person_row) del person_dict["id"] person_dict["gender"] = 1 @@ -63,13 +66,13 @@ async def seed_persons(database: Database, person_row: PersonRow, context: Conte @pytest.fixture(scope="module") def coach_row(seed_persons, context: Context) -> CoachRow: """Fixture for creating a coach row.""" - return CoachRow(id=0, person_id=context["persons"][0].id, active=True) + return CoachRow(id=0, member_id=context["persons"][0].id, active=True) @pytest.fixture(scope="module", autouse=True) async def seed_coaches(database: Database, coach_row: CoachRow, context: Context): """Seed the database with coaches.""" - query = database.create_query_factory().insert(CoachesTable.table_name) + query = database.create_query_factory().insert(CoachRow.__table_name__) coach_dict = dataclasses.asdict(coach_row) del coach_dict["id"] query.columns(*coach_dict.keys()).values(*coach_dict.values()) diff --git a/backend/src/tests/modules/training/teams/test_team_db_repository.py b/backend/src/tests/modules/training/teams/test_team_db_repository.py index 68e69e9b..efcdd70a 100644 --- a/backend/src/tests/modules/training/teams/test_team_db_repository.py +++ b/backend/src/tests/modules/training/teams/test_team_db_repository.py @@ -1,6 +1,6 @@ """Module for testing the team database repository.""" -import pytest +import pytest from kwai.core.db.database import Database from kwai.core.db.exceptions import QueryException from kwai.modules.training.teams.team import TeamIdentifier diff --git a/backend/src/tests/modules/training/test_create_training.py b/backend/src/tests/modules/training/test_create_training.py index 1944ed69..df8710f6 100644 --- a/backend/src/tests/modules/training/test_create_training.py +++ b/backend/src/tests/modules/training/test_create_training.py @@ -1,12 +1,11 @@ """Module for testing the use case "Create Training".""" import pytest - from kwai.core.db.database import Database from kwai.core.domain.use_case import TextCommand from kwai.core.domain.value_objects.owner import Owner from kwai.core.domain.value_objects.timestamp import Timestamp -from kwai.modules.training.coaches.coach import CoachEntity, CoachIdentifier +from kwai.modules.training.coaches.coach import CoachEntity from kwai.modules.training.coaches.coach_db_repository import CoachDbRepository from kwai.modules.training.coaches.coach_repository import CoachRepository from kwai.modules.training.create_training import CreateTraining, CreateTrainingCommand @@ -22,6 +21,7 @@ TrainingDefinitionRepository, ) from kwai.modules.training.trainings.training_repository import TrainingRepository + from tests.modules.training.conftest import Context @@ -50,11 +50,9 @@ def team_repo(database: Database) -> TeamRepository: @pytest.fixture -async def coach( - database: Database, context: Context, coach_repo: CoachRepository -) -> CoachEntity: +async def coach(make_coach_in_db) -> CoachEntity: """A fixture for a coach.""" - return await coach_repo.get_by_id(CoachIdentifier(context.get("coaches")[0].id)) + return await make_coach_in_db() @pytest.fixture diff --git a/backend/src/tests/modules/training/test_create_training_definition.py b/backend/src/tests/modules/training/test_create_training_definition.py index c7425d4f..843cc41b 100644 --- a/backend/src/tests/modules/training/test_create_training_definition.py +++ b/backend/src/tests/modules/training/test_create_training_definition.py @@ -1,7 +1,6 @@ """Module for testing the use case "Create Training Definition".""" import pytest - from kwai.core.db.database import Database from kwai.core.domain.value_objects.owner import Owner from kwai.modules.training.create_training_definition import ( diff --git a/backend/src/tests/modules/training/test_delete_training.py b/backend/src/tests/modules/training/test_delete_training.py index 6434430e..e67f9746 100644 --- a/backend/src/tests/modules/training/test_delete_training.py +++ b/backend/src/tests/modules/training/test_delete_training.py @@ -1,7 +1,6 @@ """Module for testing the use case "Delete Training".""" import pytest - from kwai.core.db.database import Database from kwai.modules.training.delete_training import DeleteTraining, DeleteTrainingCommand from kwai.modules.training.trainings.training import TrainingEntity diff --git a/backend/src/tests/modules/training/test_get_coaches.py b/backend/src/tests/modules/training/test_get_coaches.py index a1fccfad..313c6f89 100644 --- a/backend/src/tests/modules/training/test_get_coaches.py +++ b/backend/src/tests/modules/training/test_get_coaches.py @@ -1,4 +1,5 @@ """Module for testing the GetCoaches use case.""" + from kwai.core.db.database import Database from kwai.modules.training.coaches.coach_db_repository import CoachDbRepository from kwai.modules.training.get_coaches import GetCoaches, GetCoachesCommand diff --git a/backend/src/tests/modules/training/test_get_training.py b/backend/src/tests/modules/training/test_get_training.py index 0c61c003..556dc266 100644 --- a/backend/src/tests/modules/training/test_get_training.py +++ b/backend/src/tests/modules/training/test_get_training.py @@ -1,6 +1,6 @@ """Module for testing the use case "Get Training".""" -import pytest +import pytest from kwai.core.db.database import Database from kwai.modules.training.get_training import GetTraining, GetTrainingCommand from kwai.modules.training.trainings.training_db_repository import TrainingDbRepository diff --git a/backend/src/tests/modules/training/test_get_training_definition.py b/backend/src/tests/modules/training/test_get_training_definition.py index 059e8719..26f62bf0 100644 --- a/backend/src/tests/modules/training/test_get_training_definition.py +++ b/backend/src/tests/modules/training/test_get_training_definition.py @@ -1,6 +1,6 @@ """Module for testing the use case "Get Training Definition".""" -import pytest +import pytest from kwai.core.db.database import Database from kwai.modules.training.get_training_definition import ( GetTrainingDefinition, diff --git a/backend/src/tests/modules/training/test_get_training_definitions.py b/backend/src/tests/modules/training/test_get_training_definitions.py index b872a3ec..7097f16d 100644 --- a/backend/src/tests/modules/training/test_get_training_definitions.py +++ b/backend/src/tests/modules/training/test_get_training_definitions.py @@ -1,8 +1,8 @@ """Module for testing the use case "Get Training Definitions".""" + from typing import AsyncIterator import pytest - from kwai.core.db.database import Database from kwai.modules.training.get_training_definitions import ( GetTrainingDefinitions, diff --git a/backend/src/tests/modules/training/test_get_trainings.py b/backend/src/tests/modules/training/test_get_trainings.py index 7ad9da7c..cf7574cf 100644 --- a/backend/src/tests/modules/training/test_get_trainings.py +++ b/backend/src/tests/modules/training/test_get_trainings.py @@ -1,6 +1,6 @@ """Module for testing the use case "Get Trainings".""" -import pytest +import pytest from kwai.core.db.database import Database from kwai.modules.training.coaches.coach_db_repository import CoachDbRepository from kwai.modules.training.coaches.coach_repository import CoachRepository diff --git a/backend/src/tests/modules/training/test_update_training.py b/backend/src/tests/modules/training/test_update_training.py index bc857841..2674f2bb 100644 --- a/backend/src/tests/modules/training/test_update_training.py +++ b/backend/src/tests/modules/training/test_update_training.py @@ -1,7 +1,6 @@ """Module for testing the use case "Update Training".""" import pytest - from kwai.core.db.database import Database from kwai.core.domain.use_case import TextCommand from kwai.core.domain.value_objects.owner import Owner @@ -26,6 +25,7 @@ from kwai.modules.training.trainings.training_repository import TrainingRepository from kwai.modules.training.trainings.value_objects import TrainingCoach from kwai.modules.training.update_training import UpdateTraining, UpdateTrainingCommand + from tests.modules.training.conftest import Context diff --git a/backend/src/tests/modules/training/test_update_training_definition.py b/backend/src/tests/modules/training/test_update_training_definition.py index 26bc27e6..dfd4d944 100644 --- a/backend/src/tests/modules/training/test_update_training_definition.py +++ b/backend/src/tests/modules/training/test_update_training_definition.py @@ -1,7 +1,6 @@ """Module for testing the use case "Update Training Definition".""" import pytest - from kwai.core.db.database import Database from kwai.core.domain.value_objects.owner import Owner from kwai.core.domain.value_objects.time_period import TimePeriod diff --git a/backend/src/tests/modules/training/trainings/test_training_coach_db_query.py b/backend/src/tests/modules/training/trainings/test_training_coach_db_query.py index eb90cad9..2376e138 100644 --- a/backend/src/tests/modules/training/trainings/test_training_coach_db_query.py +++ b/backend/src/tests/modules/training/trainings/test_training_coach_db_query.py @@ -1,7 +1,6 @@ """Module for testing TrainingCoachDbQuery.""" import pytest - from kwai.core.db.database import Database from kwai.modules.training.trainings.training import TrainingIdentifier from kwai.modules.training.trainings.training_coach_db_query import TrainingCoachDbQuery diff --git a/backend/src/tests/modules/training/trainings/test_training_db_query.py b/backend/src/tests/modules/training/trainings/test_training_db_query.py index b73153c1..aaa78990 100644 --- a/backend/src/tests/modules/training/trainings/test_training_db_query.py +++ b/backend/src/tests/modules/training/trainings/test_training_db_query.py @@ -1,8 +1,8 @@ """Module for testing TrainingDbQuery.""" + from datetime import datetime, time, timedelta import pytest - from kwai.core.db.database import Database from kwai.core.domain.value_objects.identifier import IntIdentifier from kwai.core.domain.value_objects.name import Name diff --git a/backend/src/tests/modules/training/trainings/test_training_db_repository.py b/backend/src/tests/modules/training/trainings/test_training_db_repository.py index cb9b7ec8..2281974b 100644 --- a/backend/src/tests/modules/training/trainings/test_training_db_repository.py +++ b/backend/src/tests/modules/training/trainings/test_training_db_repository.py @@ -1,7 +1,6 @@ """Module for testing the training database repository.""" import pytest - from kwai.core.db.database import Database from kwai.core.db.exceptions import QueryException from kwai.core.domain.entity import Entity @@ -23,6 +22,7 @@ TrainingRepository, ) from kwai.modules.training.trainings.value_objects import TrainingCoach + from tests.modules.training.conftest import Context pytestmark = pytest.mark.db diff --git a/backend/src/tests/modules/training/trainings/test_training_definition_db_query.py b/backend/src/tests/modules/training/trainings/test_training_definition_db_query.py index 30853a38..400e1e49 100644 --- a/backend/src/tests/modules/training/trainings/test_training_definition_db_query.py +++ b/backend/src/tests/modules/training/trainings/test_training_definition_db_query.py @@ -1,7 +1,6 @@ """Module for testing TrainingDefinitionDbQuery.""" import pytest - from kwai.core.db.database import Database from kwai.modules.training.trainings.training import TrainingIdentifier from kwai.modules.training.trainings.training_definition_db_query import ( diff --git a/backend/src/tests/modules/training/trainings/test_training_definition_db_repository.py b/backend/src/tests/modules/training/trainings/test_training_definition_db_repository.py index c4181f60..4af9b11d 100644 --- a/backend/src/tests/modules/training/trainings/test_training_definition_db_repository.py +++ b/backend/src/tests/modules/training/trainings/test_training_definition_db_repository.py @@ -1,7 +1,6 @@ """Module for testing the training definition repository.""" import pytest - from kwai.core.db.database import Database from kwai.core.domain.entity import Entity from kwai.modules.training.trainings.training_definition import ( diff --git a/backend/src/tests/modules/training/trainings/test_training_team_db_query.py b/backend/src/tests/modules/training/trainings/test_training_team_db_query.py index 5f6602e4..6598a1fb 100644 --- a/backend/src/tests/modules/training/trainings/test_training_team_db_query.py +++ b/backend/src/tests/modules/training/trainings/test_training_team_db_query.py @@ -1,7 +1,6 @@ """Module for testing TrainingTeamDbQuery.""" import pytest - from kwai.core.db.database import Database from kwai.modules.training.trainings.training import TrainingIdentifier from kwai.modules.training.trainings.training_team_db_query import TrainingTeamDbQuery From cd377df864bcb8b9ab37febcaad2e1dc69cf7ab3 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sun, 2 Jun 2024 17:06:25 +0200 Subject: [PATCH 075/410] refactor: rename coach_tables into _tables.py --- .../training/coaches/{coach_tables.py => _tables.py} | 0 .../src/kwai/modules/training/coaches/coach_db_query.py | 6 +++--- .../kwai/modules/training/coaches/coach_db_repository.py | 8 ++++---- .../modules/training/trainings/training_coach_db_query.py | 4 ++-- backend/src/tests/modules/training/conftest.py | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) rename backend/src/kwai/modules/training/coaches/{coach_tables.py => _tables.py} (100%) diff --git a/backend/src/kwai/modules/training/coaches/coach_tables.py b/backend/src/kwai/modules/training/coaches/_tables.py similarity index 100% rename from backend/src/kwai/modules/training/coaches/coach_tables.py rename to backend/src/kwai/modules/training/coaches/_tables.py diff --git a/backend/src/kwai/modules/training/coaches/coach_db_query.py b/backend/src/kwai/modules/training/coaches/coach_db_query.py index cbc35129..8a3fa4bc 100644 --- a/backend/src/kwai/modules/training/coaches/coach_db_query.py +++ b/backend/src/kwai/modules/training/coaches/coach_db_query.py @@ -7,13 +7,13 @@ from kwai.core.db.database_query import DatabaseQuery from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.value_objects.name import Name -from kwai.modules.training.coaches.coach import CoachEntity, CoachIdentifier -from kwai.modules.training.coaches.coach_query import CoachQuery -from kwai.modules.training.coaches.coach_tables import ( +from kwai.modules.training.coaches._tables import ( CoachRow, MemberRow, PersonRow, ) +from kwai.modules.training.coaches.coach import CoachEntity, CoachIdentifier +from kwai.modules.training.coaches.coach_query import CoachQuery @dataclass(kw_only=True, frozen=True, slots=True) diff --git a/backend/src/kwai/modules/training/coaches/coach_db_repository.py b/backend/src/kwai/modules/training/coaches/coach_db_repository.py index 446afd56..22440e27 100644 --- a/backend/src/kwai/modules/training/coaches/coach_db_repository.py +++ b/backend/src/kwai/modules/training/coaches/coach_db_repository.py @@ -3,6 +3,10 @@ from typing import AsyncIterator from kwai.core.db.database import Database +from kwai.modules.training.coaches._tables import ( + CoachRow, + PersonRow, +) from kwai.modules.training.coaches.coach import CoachEntity, CoachIdentifier from kwai.modules.training.coaches.coach_db_query import CoachDbQuery, CoachQueryRow from kwai.modules.training.coaches.coach_query import CoachQuery @@ -10,10 +14,6 @@ CoachNotFoundException, CoachRepository, ) -from kwai.modules.training.coaches.coach_tables import ( - CoachRow, - PersonRow, -) def _create_entity(coach_row: CoachRow, person_row: PersonRow) -> CoachEntity: diff --git a/backend/src/kwai/modules/training/trainings/training_coach_db_query.py b/backend/src/kwai/modules/training/trainings/training_coach_db_query.py index d5ae47ee..6f43d7e1 100644 --- a/backend/src/kwai/modules/training/trainings/training_coach_db_query.py +++ b/backend/src/kwai/modules/training/trainings/training_coach_db_query.py @@ -9,12 +9,12 @@ from kwai.core.db.rows import OwnersTable, OwnerTableRow from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.value_objects.name import Name -from kwai.modules.training.coaches.coach import CoachEntity, CoachIdentifier -from kwai.modules.training.coaches.coach_tables import ( +from kwai.modules.training.coaches._tables import ( # noqa CoachRow, MemberRow, PersonRow, ) +from kwai.modules.training.coaches.coach import CoachEntity, CoachIdentifier from kwai.modules.training.trainings.training import TrainingIdentifier from kwai.modules.training.trainings.training_tables import ( TrainingCoachRow, diff --git a/backend/src/tests/modules/training/conftest.py b/backend/src/tests/modules/training/conftest.py index ff5fd007..ba9dca76 100644 --- a/backend/src/tests/modules/training/conftest.py +++ b/backend/src/tests/modules/training/conftest.py @@ -13,7 +13,7 @@ from kwai.core.domain.value_objects.time_period import TimePeriod from kwai.core.domain.value_objects.timestamp import Timestamp from kwai.core.domain.value_objects.weekday import Weekday -from kwai.modules.training.coaches.coach_tables import ( +from kwai.modules.training.coaches._tables import ( CoachRow, PersonRow, ) From c899c8f5a2f94bc8f72a6b4f9640a0c61dd0a6e4 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sun, 2 Jun 2024 19:57:04 +0200 Subject: [PATCH 076/410] refactor: use training and training_definition fixture factories --- .../src/tests/fixtures/training/__init__.py | 1 + .../fixtures/training/training_definitions.py | 62 ++++++++++++ .../src/tests/fixtures/training/trainings.py | 97 ++++++++++++++++++ .../trainings/test_training_db_repository.py | 99 +++---------------- .../test_training_definition_db_repository.py | 73 ++++++-------- 5 files changed, 208 insertions(+), 124 deletions(-) create mode 100644 backend/src/tests/fixtures/training/__init__.py create mode 100644 backend/src/tests/fixtures/training/training_definitions.py create mode 100644 backend/src/tests/fixtures/training/trainings.py diff --git a/backend/src/tests/fixtures/training/__init__.py b/backend/src/tests/fixtures/training/__init__.py new file mode 100644 index 00000000..f79555c4 --- /dev/null +++ b/backend/src/tests/fixtures/training/__init__.py @@ -0,0 +1 @@ +"""Package for defining recurring fixtures for the training bounded context.""" diff --git a/backend/src/tests/fixtures/training/training_definitions.py b/backend/src/tests/fixtures/training/training_definitions.py new file mode 100644 index 00000000..55d004de --- /dev/null +++ b/backend/src/tests/fixtures/training/training_definitions.py @@ -0,0 +1,62 @@ +"""Module for defining fixture factories for training definitions.""" + +import pytest +from kwai.core.db.database import Database +from kwai.core.db.uow import UnitOfWork +from kwai.core.domain.value_objects.owner import Owner +from kwai.core.domain.value_objects.time_period import TimePeriod +from kwai.core.domain.value_objects.weekday import Weekday +from kwai.modules.training.trainings.training_definition import TrainingDefinitionEntity +from kwai.modules.training.trainings.training_definition_db_repository import ( + TrainingDefinitionDbRepository, +) + + +@pytest.fixture +def make_training_definition(owner: Owner): + """A factory fixture for creating a training definition.""" + + def _make_training_definition( + name: str | None = None, + description: str | None = None, + weekday: Weekday | None = None, + period: TimePeriod | None = None, + ) -> TrainingDefinitionEntity: + return TrainingDefinitionEntity( + name=name or "A training", + description=description or "A training definition", + weekday=weekday or Weekday.MONDAY, + period=period + or TimePeriod.create_from_string("18:00", "19:00", "Europe/Brussels"), + owner=owner, + ) + + return _make_training_definition + + +@pytest.fixture +def make_training_definition_in_db( + request, event_loop, database: Database, make_training_definition +): + """A fixture factory for a training definition in the database.""" + + async def _make_training_definition_in_db( + training_definition: TrainingDefinitionEntity | None = None, + ) -> TrainingDefinitionEntity: + training_definition = training_definition or make_training_definition() + repo = TrainingDefinitionDbRepository(database) + async with UnitOfWork(database): + training_definition = await repo.create(training_definition) + + def cleanup(): + async def acleanup(): + async with UnitOfWork(database): + await repo.delete(training_definition) + + event_loop.run_until_complete(acleanup()) + + request.addfinalizer(cleanup) + + return training_definition + + return _make_training_definition_in_db diff --git a/backend/src/tests/fixtures/training/trainings.py b/backend/src/tests/fixtures/training/trainings.py new file mode 100644 index 00000000..9b3cae8a --- /dev/null +++ b/backend/src/tests/fixtures/training/trainings.py @@ -0,0 +1,97 @@ +"""Module for defining factory fixtures for trainings.""" + +import pytest +from kwai.core.db.database import Database +from kwai.core.db.uow import UnitOfWork +from kwai.core.domain.value_objects.owner import Owner +from kwai.core.domain.value_objects.period import Period +from kwai.core.domain.value_objects.text import DocumentFormat, Locale, LocaleText +from kwai.modules.training.coaches.coach import CoachEntity +from kwai.modules.training.trainings.training import TrainingEntity +from kwai.modules.training.trainings.training_db_repository import TrainingDbRepository +from kwai.modules.training.trainings.value_objects import TrainingCoach + + +@pytest.fixture +def make_text( + *, + locale: Locale | None = None, + format_: DocumentFormat | None = None, + title: str = "Training Test", + content: str = "This is a test training", + summary: str = "Test", + owner: Owner, +): + """A factory fixture for a text.""" + + def _make_text() -> LocaleText: + return LocaleText( + title=title, + content=content, + summary=summary, + locale=locale or Locale.NL, + format=format_ or DocumentFormat.MARKDOWN, + author=owner, + ) + + return _make_text + + +@pytest.fixture +def make_training_coach(make_coach, owner: Owner): + """A factory fixture for a training coach.""" + + def _make_training_coach(coach: CoachEntity | None = None) -> TrainingCoach: + if coach is None: + # make_coach returns a coach entity from the club module, so we need + # to convert it to one for the training module. + club_coach = make_coach() + coach = CoachEntity( + id_=club_coach.id, name=club_coach.name, active=club_coach.is_active + ) + return TrainingCoach(coach=coach, owner=owner) + + return _make_training_coach + + +@pytest.fixture +def make_training(make_text, make_training_coach): + """A factory fixture for a training.""" + + def _make_training( + text: LocaleText | None = None, + coach: TrainingCoach | None = None, + period: Period | None = None, + ) -> TrainingEntity: + coach = coach or make_training_coach() + text = text or make_text() + period = period or Period.create_from_delta(hours=2) + return TrainingEntity(texts=[text], coaches=[coach], season=None, period=period) + + return _make_training + + +@pytest.fixture +def make_training_in_db(request, event_loop, database: Database, make_training): + """A factory fixture for a training in the database.""" + + async def _make_training_in_db( + training: TrainingEntity | None = None, + ) -> TrainingEntity: + training = training or make_training() + repo = TrainingDbRepository(database) + async with UnitOfWork(database): + training = await repo.create(training) + + def cleanup(): + async def acleanup(): + async with UnitOfWork(database): + await repo.delete(training) + + event_loop.run_until_complete(acleanup()) + + request.addfinalizer(cleanup) + + return training + + return _make_training_in_db diff --git a/backend/src/tests/modules/training/trainings/test_training_db_repository.py b/backend/src/tests/modules/training/trainings/test_training_db_repository.py index 2281974b..87656353 100644 --- a/backend/src/tests/modules/training/trainings/test_training_db_repository.py +++ b/backend/src/tests/modules/training/trainings/test_training_db_repository.py @@ -4,26 +4,10 @@ from kwai.core.db.database import Database from kwai.core.db.exceptions import QueryException from kwai.core.domain.entity import Entity -from kwai.core.domain.value_objects.name import Name -from kwai.core.domain.value_objects.owner import Owner -from kwai.core.domain.value_objects.period import Period -from kwai.core.domain.value_objects.text import DocumentFormat, Locale, LocaleText -from kwai.modules.training.coaches.coach import CoachEntity, CoachIdentifier -from kwai.modules.training.trainings.training import TrainingEntity from kwai.modules.training.trainings.training_db_repository import TrainingDbRepository -from kwai.modules.training.trainings.training_definition import TrainingDefinitionEntity -from kwai.modules.training.trainings.training_definition_db_repository import ( - TrainingDefinitionDbRepository, -) -from kwai.modules.training.trainings.training_definition_repository import ( - TrainingDefinitionRepository, -) from kwai.modules.training.trainings.training_repository import ( TrainingRepository, ) -from kwai.modules.training.trainings.value_objects import TrainingCoach - -from tests.modules.training.conftest import Context pytestmark = pytest.mark.db @@ -34,52 +18,15 @@ def repo(database: Database) -> TrainingRepository: return TrainingDbRepository(database) -@pytest.fixture(scope="module") -def training(user, context: Context, owner: Owner) -> TrainingEntity: - """A fixture for a training.""" - coach = context["coaches"][0] - person = context["persons"][0] - - text = [ - LocaleText( - locale=Locale.EN, - format=DocumentFormat.MARKDOWN, - title="Training U13", - summary="Training for U13", - content="", - author=owner, - ) - ] - return TrainingEntity( - texts=text, - period=Period.create_from_delta(hours=1), - coaches=[ - TrainingCoach( - coach=CoachEntity( - id_=CoachIdentifier(coach.id), - name=Name(first_name=person.firstname, last_name=person.lastname), - active=True, - ), - owner=owner, - remark="Test Training Coach", - ) - ], - ) - - -async def test_create( - repo: TrainingRepository, context: Context, training: TrainingEntity -): +async def test_create(make_training_in_db): """Test create a training.""" - new_training = await repo.create(training) - assert new_training is not None, "There should be a training." - context["trainings"] = [new_training] + training = await make_training_in_db() + assert training is not None, "There should be a training." -async def test_update(repo: TrainingRepository, context: Context): +async def test_update(repo: TrainingRepository, make_training_in_db): """Test update of a training.""" - assert len(context["trainings"]) > 0, "There should be a training" - training = context["trainings"][0] + training = await make_training_in_db() updated_training = Entity.replace(training, remark="This training is updated.") try: await repo.update(updated_training) @@ -87,45 +34,31 @@ async def test_update(repo: TrainingRepository, context: Context): pytest.fail(str(qe)) -async def test_get_all(repo: TrainingRepository): +async def test_get_all(repo: TrainingRepository, make_training_in_db): """Test get all trainings.""" + training = await make_training_in_db() trainings = {entity.id: entity async for entity in repo.get_all()} - assert trainings is not None, "There should be a result" + assert training.id in trainings, "The training should be returned in the list" -async def test_get_by_id(repo: TrainingRepository, context: Context): +async def test_get_by_id(repo: TrainingRepository, make_training_in_db): """Test get training by id.""" - assert len(context["trainings"]) > 0, "There should be a training" - training = context["trainings"][0] + training = await make_training_in_db() training = await repo.get_by_id(training.id) assert training is not None, "There should be a result" -async def test_delete(repo: TrainingRepository, context: Context): +async def test_delete(repo: TrainingRepository, make_training_in_db): """Test delete of a training.""" - assert len(context["trainings"]) > 0, "There should be a training" - training = context["trainings"][0] + training = await make_training_in_db() try: await repo.delete(training) except QueryException as qe: pytest.fail(str(qe)) -@pytest.fixture(scope="module") -def training_definition_repo(database: Database) -> TrainingDefinitionRepository: - """Fixture for a training definition repository.""" - return TrainingDefinitionDbRepository(database) - - -@pytest.fixture -async def saved_training_definition( - training_definition_repo: TrainingDefinitionRepository, - training_definition: TrainingDefinitionEntity, -) -> TrainingDefinitionEntity: - """A fixture for a training definition in the database.""" - return await training_definition_repo.create(training_definition) - - -async def test_reset_definition(repo: TrainingRepository, saved_training_definition): +async def test_reset_definition(database: Database, make_training_definition_in_db): """Test reset definition.""" - await repo.reset_definition(saved_training_definition, False) + definition = await make_training_definition_in_db() + repo = TrainingDbRepository(database) + await repo.reset_definition(definition, False) diff --git a/backend/src/tests/modules/training/trainings/test_training_definition_db_repository.py b/backend/src/tests/modules/training/trainings/test_training_definition_db_repository.py index 4af9b11d..9d3c1f49 100644 --- a/backend/src/tests/modules/training/trainings/test_training_definition_db_repository.py +++ b/backend/src/tests/modules/training/trainings/test_training_definition_db_repository.py @@ -2,78 +2,69 @@ import pytest from kwai.core.db.database import Database +from kwai.core.db.exceptions import QueryException from kwai.core.domain.entity import Entity -from kwai.modules.training.trainings.training_definition import ( - TrainingDefinitionEntity, -) from kwai.modules.training.trainings.training_definition_db_repository import ( TrainingDefinitionDbRepository, ) from kwai.modules.training.trainings.training_definition_repository import ( TrainingDefinitionNotFoundException, - TrainingDefinitionRepository, ) pytestmark = pytest.mark.db -@pytest.fixture(scope="module") -def repo(database: Database) -> TrainingDefinitionRepository: - """Fixture for a training definition repository.""" - return TrainingDefinitionDbRepository(database) - - -@pytest.fixture -async def saved_training_definition( - repo: TrainingDefinitionRepository, - training_definition: TrainingDefinitionEntity, -) -> TrainingDefinitionEntity: - """A fixture for a training definition in the database.""" - return await repo.create(training_definition) - - -def test_create(saved_training_definition: TrainingDefinitionEntity): +async def test_create(make_training_definition_in_db): """Test if the training definition was created.""" - assert ( - not saved_training_definition.id.is_empty() - ), "There should be a training definition created" + definition = await make_training_definition_in_db() + assert definition is not None, "There should be a training definition created" async def test_get_by_id( - repo: TrainingDefinitionRepository, - saved_training_definition: TrainingDefinitionEntity, + database: Database, + make_training_definition_in_db, ): """Test if the training definition can be found with the id.""" - entity = await repo.get_by_id(saved_training_definition.id) + repo = TrainingDefinitionDbRepository(database) + definition = await make_training_definition_in_db() + entity = await repo.get_by_id(definition.id) - assert ( - entity.id == saved_training_definition.id - ), "The training definition should be found" + assert entity.id == definition.id, "The training definition should be found" -async def test_get_all(repo: TrainingDefinitionRepository): +async def test_get_all( + database: Database, + make_training_definition_in_db, +): """Test if all training definitions can be loaded.""" + repo = TrainingDefinitionDbRepository(database) + definition = await make_training_definition_in_db() entities = {entity.id: entity async for entity in repo.get_all()} - assert entities is not None, "There should be a result" + assert definition.id in entities, "Definition should be in the list." async def test_update( - repo: TrainingDefinitionRepository, - saved_training_definition: TrainingDefinitionEntity, + database: Database, + make_training_definition_in_db, ): """Test update of training definition.""" - training_definition = Entity.replace( - saved_training_definition, remark="Training definition updated" - ) - await repo.update(training_definition) + repo = TrainingDefinitionDbRepository(database) + definition = await make_training_definition_in_db() + definition = Entity.replace(definition, remark="Training definition updated") + try: + await repo.update(definition) + except QueryException as qe: + pytest.fail(str(qe)) async def test_delete( - repo: TrainingDefinitionRepository, - saved_training_definition: TrainingDefinitionEntity, + database: Database, + make_training_definition_in_db, ): """Test if the training definition can be deleted.""" - await repo.delete(saved_training_definition) + repo = TrainingDefinitionDbRepository(database) + definition = await make_training_definition_in_db() + await repo.delete(definition) with pytest.raises(TrainingDefinitionNotFoundException): - await repo.get_by_id(saved_training_definition.id) + await repo.get_by_id(definition.id) From e1c5498f0ce7bfe500a3684c1913f92b93880758 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 11:21:12 +0200 Subject: [PATCH 077/410] test: add db mark --- .../modules/club/repositories/test_coach_db_repository.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/src/tests/modules/club/repositories/test_coach_db_repository.py b/backend/src/tests/modules/club/repositories/test_coach_db_repository.py index 054f2ea5..b3ab0c46 100644 --- a/backend/src/tests/modules/club/repositories/test_coach_db_repository.py +++ b/backend/src/tests/modules/club/repositories/test_coach_db_repository.py @@ -1,5 +1,9 @@ """Module for testing the coach database repository.""" +import pytest + +pytestmark = pytest.mark.db + async def test_create_coach(make_coach_in_db, make_member_in_db): """Test creating a coach.""" From 38bd9a0d7fdd0b89a93db031f9b63b8375ec39b9 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 11:31:29 +0200 Subject: [PATCH 078/410] feat: add team entity to club module --- backend/src/kwai/modules/club/domain/team.py | 46 +++++++++++++++++++ .../kwai/modules/club/repositories/_tables.py | 30 ++++++++++++ .../club/repositories/team_db_repository.py | 23 ++++++++++ .../club/repositories/team_repository.py | 17 +++++++ 4 files changed, 116 insertions(+) create mode 100644 backend/src/kwai/modules/club/domain/team.py create mode 100644 backend/src/kwai/modules/club/repositories/team_db_repository.py create mode 100644 backend/src/kwai/modules/club/repositories/team_repository.py diff --git a/backend/src/kwai/modules/club/domain/team.py b/backend/src/kwai/modules/club/domain/team.py new file mode 100644 index 00000000..fc758914 --- /dev/null +++ b/backend/src/kwai/modules/club/domain/team.py @@ -0,0 +1,46 @@ +"""Module for defining the team entity.""" + +from kwai.core.domain.entity import Entity +from kwai.core.domain.value_objects.identifier import IntIdentifier +from kwai.core.domain.value_objects.traceable_time import TraceableTime + +TeamIdentifier = IntIdentifier + + +class TeamEntity(Entity[TeamIdentifier]): + """Entity for a team of the club.""" + + def __init__( + self, + *, + id_: TeamIdentifier | None = None, + name: str, + active: bool = True, + remark: str = "", + traceable_time: TraceableTime | None = None, + ): + super().__init__(id_ or TeamIdentifier()) + self._name = name + self._active = active + self._remark = remark + self._traceable_time = traceable_time or TraceableTime() + + @property + def name(self) -> str: + """Return the name of the team.""" + return self._name + + @property + def is_active(self): + """Is this team active?""" + return self._active + + @property + def remark(self) -> str: + """Return the remark of the team.""" + return self._remark + + @property + def traceable_time(self) -> TraceableTime: + """Return the traceable_time.""" + return self._traceable_time diff --git a/backend/src/kwai/modules/club/repositories/_tables.py b/backend/src/kwai/modules/club/repositories/_tables.py index 263205e0..76d3a3de 100644 --- a/backend/src/kwai/modules/club/repositories/_tables.py +++ b/backend/src/kwai/modules/club/repositories/_tables.py @@ -17,6 +17,7 @@ from kwai.modules.club.domain.file_upload import FileUploadEntity from kwai.modules.club.domain.member import MemberEntity, MemberIdentifier from kwai.modules.club.domain.person import PersonEntity, PersonIdentifier +from kwai.modules.club.domain.team import TeamEntity from kwai.modules.club.domain.value_objects import ( Address, Birthdate, @@ -326,3 +327,32 @@ def persist(cls, coach: CoachEntity) -> Self: created_at=coach.traceable_time.created_at.timestamp, # type: ignore[arg-type] updated_at=coach.traceable_time.updated_at.timestamp, ) + + +@dataclass(kw_only=True, frozen=True, slots=True) +class TeamRow(TableRow): + """Represents a row of the teams table.""" + + __table_name__ = "teams" + + id: int + name: str + season_id: int | None + team_category_id: int | None + active: int + remark: str + created_at: datetime + updated_at: datetime | None + + @classmethod + def persist(cls, team: TeamEntity) -> Self: + return cls( + id=team.id.value, + name=team.name, + season_id=None, + team_category_id=None, + active=1 if team.is_active else 0, + remark=team.remark, + created_at=team.traceable_time.created_at.timestamp, # type: ignore[arg-type] + updated_at=team.traceable_time.updated_at.timestamp, + ) diff --git a/backend/src/kwai/modules/club/repositories/team_db_repository.py b/backend/src/kwai/modules/club/repositories/team_db_repository.py new file mode 100644 index 00000000..369f37d5 --- /dev/null +++ b/backend/src/kwai/modules/club/repositories/team_db_repository.py @@ -0,0 +1,23 @@ +"""Module that implements a team repository for a database.""" + +from kwai.core.db.database import Database +from kwai.core.domain.entity import Entity +from kwai.modules.club.domain.team import TeamEntity, TeamIdentifier +from kwai.modules.club.repositories._tables import TeamRow +from kwai.modules.club.repositories.team_repository import TeamRepository + + +class TeamDbRepository(TeamRepository): + """A team repository for a database.""" + + def __init__(self, database: Database): + self._database = database + + async def create(self, team: TeamEntity) -> TeamEntity: + new_team_id = await self._database.insert( + TeamRow.__table_name__, TeamRow.persist(team) + ) + return Entity.replace(team, id_=TeamIdentifier(new_team_id)) + + async def delete(self, team: TeamEntity) -> None: + await self._database.delete(team.id.value, TeamRow.__table_name__) diff --git a/backend/src/kwai/modules/club/repositories/team_repository.py b/backend/src/kwai/modules/club/repositories/team_repository.py new file mode 100644 index 00000000..d0f1c10d --- /dev/null +++ b/backend/src/kwai/modules/club/repositories/team_repository.py @@ -0,0 +1,17 @@ +"""Module that defines an interface for a team repository.""" + +from abc import ABC, abstractmethod + +from kwai.modules.club.domain.team import TeamEntity + + +class TeamRepository(ABC): + """An interface for a team repository.""" + + @abstractmethod + async def create(self, team: TeamEntity) -> TeamEntity: + """Save a new team.""" + + @abstractmethod + async def delete(self, team: TeamEntity) -> None: + """Delete a team.""" From 6facfe9caeddc3fd74a453b9feecca6e2d181a54 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 11:32:06 +0200 Subject: [PATCH 079/410] test: add fixture factory a team --- backend/src/tests/fixtures/club/teams.py | 41 ++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 backend/src/tests/fixtures/club/teams.py diff --git a/backend/src/tests/fixtures/club/teams.py b/backend/src/tests/fixtures/club/teams.py new file mode 100644 index 00000000..94c0094d --- /dev/null +++ b/backend/src/tests/fixtures/club/teams.py @@ -0,0 +1,41 @@ +"""Module for defining factory fixtures for teams.""" + +import pytest +from kwai.core.db.database import Database +from kwai.core.db.uow import UnitOfWork +from kwai.modules.club.domain.team import TeamEntity +from kwai.modules.club.repositories.team_db_repository import TeamDbRepository + + +@pytest.fixture +def make_team(): + """A factory fixture for creating a team.""" + + def _make_team(name: str | None = None) -> TeamEntity: + return TeamEntity(name=name or "U11") + + return _make_team + + +@pytest.fixture +def make_team_in_db(request, event_loop, database: Database, make_team): + """A factory fixture for creating a team in database.""" + + async def _make_team_in_db(team: TeamEntity | None = None) -> TeamEntity: + team = team or make_team() + repo = TeamDbRepository(database) + async with UnitOfWork(database): + team = await repo.create(team) + + def cleanup(): + async def acleanup(): + async with UnitOfWork(database): + await repo.delete(team) + + event_loop.run_until_complete(acleanup()) + + request.addfinalizer(cleanup) + + return team + + return _make_team_in_db From 37d18370a7485447b11f062e65928a20d9952faf Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 11:36:19 +0200 Subject: [PATCH 080/410] test: create team --- backend/src/tests/modules/club/conftest.py | 1 + .../modules/club/repositories/test_team_db_repository.py | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 backend/src/tests/modules/club/repositories/test_team_db_repository.py diff --git a/backend/src/tests/modules/club/conftest.py b/backend/src/tests/modules/club/conftest.py index 9004a6ce..ff16a842 100644 --- a/backend/src/tests/modules/club/conftest.py +++ b/backend/src/tests/modules/club/conftest.py @@ -5,3 +5,4 @@ from tests.fixtures.club.persons import * # noqa from tests.fixtures.club.members import * # noqa from tests.fixtures.club.coaches import * # noqa +from tests.fixtures.club.teams import * # noqa diff --git a/backend/src/tests/modules/club/repositories/test_team_db_repository.py b/backend/src/tests/modules/club/repositories/test_team_db_repository.py new file mode 100644 index 00000000..faaf13ea --- /dev/null +++ b/backend/src/tests/modules/club/repositories/test_team_db_repository.py @@ -0,0 +1,7 @@ +"""Module for testing the team db repository.""" + + +async def test_create_team(make_team_in_db): + """Test creating a team in the database.""" + team = await make_team_in_db() + assert team is not None, "There should be a team in the database." From b79f79ee3e8d59e8ffaa1565ae700ed41d363891 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 11:37:39 +0200 Subject: [PATCH 081/410] docs: fix module doc --- backend/src/tests/modules/club/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/tests/modules/club/conftest.py b/backend/src/tests/modules/club/conftest.py index ff16a842..28b3cf52 100644 --- a/backend/src/tests/modules/club/conftest.py +++ b/backend/src/tests/modules/club/conftest.py @@ -1,4 +1,4 @@ -"""Module for defining common fixtures for testing code related to members.""" +"""Module for common fixtures used for testing code of the club module.""" from tests.fixtures.club.countries import * # noqa from tests.fixtures.club.contacts import * # noqa From d5d45e6744f62fe0236f91fe18ecd3c332fcfdec Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 11:41:37 +0200 Subject: [PATCH 082/410] test: use factory fixtures --- .../modules/training/test_create_training.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/backend/src/tests/modules/training/test_create_training.py b/backend/src/tests/modules/training/test_create_training.py index df8710f6..6314a9f2 100644 --- a/backend/src/tests/modules/training/test_create_training.py +++ b/backend/src/tests/modules/training/test_create_training.py @@ -9,7 +9,6 @@ from kwai.modules.training.coaches.coach_db_repository import CoachDbRepository from kwai.modules.training.coaches.coach_repository import CoachRepository from kwai.modules.training.create_training import CreateTraining, CreateTrainingCommand -from kwai.modules.training.teams.team import TeamEntity, TeamIdentifier from kwai.modules.training.teams.team_db_repository import TeamDbRepository from kwai.modules.training.teams.team_repository import TeamRepository from kwai.modules.training.training_command import Coach @@ -22,8 +21,6 @@ ) from kwai.modules.training.trainings.training_repository import TrainingRepository -from tests.modules.training.conftest import Context - @pytest.fixture def training_repo(database: Database) -> TrainingRepository: @@ -56,17 +53,10 @@ async def coach(make_coach_in_db) -> CoachEntity: @pytest.fixture -async def team( - database: Database, context: Context, team_repo: TeamRepository -) -> TeamEntity: - """A fixture for a team repository.""" - teams_iterator = team_repo.get_by_ids(TeamIdentifier(context.get("teams")[0].id)) - return await anext(teams_iterator) - - -@pytest.fixture -async def command(coach: CoachEntity, team: TeamEntity) -> CreateTrainingCommand: +async def command(make_coach_in_db, make_team_in_db) -> CreateTrainingCommand: """A fixture for a training entity.""" + coach = await make_coach_in_db() + team = await make_team_in_db() start_date = Timestamp.create_now() return CreateTrainingCommand( start_date=str(start_date), From caae3ea1e5e89ead3ed699089c260c74255b2f7a Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 11:51:12 +0200 Subject: [PATCH 083/410] fix: add await to get_by_id for team --- backend/src/kwai/modules/training/create_training_definition.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/kwai/modules/training/create_training_definition.py b/backend/src/kwai/modules/training/create_training_definition.py index 01e151fd..6511014f 100644 --- a/backend/src/kwai/modules/training/create_training_definition.py +++ b/backend/src/kwai/modules/training/create_training_definition.py @@ -43,7 +43,7 @@ async def execute( command: The input for this use case. """ if command.team_id is not None: - team = self._team_repo.get_by_id(TeamIdentifier(command.team_id)) + team = await self._team_repo.get_by_id(TeamIdentifier(command.team_id)) else: team = None From 4f65cf91ef5e704afe41b90f4d62c23e0d904232 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 15:15:19 +0200 Subject: [PATCH 084/410] test: use make_coach_in_db --- .../src/tests/modules/training/test_get_coaches.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/backend/src/tests/modules/training/test_get_coaches.py b/backend/src/tests/modules/training/test_get_coaches.py index 313c6f89..4bf47a50 100644 --- a/backend/src/tests/modules/training/test_get_coaches.py +++ b/backend/src/tests/modules/training/test_get_coaches.py @@ -5,9 +5,14 @@ from kwai.modules.training.get_coaches import GetCoaches, GetCoachesCommand -async def test_get_coaches(database: Database): +async def test_get_coaches(database: Database, make_coach_in_db): """Test the get coaches use case.""" - coach_repo = CoachDbRepository(database) + coach = await make_coach_in_db() + command = GetCoachesCommand(active=True) + coach_repo = CoachDbRepository(database) count, iterator = await GetCoaches(coach_repo).execute(command) - assert count is not None, "There should be result" + assert count > 0, "There should be at least one result" + + coaches = {coach.id: coach async for coach in iterator} + assert coach.id in coaches, "The coach should be retrieved" From 178b7aae8c999ef62aafe38f3b56a7d9ba4d276b Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 15:15:36 +0200 Subject: [PATCH 085/410] test: use make_training_in_db --- .../modules/training/test_delete_training.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/backend/src/tests/modules/training/test_delete_training.py b/backend/src/tests/modules/training/test_delete_training.py index e67f9746..dae3b3d1 100644 --- a/backend/src/tests/modules/training/test_delete_training.py +++ b/backend/src/tests/modules/training/test_delete_training.py @@ -3,7 +3,6 @@ import pytest from kwai.core.db.database import Database from kwai.modules.training.delete_training import DeleteTraining, DeleteTrainingCommand -from kwai.modules.training.trainings.training import TrainingEntity from kwai.modules.training.trainings.training_db_repository import TrainingDbRepository from kwai.modules.training.trainings.training_repository import ( TrainingNotFoundException, @@ -17,23 +16,14 @@ def training_repo(database: Database) -> TrainingRepository: return TrainingDbRepository(database) -@pytest.fixture -async def saved_training_entity( - training_repo: TrainingRepository, training_entity: TrainingEntity -): - """A fixture for a training in the repository.""" - return await training_repo.create(training_entity) - - -async def test_delete_training( - training_repo: TrainingRepository, saved_training_entity -): +async def test_delete_training(training_repo: TrainingRepository, make_training_in_db): """Test the use case "Delete Training".""" - command = DeleteTrainingCommand(id=saved_training_entity.id.value) + training = await make_training_in_db() + command = DeleteTrainingCommand(id=training.id.value) try: await DeleteTraining(training_repo).execute(command) except TrainingNotFoundException as ex: pytest.fail(str(ex)) with pytest.raises(TrainingNotFoundException): - await training_repo.get_by_id(saved_training_entity.id) + await training_repo.get_by_id(training.id) From 06723df0e00d0a37536bdb4f4f3c802f8f50d0ae Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 15:17:54 +0200 Subject: [PATCH 086/410] test: use make_team_in_db --- .../modules/training/test_create_training_definition.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/src/tests/modules/training/test_create_training_definition.py b/backend/src/tests/modules/training/test_create_training_definition.py index 843cc41b..cee43c01 100644 --- a/backend/src/tests/modules/training/test_create_training_definition.py +++ b/backend/src/tests/modules/training/test_create_training_definition.py @@ -30,8 +30,9 @@ def team_repo(database: Database) -> TeamRepository: @pytest.fixture -def command(): +async def command(make_team_in_db): """A fixture for a create command.""" + team = await make_team_in_db() return CreateTrainingDefinitionCommand( name="U11 Monday Training", description="Training for U11 on Monday", @@ -42,7 +43,7 @@ def command(): active=True, location="Sports Hall", remark="Test", - team_id=None, + team_id=team.id.value, ) From bfc61532b107f7268b9f1cd8d88dc5ff6f4de1a3 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 15:21:46 +0200 Subject: [PATCH 087/410] test: use make_team_in_db --- backend/src/tests/modules/training/test_get_teams.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/backend/src/tests/modules/training/test_get_teams.py b/backend/src/tests/modules/training/test_get_teams.py index d90d1ce4..daef148b 100644 --- a/backend/src/tests/modules/training/test_get_teams.py +++ b/backend/src/tests/modules/training/test_get_teams.py @@ -1,11 +1,14 @@ """Module for tests of the get teams use case.""" + from kwai.core.db.database import Database from kwai.modules.training.get_teams import GetTeams from kwai.modules.training.teams.team_db_repository import TeamDbRepository -async def test_get_teams(database: Database): +async def test_get_teams(database: Database, make_team_in_db): """Test use case get teams.""" - result = await GetTeams(TeamDbRepository(database)).execute() - assert result is not None - assert result.count > 0, "There should be a team" + team = await make_team_in_db() + count, iterator = await GetTeams(TeamDbRepository(database)).execute() + assert count > 0, "There should be a team" + teams = {team.id: team async for team in iterator} + assert team.id in teams, "The team should be in the result" From d533b8a865fb462df74f897626ad37a121824f74 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 15:23:07 +0200 Subject: [PATCH 088/410] test: use make_training_in_db --- .../src/tests/modules/training/test_get_training.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/backend/src/tests/modules/training/test_get_training.py b/backend/src/tests/modules/training/test_get_training.py index 556dc266..1d251f69 100644 --- a/backend/src/tests/modules/training/test_get_training.py +++ b/backend/src/tests/modules/training/test_get_training.py @@ -5,7 +5,6 @@ from kwai.modules.training.get_training import GetTraining, GetTrainingCommand from kwai.modules.training.trainings.training_db_repository import TrainingDbRepository from kwai.modules.training.trainings.training_repository import ( - TrainingNotFoundException, TrainingRepository, ) @@ -16,11 +15,9 @@ def training_repo(database: Database) -> TrainingRepository: return TrainingDbRepository(database) -async def test_get_training(training_repo: TrainingRepository): +async def test_get_training(training_repo: TrainingRepository, make_training_in_db): """Test the use case "Get Training".""" - command = GetTrainingCommand(id=1) - try: - training = await GetTraining(training_repo).execute(command) - assert training is not None, "There should be a training." - except TrainingNotFoundException: - pass + training = await make_training_in_db() + command = GetTrainingCommand(id=training.id.value) + training = await GetTraining(training_repo).execute(command) + assert training is not None, "There should be a training." From 319bad756f6fbffa9c7048e9c16114117ca62574 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 15:24:43 +0200 Subject: [PATCH 089/410] test: use make_training_definition_in_db --- .../training/test_get_training_definition.py | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/backend/src/tests/modules/training/test_get_training_definition.py b/backend/src/tests/modules/training/test_get_training_definition.py index 26f62bf0..72d59608 100644 --- a/backend/src/tests/modules/training/test_get_training_definition.py +++ b/backend/src/tests/modules/training/test_get_training_definition.py @@ -6,7 +6,6 @@ GetTrainingDefinition, GetTrainingDefinitionCommand, ) -from kwai.modules.training.trainings.training_definition import TrainingDefinitionEntity from kwai.modules.training.trainings.training_definition_db_repository import ( TrainingDefinitionDbRepository, ) @@ -21,21 +20,13 @@ def training_definition_repo(database: Database) -> TrainingDefinitionRepository return TrainingDefinitionDbRepository(database) -@pytest.fixture -async def saved_training_definition( - training_definition_repo: TrainingDefinitionRepository, - training_definition: TrainingDefinitionEntity, -) -> TrainingDefinitionEntity: - """A fixture for a training definition in the database.""" - return await training_definition_repo.create(training_definition) - - async def test_get_training_definition( training_definition_repo: TrainingDefinitionRepository, - saved_training_definition: TrainingDefinitionEntity, + make_training_definition_in_db, ): """Test a successful execution of the use case.""" - command = GetTrainingDefinitionCommand(id=saved_training_definition.id.value) + definition = await make_training_definition_in_db() + command = GetTrainingDefinitionCommand(id=definition.id.value) training_definition = await GetTrainingDefinition(training_definition_repo).execute( command ) From 03ae203ee96a28f608bf51042cdade5506ce5fd1 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 15:35:12 +0200 Subject: [PATCH 090/410] test: use make_training_definition_in_db --- .../training/test_get_training_definitions.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/backend/src/tests/modules/training/test_get_training_definitions.py b/backend/src/tests/modules/training/test_get_training_definitions.py index 7097f16d..0a358181 100644 --- a/backend/src/tests/modules/training/test_get_training_definitions.py +++ b/backend/src/tests/modules/training/test_get_training_definitions.py @@ -1,7 +1,5 @@ """Module for testing the use case "Get Training Definitions".""" -from typing import AsyncIterator - import pytest from kwai.core.db.database import Database from kwai.modules.training.get_training_definitions import ( @@ -10,7 +8,6 @@ ) from kwai.modules.training.trainings.training_definition import ( TrainingDefinitionEntity, - TrainingDefinitionIdentifier, ) from kwai.modules.training.trainings.training_definition_db_repository import ( TrainingDefinitionDbRepository, @@ -20,14 +17,6 @@ ) -async def _find(iterator: AsyncIterator, id_: TrainingDefinitionIdentifier): - """Search for an entity with the given id.""" - async for entity in iterator: - if entity.id == id_: - return entity - return None - - @pytest.fixture(scope="module") def training_definition_repo(database: Database) -> TrainingDefinitionRepository: """A fixture for a training definition repository.""" @@ -45,14 +34,15 @@ async def saved_training_definition( async def test_get_training_definitions( training_definition_repo: TrainingDefinitionRepository, - saved_training_definition: TrainingDefinitionEntity, + make_training_definition_in_db, ): """Test a successful execution of the use case.""" + definition = await make_training_definition_in_db() command = GetTrainingDefinitionsCommand() count, iterator = await GetTrainingDefinitions(training_definition_repo).execute( command ) assert count >= 1, "There should be at least a training definition" - entity = await _find(iterator, saved_training_definition.id) - assert entity is not None, "The definition should be part of the data" + definitions = {definition.id: definition async for definition in iterator} + assert definition.id in definitions, "The definition should be part of the data" From 3589226856b8478d74db9a8640ff2be56e503355 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 19:29:36 +0200 Subject: [PATCH 091/410] test: use make_training_in_db --- .../modules/training/test_get_trainings.py | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/backend/src/tests/modules/training/test_get_trainings.py b/backend/src/tests/modules/training/test_get_trainings.py index cf7574cf..d66d77f7 100644 --- a/backend/src/tests/modules/training/test_get_trainings.py +++ b/backend/src/tests/modules/training/test_get_trainings.py @@ -2,6 +2,8 @@ import pytest from kwai.core.db.database import Database +from kwai.core.domain.value_objects.period import Period +from kwai.core.domain.value_objects.timestamp import Timestamp from kwai.modules.training.coaches.coach_db_repository import CoachDbRepository from kwai.modules.training.coaches.coach_repository import CoachRepository from kwai.modules.training.get_trainings import GetTrainings, GetTrainingsCommand @@ -37,27 +39,36 @@ async def test_get_active_trainings( training_repo: TrainingRepository, coach_repo: CoachRepository, definition_repo: TrainingDefinitionRepository, + make_training_in_db, ): """Test the use case "Get Trainings".""" - command = GetTrainingsCommand(active=True, limit=10) + training = await make_training_in_db() + command = GetTrainingsCommand(active=True) count, iterator = await GetTrainings( training_repo, coach_repo, definition_repo ).execute(command) - entities = {entity.id: entity async for entity in iterator} + assert count > 0, "There should be at least one active training" - assert entities is not None, "There should be a result" + entities = {entity.id: entity async for entity in iterator} + assert training.id in entities, "The training should be returned" async def test_get_year_month_trainings( training_repo: TrainingRepository, coach_repo: CoachRepository, definition_repo: TrainingDefinitionRepository, + make_training_in_db, + make_training, ): """Test the use case "Get Trainings".""" - command = GetTrainingsCommand(limit=10, year=2023, month=1) + start_date = Timestamp.create_from_string("2024-01-01 19:00:00") + training = await make_training_in_db( + make_training(period=Period.create_from_delta(start_date, hours=2)) + ) + command = GetTrainingsCommand(limit=10, year=2024, month=1) count, iterator = await GetTrainings( training_repo, coach_repo, definition_repo ).execute(command) + assert count > 0, "There should be at least one training in 01/2023." entities = {entity.id: entity async for entity in iterator} - - assert entities is not None, "There should be a result" + assert training.id in entities, "The training should be returned in the result." From 6ca524981973ba681035a43e8ff41dadb02cc8b2 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 19:41:10 +0200 Subject: [PATCH 092/410] test: use make_training_in_db --- .../modules/training/test_update_training.py | 73 +++---------------- 1 file changed, 10 insertions(+), 63 deletions(-) diff --git a/backend/src/tests/modules/training/test_update_training.py b/backend/src/tests/modules/training/test_update_training.py index 2674f2bb..1a8e0cc9 100644 --- a/backend/src/tests/modules/training/test_update_training.py +++ b/backend/src/tests/modules/training/test_update_training.py @@ -4,17 +4,12 @@ from kwai.core.db.database import Database from kwai.core.domain.use_case import TextCommand from kwai.core.domain.value_objects.owner import Owner -from kwai.core.domain.value_objects.period import Period -from kwai.core.domain.value_objects.text import DocumentFormat, Locale, LocaleText from kwai.core.domain.value_objects.timestamp import Timestamp -from kwai.modules.training.coaches.coach import CoachEntity, CoachIdentifier from kwai.modules.training.coaches.coach_db_repository import CoachDbRepository from kwai.modules.training.coaches.coach_repository import CoachRepository -from kwai.modules.training.teams.team import TeamEntity, TeamIdentifier from kwai.modules.training.teams.team_db_repository import TeamDbRepository from kwai.modules.training.teams.team_repository import TeamRepository from kwai.modules.training.training_command import Coach -from kwai.modules.training.trainings.training import TrainingEntity from kwai.modules.training.trainings.training_db_repository import TrainingDbRepository from kwai.modules.training.trainings.training_definition_db_repository import ( TrainingDefinitionDbRepository, @@ -23,11 +18,8 @@ TrainingDefinitionRepository, ) from kwai.modules.training.trainings.training_repository import TrainingRepository -from kwai.modules.training.trainings.value_objects import TrainingCoach from kwai.modules.training.update_training import UpdateTraining, UpdateTrainingCommand -from tests.modules.training.conftest import Context - @pytest.fixture def training_repo(database: Database) -> TrainingRepository: @@ -53,71 +45,25 @@ def team_repo(database: Database) -> TeamRepository: return TeamDbRepository(database) -@pytest.fixture -async def coach( - database: Database, context: Context, coach_repo: CoachRepository -) -> CoachEntity: - """A fixture for a coach.""" - return await coach_repo.get_by_id(CoachIdentifier(context.get("coaches")[0].id)) - - -@pytest.fixture -async def team( - database: Database, context: Context, team_repo: TeamRepository -) -> TeamEntity: - """A fixture for a team repository.""" - teams_iterator = team_repo.get_by_ids(TeamIdentifier(context.get("teams")[0].id)) - return await anext(teams_iterator) - - -@pytest.fixture -async def training_entity( - training_repo: TrainingRepository, - coach: CoachEntity, - team: TeamEntity, - owner: Owner, -) -> TrainingEntity: - """A fixture for a training entity.""" - start_date = Timestamp.create_now() - return await training_repo.create( - TrainingEntity( - texts=[ - LocaleText( - locale=Locale.EN, - format=DocumentFormat.MARKDOWN, - title="Test training", - content="This is a test", - summary="This is a test", - author=owner, - ) - ], - coaches=[TrainingCoach(coach=coach, owner=owner)], - teams=[team], - period=Period( - start_date=start_date, end_date=start_date.add_delta(hours=1) - ), - ) - ) - - async def test_update_training( - training_entity: TrainingEntity, training_repo: TrainingRepository, definition_repo: TrainingDefinitionRepository, coach_repo: CoachRepository, team_repo: TeamRepository, + make_training_in_db, owner: Owner, ): """Test the use case "Update Training".""" + training = await make_training_in_db() start_date = Timestamp.create_now().add_delta(hours=1) end_date = start_date.add_delta(hours=1) command = UpdateTrainingCommand( - id=training_entity.id.value, + id=training.id.value, start_date=str(start_date), end_date=str(end_date), - active=training_entity.active, - cancelled=training_entity.cancelled, - location=training_entity.location, + active=training.active, + cancelled=training.cancelled, + location=training.location, texts=[ TextCommand( locale="en", @@ -130,14 +76,14 @@ async def test_update_training( remark="This is a test", coaches=[ Coach( - id=training_coach.coach.id.value, + id=training.coaches[0].coach.id.value, head=training_coach.type == 1, present=training_coach.present, payed=training_coach.payed, ) - for training_coach in training_entity.coaches + for training_coach in training.coaches ], - teams=[team.id.value for team in training_entity.teams], + teams=[team.id.value for team in training.teams], definition=None, ) @@ -146,3 +92,4 @@ async def test_update_training( ).execute(command) assert training is not None, "There should be a training" + assert training.texts[0].title == "Updated Test Training" From 687ebcc4fb02c15348a1e52175801bb2a9189135 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 19:45:24 +0200 Subject: [PATCH 093/410] test: use make_training_definition_in_db --- .../test_update_training_definition.py | 35 +++++-------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/backend/src/tests/modules/training/test_update_training_definition.py b/backend/src/tests/modules/training/test_update_training_definition.py index dfd4d944..9d046a3a 100644 --- a/backend/src/tests/modules/training/test_update_training_definition.py +++ b/backend/src/tests/modules/training/test_update_training_definition.py @@ -3,11 +3,8 @@ import pytest from kwai.core.db.database import Database from kwai.core.domain.value_objects.owner import Owner -from kwai.core.domain.value_objects.time_period import TimePeriod -from kwai.core.domain.value_objects.weekday import Weekday from kwai.modules.training.teams.team_db_repository import TeamDbRepository from kwai.modules.training.teams.team_repository import TeamRepository -from kwai.modules.training.trainings.training_definition import TrainingDefinitionEntity from kwai.modules.training.trainings.training_definition_db_repository import ( TrainingDefinitionDbRepository, ) @@ -32,40 +29,24 @@ def team_repo(database: Database) -> TeamRepository: return TeamDbRepository(database) -@pytest.fixture -async def training_definition_entity( - training_definition_repo: TrainingDefinitionRepository, - owner: Owner, -) -> TrainingDefinitionEntity: - """A fixture for a training definition entity.""" - return await training_definition_repo.create( - TrainingDefinitionEntity( - name="U9 Training", - description="Test Training Definition", - weekday=Weekday.MONDAY, - period=TimePeriod.create_from_string("19:00", "20:00"), - owner=owner, - ) - ) - - async def test_update_training_definition( - training_definition_entity: TrainingDefinitionEntity, training_definition_repo: TrainingDefinitionRepository, team_repo: TeamRepository, + make_training_definition_in_db, owner: Owner, ): """Test the use case "Update Training".""" + definition = await make_training_definition_in_db() command = UpdateTrainingDefinitionCommand( - id=training_definition_entity.id.value, - name=training_definition_entity.name, - description=training_definition_entity.description, - weekday=training_definition_entity.weekday.value, + id=definition.id.value, + name=definition.name, + description=definition.description, + weekday=definition.weekday.value, start_time="20:00", end_time="21:00", timezone="Europe/Brussels", - active=training_definition_entity.active, - location=training_definition_entity.location, + active=definition.active, + location=definition.location, remark="This is an update test", team_id=None, ) From c43eea3e8809d7ea1deea59a5971dc157e6b74a5 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 3 Jun 2024 20:10:59 +0200 Subject: [PATCH 094/410] test: use factory fixtures --- .../src/tests/modules/training/conftest.py | 124 +----------------- 1 file changed, 3 insertions(+), 121 deletions(-) diff --git a/backend/src/tests/modules/training/conftest.py b/backend/src/tests/modules/training/conftest.py index ba9dca76..6e45b30f 100644 --- a/backend/src/tests/modules/training/conftest.py +++ b/backend/src/tests/modules/training/conftest.py @@ -1,128 +1,10 @@ """Module with fixtures for the training bounded context.""" -import dataclasses -from collections import defaultdict -from datetime import datetime, time -from typing import Any - -import pytest -from kwai.core.db.database import Database -from kwai.core.domain.value_objects.owner import Owner -from kwai.core.domain.value_objects.period import Period -from kwai.core.domain.value_objects.text import DocumentFormat, Locale, LocaleText -from kwai.core.domain.value_objects.time_period import TimePeriod -from kwai.core.domain.value_objects.timestamp import Timestamp -from kwai.core.domain.value_objects.weekday import Weekday -from kwai.modules.training.coaches._tables import ( - CoachRow, - PersonRow, -) -from kwai.modules.training.teams.team_tables import TeamRow, TeamsTable -from kwai.modules.training.trainings.training import TrainingEntity -from kwai.modules.training.trainings.training_definition import TrainingDefinitionEntity - from tests.fixtures.club.coaches import * # noqa from tests.fixtures.club.contacts import * # noqa from tests.fixtures.club.countries import * # noqa from tests.fixtures.club.members import * # noqa from tests.fixtures.club.persons import * # noqa - -Context = dict[str, list[Any]] - - -@pytest.fixture(scope="module") -def context() -> Context: - """A fixture for creating a context. - - This context is a dictionary for collecting data. - """ - return defaultdict(list) - - -@pytest.fixture(scope="module") -def person_row() -> PersonRow: - """Fixture for creating a person row.""" - return PersonRow(id=0, firstname="Jigoro", lastname="Kano") - - -@pytest.fixture(scope="module", autouse=True) -async def seed_persons(database: Database, person_row: PersonRow, context: Context): - """Seed the database with persons.""" - # For now, we create the query, in the future a repository from the members - # bounded context can be used. - query = database.create_query_factory().insert(PersonRow.__table_name__) - person_dict = dataclasses.asdict(person_row) - del person_dict["id"] - person_dict["gender"] = 1 - person_dict["birthdate"] = datetime(year=1860, month=12, day=10) - person_dict["nationality_id"] = 1 - query.columns(*person_dict.keys()).values(*person_dict.values()) - context["persons"].append( - dataclasses.replace(person_row, id=await database.execute(query)) - ) - await database.commit() - - -@pytest.fixture(scope="module") -def coach_row(seed_persons, context: Context) -> CoachRow: - """Fixture for creating a coach row.""" - return CoachRow(id=0, member_id=context["persons"][0].id, active=True) - - -@pytest.fixture(scope="module", autouse=True) -async def seed_coaches(database: Database, coach_row: CoachRow, context: Context): - """Seed the database with coaches.""" - query = database.create_query_factory().insert(CoachRow.__table_name__) - coach_dict = dataclasses.asdict(coach_row) - del coach_dict["id"] - query.columns(*coach_dict.keys()).values(*coach_dict.values()) - context["coaches"].append( - dataclasses.replace(coach_row, id=await database.execute(query)) - ) - await database.commit() - - -@pytest.fixture(scope="module", autouse=True) -async def seed_teams(database: Database, context: Context): - """Seed the database with teams.""" - query = database.create_query_factory().insert(TeamsTable.table_name) - team_row = TeamRow(id=0, name="U18") - team_dict = dataclasses.asdict(team_row) - del team_dict["id"] - query.columns(*team_dict.keys()).values(*team_dict.values()) - context["teams"].append( - dataclasses.replace(team_row, id=await database.execute(query)) - ) - await database.commit() - - -@pytest.fixture -async def training_entity(owner: Owner) -> TrainingEntity: - """A fixture for a training entity.""" - start_date = Timestamp.create_now() - training = TrainingEntity( - texts=[ - LocaleText( - locale=Locale.NL, - format=DocumentFormat.MARKDOWN, - title="Test Training", - content="This is a test training", - summary="This is a test training", - author=owner, - ) - ], - period=Period(start_date=start_date, end_date=start_date.add_delta(hours=1)), - ) - return training - - -@pytest.fixture -async def training_definition(owner: Owner) -> TrainingDefinitionEntity: - """A fixture for a training definition entity.""" - return TrainingDefinitionEntity( - name="U11 Training Monday", - description="Training for U11 on each monday", - weekday=Weekday.MONDAY, - owner=owner, - period=TimePeriod(start=time(hour=20), end=time(hour=21)), - ) +from tests.fixtures.club.teams import * # noqa +from tests.fixtures.training.training_definitions import * # noqa +from tests.fixtures.training.trainings import * # noqa From 42506eaa279c0aee5315190fb3e634c82a30570e Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 5 Jun 2024 20:39:55 +0200 Subject: [PATCH 095/410] test: add db mark --- .../modules/club/repositories/test_team_db_repository.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/src/tests/modules/club/repositories/test_team_db_repository.py b/backend/src/tests/modules/club/repositories/test_team_db_repository.py index faaf13ea..54658177 100644 --- a/backend/src/tests/modules/club/repositories/test_team_db_repository.py +++ b/backend/src/tests/modules/club/repositories/test_team_db_repository.py @@ -1,5 +1,9 @@ """Module for testing the team db repository.""" +import pytest + +pytestmark = pytest.mark.db + async def test_create_team(make_team_in_db): """Test creating a team in the database.""" From 24e82eba81f9e7442e5a9b4829379a4753b4936e Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 5 Jun 2024 21:53:50 +0200 Subject: [PATCH 096/410] feat: add team_member (WIP) --- .../kwai/modules/club/domain/team_member.py | 68 +++++++++++++ .../repositories/team_member_db_repository.py | 95 +++++++++++++++++++ .../repositories/team_member_repository.py | 55 +++++++++++ .../repositories/test_team_member_db_query.py | 5 + .../test_team_member_db_repository.py | 16 ++++ 5 files changed, 239 insertions(+) create mode 100644 backend/src/kwai/modules/club/domain/team_member.py create mode 100644 backend/src/kwai/modules/club/repositories/team_member_db_repository.py create mode 100644 backend/src/kwai/modules/club/repositories/team_member_repository.py create mode 100644 backend/src/tests/modules/club/repositories/test_team_member_db_query.py create mode 100644 backend/src/tests/modules/club/repositories/test_team_member_db_repository.py diff --git a/backend/src/kwai/modules/club/domain/team_member.py b/backend/src/kwai/modules/club/domain/team_member.py new file mode 100644 index 00000000..2674be20 --- /dev/null +++ b/backend/src/kwai/modules/club/domain/team_member.py @@ -0,0 +1,68 @@ +"""Module for defining the team member entity.""" + +from kwai.core.domain.entity import Entity +from kwai.core.domain.value_objects.date import Date +from kwai.core.domain.value_objects.identifier import IntIdentifier +from kwai.core.domain.value_objects.name import Name +from kwai.core.domain.value_objects.unique_id import UniqueId +from kwai.modules.club.domain.country import CountryEntity +from kwai.modules.club.domain.value_objects import Gender, License + +TeamMemberIdentifier = IntIdentifier + + +class TeamMemberEntity(Entity[TeamMemberIdentifier]): + """A team member entity. + + A team member entity is an entity which holds specific information of a member + that can be used for a member of a team. + """ + + def __init__( + self, + *, + id_: TeamMemberIdentifier, + uuid: UniqueId, + name: Name, + license: License, + birthdate: Date, + nationality: CountryEntity, + gender: Gender, + ): + super().__init__(id_) + self._name = name + self._uuid = uuid + self._license = license + self._birthdate = birthdate + self._nationality = nationality + self._gender = gender + + @property + def name(self) -> Name: + """Return the name.""" + return self._name + + @property + def uuid(self) -> UniqueId: + """Return the uuid.""" + return self._uuid + + @property + def license(self) -> License: + """Return the license.""" + return self._license + + @property + def birthdate(self) -> Date: + """Return the birthdate.""" + return self._birthdate + + @property + def nationality(self) -> CountryEntity: + """Return the nat.""" + return self._nationality + + @property + def gender(self) -> Gender: + """Return the gender.""" + return self._gender diff --git a/backend/src/kwai/modules/club/repositories/team_member_db_repository.py b/backend/src/kwai/modules/club/repositories/team_member_db_repository.py new file mode 100644 index 00000000..ee7c0fa6 --- /dev/null +++ b/backend/src/kwai/modules/club/repositories/team_member_db_repository.py @@ -0,0 +1,95 @@ +"""Module for defining a team member repository for a database.""" + +from dataclasses import dataclass +from typing import AsyncGenerator + +from sql_smith.functions import on + +from kwai.core.db.database import Database +from kwai.core.db.database_query import DatabaseQuery +from kwai.core.db.table_row import JoinedTableRow +from kwai.core.domain.value_objects.date import Date +from kwai.core.domain.value_objects.name import Name +from kwai.core.domain.value_objects.unique_id import UniqueId +from kwai.modules.club.domain.team_member import TeamMemberEntity, TeamMemberIdentifier +from kwai.modules.club.domain.value_objects import Gender, License +from kwai.modules.club.repositories._tables import ( + CountryRow, + TeamMemberPersonRow, + TeamMemberRow, +) +from kwai.modules.club.repositories.team_member_repository import ( + TeamMemberQuery, + TeamMemberRepository, +) + + +@dataclass(kw_only=True, frozen=True, slots=True) +class TeamMemberQueryRow(JoinedTableRow): + """A data transfer object for the team member query.""" + + member: TeamMemberRow + person: TeamMemberPersonRow + country: CountryRow + + def create_entity(self) -> TeamMemberEntity: + """Create a team member entity from a row.""" + return TeamMemberEntity( + id_=TeamMemberIdentifier(self.member.id), + uuid=UniqueId.create_from_string(self.member.uuid), + name=Name(first_name=self.person.firstname, last_name=self.person.lastname), + license=License( + number=self.member.license, + end_date=Date.create_from_date(self.member.license_end_date), + ), + birthdate=Date.create_from_date(self.person.birthdate), + gender=Gender(self.person.gender), + nationality=self.country.create_country(), + ) + + +class TeamMemberDbQuery(TeamMemberQuery, DatabaseQuery): + """A team member query for a database.""" + + def __init__(self, database: Database): + super().__init__(database) + + def init(self): + self._query.from_(TeamMemberRow.__table_name__).inner_join( + TeamMemberPersonRow.__table_name__, + on(TeamMemberPersonRow.column("id"), TeamMemberRow.column("person_id")), + ).inner_join( + CountryRow.__table_name__, + on(CountryRow.column("id"), TeamMemberPersonRow.column("nationality_id")), + ) + + @property + def columns(self): + return TeamMemberQueryRow.get_aliases() + + def count_column(self): + return TeamMemberRow.column("id") + + +class TeamMemberDbRepository(TeamMemberRepository): + """A team member repository for a database.""" + + def __init__(self, database: Database): + self._database = database + + def create_query(self) -> TeamMemberQuery: + return TeamMemberDbQuery(self._database) + + async def get(self, query: TeamMemberQuery | None = None) -> TeamMemberEntity: + pass + + async def get_all( + self, + query: TeamMemberQuery | None = None, + limit: int | None = None, + offset: int | None = None, + ) -> AsyncGenerator[TeamMemberEntity, None]: + query = query or self.create_query() + + async for row in query.fetch(limit, offset): + yield TeamMemberQueryRow.map(row).create_entity() diff --git a/backend/src/kwai/modules/club/repositories/team_member_repository.py b/backend/src/kwai/modules/club/repositories/team_member_repository.py new file mode 100644 index 00000000..2b3c4af4 --- /dev/null +++ b/backend/src/kwai/modules/club/repositories/team_member_repository.py @@ -0,0 +1,55 @@ +"""Module for defining the team member repository interface.""" + +from abc import ABC, abstractmethod +from typing import AsyncGenerator + +from kwai.core.domain.repository.query import Query +from kwai.modules.club.domain.team_member import TeamMemberEntity + + +class TeamMemberNotFoundException(Exception): + """Raised when a team member does not exist.""" + + +class TeamMemberQuery(Query, ABC): + """An interface for a team member query.""" + + +class TeamMemberRepository(ABC): + """An interface for a team member repository.""" + + @abstractmethod + def create_query(self) -> TeamMemberQuery: + """Create a query for querying team members.""" + raise NotImplementedError + + @abstractmethod + async def get(self, query: TeamMemberQuery | None = None) -> TeamMemberEntity: + """Return the first returned element of the given query. + + Args: + query: The query to use for getting the first member. + + Raises: + TeamMemberNotFoundException: If the team member is not found. + """ + raise NotImplementedError + + @abstractmethod + def get_all( + self, + query: TeamMemberQuery | None = None, + limit: int | None = None, + offset: int | None = None, + ) -> AsyncGenerator[TeamMemberEntity, None]: + """Return all team members of the given query. + + Args: + query: The query to use for getting the members. + limit: The maximum number of members to return. + offset: The offset to use for fetching members. + + Yields: + A team member entity. + """ + raise NotImplementedError diff --git a/backend/src/tests/modules/club/repositories/test_team_member_db_query.py b/backend/src/tests/modules/club/repositories/test_team_member_db_query.py new file mode 100644 index 00000000..2a05323d --- /dev/null +++ b/backend/src/tests/modules/club/repositories/test_team_member_db_query.py @@ -0,0 +1,5 @@ +"""Module for testing the team member query for a database.""" + +import pytest + +pytestmark = pytest.mark.db diff --git a/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py b/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py new file mode 100644 index 00000000..1e4e34ab --- /dev/null +++ b/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py @@ -0,0 +1,16 @@ +"""Module for testing the team member repository for a database.""" + +import pytest +from kwai.core.db.database import Database +from kwai.modules.club.repositories.team_member_db_repository import ( + TeamMemberDbRepository, +) + +pytestmark = pytest.mark.db + + +async def test_get_all(database: Database): + """Test getting all team members.""" + repo = TeamMemberDbRepository(database) + team_members = {team_member.id: team_member async for team_member in repo.get_all()} + assert team_members is not None From fb850e497c0ea53cbee8b15275ca21f0c2063939 Mon Sep 17 00:00:00 2001 From: zumuta Date: Thu, 6 Jun 2024 21:53:27 +0200 Subject: [PATCH 097/410] feat: add more filter methods --- .../kwai/modules/club/repositories/_tables.py | 27 +++++++++++++ .../repositories/team_member_db_repository.py | 24 +++++++++++- .../repositories/team_member_repository.py | 15 +++++++- .../repositories/test_team_member_db_query.py | 38 +++++++++++++++++++ .../test_team_member_db_repository.py | 7 ++++ 5 files changed, 107 insertions(+), 4 deletions(-) diff --git a/backend/src/kwai/modules/club/repositories/_tables.py b/backend/src/kwai/modules/club/repositories/_tables.py index 76d3a3de..60832cee 100644 --- a/backend/src/kwai/modules/club/repositories/_tables.py +++ b/backend/src/kwai/modules/club/repositories/_tables.py @@ -356,3 +356,30 @@ def persist(cls, team: TeamEntity) -> Self: created_at=team.traceable_time.created_at.timestamp, # type: ignore[arg-type] updated_at=team.traceable_time.updated_at.timestamp, ) + + +@dataclass(kw_only=True, frozen=True, slots=True) +class TeamMemberRow(TableRow): + """Represents a row of the members table used for a team member.""" + + __table_name__ = "judo_members" + + id: int + uuid: str + license: str + license_end_date: date + person_id: int + + +@dataclass(kw_only=True, frozen=True, slots=True) +class TeamMemberPersonRow(TableRow): + """Represents a row of the persons table used for a team member.""" + + __table_name__ = "persons" + + id: int + firstname: str + lastname: str + gender: int + birthdate: date + nationality_id: int diff --git a/backend/src/kwai/modules/club/repositories/team_member_db_repository.py b/backend/src/kwai/modules/club/repositories/team_member_db_repository.py index ee7c0fa6..a1487eac 100644 --- a/backend/src/kwai/modules/club/repositories/team_member_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/team_member_db_repository.py @@ -1,7 +1,7 @@ """Module for defining a team member repository for a database.""" from dataclasses import dataclass -from typing import AsyncGenerator +from typing import AsyncGenerator, Self from sql_smith.functions import on @@ -19,6 +19,7 @@ TeamMemberRow, ) from kwai.modules.club.repositories.team_member_repository import ( + TeamMemberNotFoundException, TeamMemberQuery, TeamMemberRepository, ) @@ -70,6 +71,21 @@ def columns(self): def count_column(self): return TeamMemberRow.column("id") + def find_by_id(self, id_: TeamMemberIdentifier) -> Self: + self._query.and_where(TeamMemberRow.field("id").eq(id_.value)) + return self + + def find_by_birthdate(self, start_date: Date, end_date: Date | None = None) -> Self: + if end_date is None: + self._query.and_where( + TeamMemberPersonRow.field("birthdate").gte(start_date) + ) + else: + self._query.and_where( + TeamMemberPersonRow.field("birthdate").between(start_date, end_date) + ) + return self + class TeamMemberDbRepository(TeamMemberRepository): """A team member repository for a database.""" @@ -81,7 +97,11 @@ def create_query(self) -> TeamMemberQuery: return TeamMemberDbQuery(self._database) async def get(self, query: TeamMemberQuery | None = None) -> TeamMemberEntity: - pass + team_member_iterator = self.get_all(query) + try: + return await anext(team_member_iterator) + except StopAsyncIteration: + raise TeamMemberNotFoundException("Member not found") from None async def get_all( self, diff --git a/backend/src/kwai/modules/club/repositories/team_member_repository.py b/backend/src/kwai/modules/club/repositories/team_member_repository.py index 2b3c4af4..ecc2d8b2 100644 --- a/backend/src/kwai/modules/club/repositories/team_member_repository.py +++ b/backend/src/kwai/modules/club/repositories/team_member_repository.py @@ -1,10 +1,11 @@ """Module for defining the team member repository interface.""" from abc import ABC, abstractmethod -from typing import AsyncGenerator +from typing import AsyncGenerator, Self from kwai.core.domain.repository.query import Query -from kwai.modules.club.domain.team_member import TeamMemberEntity +from kwai.core.domain.value_objects.date import Date +from kwai.modules.club.domain.team_member import TeamMemberEntity, TeamMemberIdentifier class TeamMemberNotFoundException(Exception): @@ -14,6 +15,16 @@ class TeamMemberNotFoundException(Exception): class TeamMemberQuery(Query, ABC): """An interface for a team member query.""" + @abstractmethod + def find_by_id(self, id_: TeamMemberIdentifier) -> Self: + """Find a team member by its id.""" + raise NotImplementedError + + @abstractmethod + def find_by_birthdate(self, start_date: Date, end_date: Date | None = None) -> Self: + """Find team members by their birthdate.""" + raise NotImplementedError + class TeamMemberRepository(ABC): """An interface for a team member repository.""" diff --git a/backend/src/tests/modules/club/repositories/test_team_member_db_query.py b/backend/src/tests/modules/club/repositories/test_team_member_db_query.py index 2a05323d..9a9cee29 100644 --- a/backend/src/tests/modules/club/repositories/test_team_member_db_query.py +++ b/backend/src/tests/modules/club/repositories/test_team_member_db_query.py @@ -1,5 +1,43 @@ """Module for testing the team member query for a database.""" import pytest +from kwai.core.db.database import Database +from kwai.core.domain.value_objects.date import Date +from kwai.modules.club.domain.team_member import TeamMemberIdentifier +from kwai.modules.club.repositories.team_member_db_repository import TeamMemberDbQuery +from kwai.modules.club.repositories.team_member_repository import TeamMemberQuery pytestmark = pytest.mark.db + + +@pytest.fixture +def query(database: Database) -> TeamMemberQuery: + """A fixture for a team member query.""" + return TeamMemberDbQuery(database) + + +async def test_filter_by_id(query: TeamMemberQuery): + """Test filtering by id.""" + query.find_by_id(TeamMemberIdentifier(1)) + try: + await query.fetch_one() + except Exception as exc: + pytest.fail(f"An exception occurred: {exc}") + + +async def test_filter_by_birthdate_without_end_date(query: TeamMemberQuery): + """Test filtering by birthdate.""" + query.find_by_birthdate(Date.create(2015, 1, 1)) + try: + await query.fetch_one() + except Exception as exc: + pytest.fail(f"An exception occurred: {exc}") + + +async def test_filter_by_birthdate(query: TeamMemberQuery): + """Test filtering by birthdate between two dates.""" + query.find_by_birthdate(Date.create(2015, 1, 1), Date.create(2015, 1, 31)) + try: + await query.fetch_one() + except Exception as exc: + pytest.fail(f"An exception occurred: {exc}") diff --git a/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py b/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py index 1e4e34ab..0f9fdd2d 100644 --- a/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py +++ b/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py @@ -14,3 +14,10 @@ async def test_get_all(database: Database): repo = TeamMemberDbRepository(database) team_members = {team_member.id: team_member async for team_member in repo.get_all()} assert team_members is not None + + +async def test_get(database: Database): + """Test get team member.""" + repo = TeamMemberDbRepository(database) + team_member = await repo.get() + assert team_member is not None From 78e8da2823cf9711f5e9ce63756f12fc6aa766f8 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 8 Jun 2024 19:50:55 +0200 Subject: [PATCH 098/410] test: remove some types --- backend/src/tests/fixtures/club/contacts.py | 45 ++------------------- 1 file changed, 4 insertions(+), 41 deletions(-) diff --git a/backend/src/tests/fixtures/club/contacts.py b/backend/src/tests/fixtures/club/contacts.py index 8d4fb91d..2aac6c6f 100644 --- a/backend/src/tests/fixtures/club/contacts.py +++ b/backend/src/tests/fixtures/club/contacts.py @@ -1,14 +1,5 @@ """Module for defining fixtures for contacts.""" -from typing import ( - Awaitable, - Callable, - NotRequired, - TypeAlias, - TypedDict, - Unpack, -) - import pytest from kwai.core.db.database import Database from kwai.core.db.uow import UnitOfWork @@ -19,21 +10,8 @@ from kwai.modules.club.repositories.contact_db_repository import ContactDbRepository -class AddressType(TypedDict): - """Keyword arguments for the Address fixture factory method.""" - - address: NotRequired[str] - postal_code: NotRequired[str] - city: NotRequired[str] - county: NotRequired[str] - country: NotRequired[CountryEntity] - - -AddressFixtureFactory: TypeAlias = Callable[[Unpack[AddressType]], Address] - - @pytest.fixture -def make_address(country_japan) -> AddressFixtureFactory: +def make_address(country_japan): """A factory fixture for an address.""" def _make_address( @@ -55,18 +33,8 @@ def _make_address( return _make_address -class ContactType(TypedDict): - """Keyword arguments for the Contact fixture factory method.""" - - emails: NotRequired[list[EmailAddress]] - address: NotRequired[Address] - - -ContactFixtureFactory: TypeAlias = Callable[[Unpack[ContactType]], ContactEntity] - - @pytest.fixture -def make_emails() -> Callable[[str | None], list[EmailAddress]]: +def make_emails(): """A factory fixture for a contact email.""" def _make_emails(email: str | None = None) -> list[EmailAddress]: @@ -78,7 +46,7 @@ def _make_emails(email: str | None = None) -> list[EmailAddress]: @pytest.fixture -def make_contact(make_emails, make_address) -> ContactFixtureFactory: +def make_contact(make_emails, make_address): """A factory fixture for a contact.""" def _make_contact( @@ -92,11 +60,6 @@ def _make_contact( return _make_contact -ContactDbFixtureFactory: TypeAlias = Callable[ - [ContactEntity | None], Awaitable[ContactEntity] -] - - @pytest.fixture def make_contact_in_db( request, @@ -105,7 +68,7 @@ def make_contact_in_db( make_contact, make_address, make_country_in_db, -) -> ContactDbFixtureFactory: +): """A fixture for a contact in the database.""" async def _make_contact_in_db( From 21ccfb8fcce8d522e7c7cca595cb4f619d955e04 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 8 Jun 2024 19:51:35 +0200 Subject: [PATCH 099/410] test: add get, get_by_id, get_by_birthdate --- .../test_team_member_db_repository.py | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py b/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py index 0f9fdd2d..81786db5 100644 --- a/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py +++ b/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py @@ -2,6 +2,8 @@ import pytest from kwai.core.db.database import Database +from kwai.core.domain.value_objects.date import Date +from kwai.modules.club.domain.value_objects import Birthdate from kwai.modules.club.repositories.team_member_db_repository import ( TeamMemberDbRepository, ) @@ -9,15 +11,39 @@ pytestmark = pytest.mark.db -async def test_get_all(database: Database): +async def test_get_all(database: Database, make_member_in_db): """Test getting all team members.""" + member = await make_member_in_db() repo = TeamMemberDbRepository(database) team_members = {team_member.id: team_member async for team_member in repo.get_all()} assert team_members is not None + assert member.id in team_members, "The team member should be returned." -async def test_get(database: Database): - """Test get team member.""" +async def test_get_by_id(database: Database, make_member_in_db): + """Test get team member by its ids.""" + member = await make_member_in_db() repo = TeamMemberDbRepository(database) - team_member = await repo.get() + query = repo.create_query() + query.find_by_id(member.id) + team_member = await repo.get(query) + assert team_member is not None + + +async def test_get_by_birthdate( + database: Database, + make_member_in_db, + make_person_in_db, + make_person, + make_contact_in_db, +): + """Test get a member by its birthdate.""" + birthdate = Birthdate(Date.create(year=2000, month=12, day=31)) + await make_person_in_db( + make_person(birthdate=birthdate, contact=await make_contact_in_db()) + ) + repo = TeamMemberDbRepository(database) + query = repo.create_query() + query.find_by_birthdate(birthdate.date) + team_member = await repo.get(query) assert team_member is not None From d596cf08e8c3dc517ad2642c8f2d3a74956ef9ff Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 10 Jun 2024 15:32:35 +0200 Subject: [PATCH 100/410] refactor: remove some types --- backend/src/tests/fixtures/club/countries.py | 30 ++------------------ 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/backend/src/tests/fixtures/club/countries.py b/backend/src/tests/fixtures/club/countries.py index ce6e1c13..5e795b55 100644 --- a/backend/src/tests/fixtures/club/countries.py +++ b/backend/src/tests/fixtures/club/countries.py @@ -1,13 +1,5 @@ """Module for fixtures related to countries.""" -from typing import ( - AsyncGenerator, - Callable, - NotRequired, - TypedDict, - Unpack, -) - import pytest from kwai.core.db.database import Database from kwai.core.db.uow import UnitOfWork @@ -16,19 +8,8 @@ from kwai.modules.club.repositories.country_repository import CountryNotFoundException -class CountryType(TypedDict): - """Keyword arguments for the Country fixture factory method.""" - - iso_2: NotRequired[str] - iso_3: NotRequired[str] - name: NotRequired[str] - - -type CountryFixtureFactory = Callable[[Unpack[CountryType]], CountryEntity] - - @pytest.fixture -def make_country() -> CountryFixtureFactory: +def make_country(): """A factory fixture for a country.""" def _make_country(iso_2="XX", iso_3="XXX", name="Test Country"): @@ -38,18 +19,13 @@ def _make_country(iso_2="XX", iso_3="XXX", name="Test Country"): @pytest.fixture -def country_japan() -> CountryEntity: +def country_japan(): """A factory fixture for the country Japan.""" return CountryEntity(iso_2="JP", iso_3="JPN", name="Japan") -type CountryDbFixtureFactory = Callable[[], AsyncGenerator[CountryEntity, None]] - - @pytest.fixture -async def make_country_in_db( - request, event_loop, database: Database, make_country: CountryFixtureFactory -) -> CountryDbFixtureFactory: +async def make_country_in_db(request, event_loop, database: Database, make_country): """A fixture for a country in the database. When the country is already in the database, it will be returned. From 51764ceb307e03c5fd259968f912d15eeaebb6f8 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 10 Jun 2024 15:32:52 +0200 Subject: [PATCH 101/410] fix: use make_person --- backend/src/tests/fixtures/club/members.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/backend/src/tests/fixtures/club/members.py b/backend/src/tests/fixtures/club/members.py index 56b07fb4..42bd703a 100644 --- a/backend/src/tests/fixtures/club/members.py +++ b/backend/src/tests/fixtures/club/members.py @@ -1,7 +1,5 @@ """Module for defining fixtures of members.""" -from typing import Callable, TypeAlias - import pytest from kwai.core.db.database import Database from kwai.core.db.uow import UnitOfWork @@ -11,11 +9,9 @@ from kwai.modules.club.domain.value_objects import License from kwai.modules.club.repositories.member_db_repository import MemberDbRepository -MemberFixtureFactory: TypeAlias = Callable[[License | None], MemberEntity] - @pytest.fixture -def make_member(make_person) -> MemberFixtureFactory: +def make_member(make_person): """A factory fixture for a member.""" def _make_member_entity( @@ -40,11 +36,22 @@ def make_member_in_db( database: Database, make_member, make_person_in_db, + make_person, + make_contact_in_db, + make_country_in_db, + country_japan, ): """A fixture for a member in the database.""" async def _make_member_in_db(member: MemberEntity | None = None) -> MemberEntity: - member = member or make_member(person=await make_person_in_db()) + member = member or make_member( + person=await make_person_in_db( + make_person( + contact=await make_contact_in_db(), + nationality=await make_country_in_db(country_japan), + ), + ) + ) repo = MemberDbRepository(database) async with UnitOfWork(database): member = await repo.create(member) From f8016acb7e172d9016b1ab9cba8ea24229444880 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 10 Jun 2024 15:34:21 +0200 Subject: [PATCH 102/410] test: add tests for filters on date --- .../test_team_member_db_repository.py | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py b/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py index 81786db5..126896bd 100644 --- a/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py +++ b/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py @@ -32,18 +32,62 @@ async def test_get_by_id(database: Database, make_member_in_db): async def test_get_by_birthdate( database: Database, + make_member, make_member_in_db, make_person_in_db, make_person, make_contact_in_db, + make_country_in_db, + country_japan, ): """Test get a member by its birthdate.""" birthdate = Birthdate(Date.create(year=2000, month=12, day=31)) - await make_person_in_db( - make_person(birthdate=birthdate, contact=await make_contact_in_db()) + await make_member_in_db( + make_member( + person=await make_person_in_db( + make_person( + birthdate=birthdate, + contact=await make_contact_in_db(), + nationality=await make_country_in_db(country_japan), + ) + ) + ) ) + repo = TeamMemberDbRepository(database) query = repo.create_query() query.find_by_birthdate(birthdate.date) team_member = await repo.get(query) assert team_member is not None + + +async def test_get_by_birthdate_between_dates( + database: Database, + make_member, + make_member_in_db, + make_person_in_db, + make_person, + make_contact_in_db, + make_country_in_db, + country_japan, +): + """Test get a member by its birthdate between two dates.""" + birthdate = Birthdate(Date.create(year=1990, month=1, day=1)) + await make_member_in_db( + make_member( + person=await make_person_in_db( + make_person( + birthdate=birthdate, + contact=await make_contact_in_db(), + nationality=await make_country_in_db(country_japan), + ) + ) + ) + ) + repo = TeamMemberDbRepository(database) + query = repo.create_query() + start_date = Date.create(year=1990, month=1, day=1) + end_date = Date.create(year=1990, month=12, day=31) + query.find_by_birthdate(start_date, end_date) + team_member = await repo.get(query) + assert team_member is not None From aa47729be59bf93bd63c1ec664724a49088c7345 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 10 Jun 2024 16:49:34 +0200 Subject: [PATCH 103/410] fix: birthdate must be a Birthdate value object --- backend/src/kwai/modules/club/domain/team_member.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/backend/src/kwai/modules/club/domain/team_member.py b/backend/src/kwai/modules/club/domain/team_member.py index 2674be20..5cd327d3 100644 --- a/backend/src/kwai/modules/club/domain/team_member.py +++ b/backend/src/kwai/modules/club/domain/team_member.py @@ -1,12 +1,11 @@ """Module for defining the team member entity.""" from kwai.core.domain.entity import Entity -from kwai.core.domain.value_objects.date import Date from kwai.core.domain.value_objects.identifier import IntIdentifier from kwai.core.domain.value_objects.name import Name from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.club.domain.country import CountryEntity -from kwai.modules.club.domain.value_objects import Gender, License +from kwai.modules.club.domain.value_objects import Birthdate, Gender, License TeamMemberIdentifier = IntIdentifier @@ -25,7 +24,7 @@ def __init__( uuid: UniqueId, name: Name, license: License, - birthdate: Date, + birthdate: Birthdate, nationality: CountryEntity, gender: Gender, ): @@ -53,7 +52,7 @@ def license(self) -> License: return self._license @property - def birthdate(self) -> Date: + def birthdate(self) -> Birthdate: """Return the birthdate.""" return self._birthdate From bafa75ea6cf6cb09f29ba0d71bd81fbbf6c87de9 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 10 Jun 2024 21:52:56 +0200 Subject: [PATCH 104/410] feat: add team and team member resource schema's. --- backend/src/kwai/api/v1/teams/schemas.py | 123 ++++++++++++++++++ .../src/tests/api/v1/teams/test_schemas.py | 120 +++++++++++++++++ 2 files changed, 243 insertions(+) create mode 100644 backend/src/kwai/api/v1/teams/schemas.py create mode 100644 backend/src/tests/api/v1/teams/test_schemas.py diff --git a/backend/src/kwai/api/v1/teams/schemas.py b/backend/src/kwai/api/v1/teams/schemas.py new file mode 100644 index 00000000..8e8223f2 --- /dev/null +++ b/backend/src/kwai/api/v1/teams/schemas.py @@ -0,0 +1,123 @@ +"""Module that defines the schemas for the teams API.""" + +from typing import Annotated, Self + +from pydantic import BaseModel, Field + +from kwai.api.schemas.resources import TeamResourceIdentifier +from kwai.api.v1.club.schemas.country import CountryDocument, CountryResource +from kwai.api.v1.club.schemas.resources import ( + CountryResourceIdentifier, + MemberResourceIdentifier, +) +from kwai.core.json_api import Document, Relationship, ResourceData +from kwai.modules.club.domain.team import TeamEntity +from kwai.modules.club.domain.team_member import TeamMemberEntity + + +class TeamMemberAttributes(BaseModel): + """Attributes for a team member.""" + + first_name: str + last_name: str + license_number: str + license_end_date: str + gender: int + birthdate: str + + +class TeamMemberRelationships(BaseModel): + """Relationships for a team member JSON:API resource.""" + + nationality: Relationship[CountryResourceIdentifier] + + +class TeamMemberResource( + MemberResourceIdentifier, + ResourceData[TeamMemberAttributes, TeamMemberRelationships], +): + """A JSON:API resource for a team member.""" + + +TeamMemberInclude = Annotated[CountryResource, Field(discriminator="type")] + + +class TeamMemberDocument(Document[TeamMemberResource, TeamMemberInclude]): + """A JSON:API document for one or more team members.""" + + @classmethod + def create(cls, team_member: TeamMemberEntity) -> Self: + """Create a team member document.""" + nationality_document = CountryDocument.create(team_member.nationality) + + team_member_resource = TeamMemberResource( + id=str(team_member.uuid), + attributes=TeamMemberAttributes( + first_name=team_member.name.first_name, + last_name=team_member.name.last_name, + license_number=team_member.license.number, + license_end_date=str(team_member.license.end_date), + gender=team_member.gender, + birthdate=str(team_member.birthdate), + ), + ) + team_member_resource.relationships = TeamMemberRelationships( + nationality=Relationship[CountryResourceIdentifier]( + data=CountryResourceIdentifier(id=nationality_document.resource.id), + ) + ) + + return cls(data=team_member_resource, included={nationality_document.resource}) + + +class TeamAttributes(BaseModel): + """Attributes for the team JSON:API resource.""" + + name: str + active: bool + remark: str + + +class TeamRelationships(BaseModel): + """Relationships for a team JSON:API resource.""" + + members: Relationship[MemberResourceIdentifier] + + +class TeamResource( + TeamResourceIdentifier, ResourceData[TeamAttributes, TeamRelationships] +): + """A JSON:API resource for a team.""" + + +TeamInclude = Annotated[ + TeamMemberResource | CountryResource, Field(discriminator="type") +] + + +class TeamDocument(Document[TeamResource, TeamInclude]): + """A JSON:API document for one or more teams.""" + + @classmethod + def create(cls, team: TeamEntity) -> Self: + """Create a team document from a team entity.""" + team_member_document = TeamMemberDocument(data=[], included=set()) + for team_member in team.members: + team_member_document.merge(TeamMemberDocument.create(team_member)) + + team_resource = TeamResource( + id=str(team.id), + attributes=TeamAttributes( + name=team.name, active=team.is_active, remark=team.remark + ), + relationships=TeamRelationships( + members=Relationship[MemberResourceIdentifier]( + data=team_member_document.resources + ) + ), + ) + + included: set[TeamInclude] = set(team_member_document.resources) + included = included.union(team_member_document.included) + + return TeamDocument(data=team_resource, included=included) diff --git a/backend/src/tests/api/v1/teams/test_schemas.py b/backend/src/tests/api/v1/teams/test_schemas.py new file mode 100644 index 00000000..6cb4993e --- /dev/null +++ b/backend/src/tests/api/v1/teams/test_schemas.py @@ -0,0 +1,120 @@ +"""Module for testing teams schemas.""" + +import json +from typing import Any + +import pytest +from deepdiff import DeepDiff +from kwai.api.v1.teams.schemas import TeamDocument, TeamMemberDocument +from kwai.core.domain.value_objects.date import Date +from kwai.core.domain.value_objects.name import Name +from kwai.core.domain.value_objects.unique_id import UniqueId +from kwai.modules.club.domain.team import TeamEntity, TeamIdentifier +from kwai.modules.club.domain.team_member import TeamMemberEntity, TeamMemberIdentifier +from kwai.modules.club.domain.value_objects import Birthdate, Gender, License + +from tests.fixtures.club.countries import * # noqa + + +@pytest.fixture +def team_member(country_japan) -> TeamMemberEntity: + """A fixture for a team member.""" + return TeamMemberEntity( + id_=TeamMemberIdentifier(1), + name=Name(first_name="Jigoro", last_name="Kano"), + uuid=UniqueId.generate(), + license=License(number="1234", end_date=Date.today().add(years=1)), + birthdate=Birthdate(Date.create(year=1860, month=10, day=28)), + gender=Gender.MALE, + nationality=country_japan, + ) + + +@pytest.fixture +def expected_team_member_json(team_member: TeamMemberEntity) -> dict[str, Any]: + """A fixture for a JSON:API resource of a team member.""" + return { + "data": { + "id": str(team_member.uuid), + "type": "members", + "attributes": { + "first_name": "Jigoro", + "last_name": "Kano", + "gender": team_member.gender.value, + "birthdate": str(team_member.birthdate), + "license_number": team_member.license.number, + "license_end_date": str(team_member.license.end_date), + }, + "relationships": { + "nationality": { + "data": { + "id": str(team_member.nationality.id), + "type": "countries", + } + } + }, + }, + "included": [ + { + "id": str(team_member.nationality.id), + "type": "countries", + "attributes": {"iso_2": "JP", "iso_3": "JPN", "name": "Japan"}, + } + ], + } + + +def test_create_team_member_document( + team_member: TeamMemberEntity, expected_team_member_json: dict[str, Any] +): + """Test the creation of a JSON:API document for a team member resource.""" + team_member_document = TeamMemberDocument.create(team_member) + json_resource = json.loads(team_member_document.json()) + + diff = DeepDiff(json_resource, expected_team_member_json, ignore_order=True) + assert not diff, f"JSON structure is not expected:{diff}" + + +@pytest.fixture +def team(team_member: TeamMemberEntity) -> TeamEntity: + """A fixture for a team entity.""" + return TeamEntity( + id_=TeamIdentifier(1), + name="U11", + members=[team_member], + ) + + +@pytest.fixture +def expected_team_json(team: TeamEntity, expected_team_member_json) -> dict[str, Any]: + """A fixture for a JSON:API resource of a team.""" + return { + "data": { + "id": "1", + "type": "teams", + "attributes": {"name": "U11", "remark": "", "active": True}, + "relationships": { + "members": { + "data": [ + { + "id": expected_team_member_json["data"]["id"], + "type": expected_team_member_json["data"]["type"], + } + ] + } + }, + }, + "included": [ + expected_team_member_json["data"], + *expected_team_member_json["included"], + ], + } + + +def test_create_team_document(team: TeamEntity, expected_team_json: dict[str, Any]): + """Test the creation of a JSON:API document for a team entity.""" + team_document = TeamDocument.create(team) + json_resource = json.loads(team_document.json()) + + diff = DeepDiff(json_resource, expected_team_json, ignore_order=True) + assert not diff, f"JSON structure is not expected:{diff}" From 4ab99b8e8a197f351a43acdcee1d9582e77858c2 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 10 Jun 2024 21:53:12 +0200 Subject: [PATCH 105/410] feat: add members --- backend/src/kwai/modules/club/domain/team.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/backend/src/kwai/modules/club/domain/team.py b/backend/src/kwai/modules/club/domain/team.py index fc758914..f53ab7aa 100644 --- a/backend/src/kwai/modules/club/domain/team.py +++ b/backend/src/kwai/modules/club/domain/team.py @@ -3,6 +3,7 @@ from kwai.core.domain.entity import Entity from kwai.core.domain.value_objects.identifier import IntIdentifier from kwai.core.domain.value_objects.traceable_time import TraceableTime +from kwai.modules.club.domain.team_member import TeamMemberEntity TeamIdentifier = IntIdentifier @@ -17,12 +18,14 @@ def __init__( name: str, active: bool = True, remark: str = "", + members: list[TeamMemberEntity] = None, traceable_time: TraceableTime | None = None, ): super().__init__(id_ or TeamIdentifier()) self._name = name self._active = active self._remark = remark + self._members = [] if members is None else members.copy() self._traceable_time = traceable_time or TraceableTime() @property @@ -44,3 +47,11 @@ def remark(self) -> str: def traceable_time(self) -> TraceableTime: """Return the traceable_time.""" return self._traceable_time + + @property + def members(self) -> list[TeamMemberEntity]: + """Return the members. + + Note: the returned list is a copy. + """ + return self._members.copy() From f506133fd6cc61c31737819686d525ce29a28629 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 10 Jun 2024 21:53:33 +0200 Subject: [PATCH 106/410] test: add team member factory fixture --- .../src/tests/fixtures/club/team_members.py | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 backend/src/tests/fixtures/club/team_members.py diff --git a/backend/src/tests/fixtures/club/team_members.py b/backend/src/tests/fixtures/club/team_members.py new file mode 100644 index 00000000..31b49f6b --- /dev/null +++ b/backend/src/tests/fixtures/club/team_members.py @@ -0,0 +1,24 @@ +"""Module for defining factory fixtures for team members.""" + +import pytest +from kwai.modules.club.domain.member import MemberEntity +from kwai.modules.club.domain.team_member import TeamMemberEntity + + +@pytest.fixture +def make_team_member(make_member): + """A factory fixture for a team member.""" + + def _make_team_member(member: MemberEntity | None = None) -> TeamMemberEntity: + member = member or make_member() + return TeamMemberEntity( + id_=member.id, + uuid=member.uuid, + name=member.name, + license=member.license, + birthdate=member.person.birthdate, + nationality=member.person.nationality, + gender=member.person.gender, + ) + + return _make_team_member From 00f77a58b670bfe1007b4d38ef03585aea5ac530 Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 11 Jun 2024 20:40:13 +0200 Subject: [PATCH 107/410] fix: use Birthdate --- .../modules/club/repositories/team_member_db_repository.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/kwai/modules/club/repositories/team_member_db_repository.py b/backend/src/kwai/modules/club/repositories/team_member_db_repository.py index a1487eac..3212c4b9 100644 --- a/backend/src/kwai/modules/club/repositories/team_member_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/team_member_db_repository.py @@ -12,7 +12,7 @@ from kwai.core.domain.value_objects.name import Name from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.club.domain.team_member import TeamMemberEntity, TeamMemberIdentifier -from kwai.modules.club.domain.value_objects import Gender, License +from kwai.modules.club.domain.value_objects import Birthdate, Gender, License from kwai.modules.club.repositories._tables import ( CountryRow, TeamMemberPersonRow, @@ -43,7 +43,7 @@ def create_entity(self) -> TeamMemberEntity: number=self.member.license, end_date=Date.create_from_date(self.member.license_end_date), ), - birthdate=Date.create_from_date(self.person.birthdate), + birthdate=Birthdate(Date.create_from_date(self.person.birthdate)), gender=Gender(self.person.gender), nationality=self.country.create_country(), ) From 98c57888949ada1970fe46a544ec8e3913cc2d7c Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 11 Jun 2024 21:25:54 +0200 Subject: [PATCH 108/410] test: teams api --- backend/src/tests/api/v1/teams/__init__.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 backend/src/tests/api/v1/teams/__init__.py diff --git a/backend/src/tests/api/v1/teams/__init__.py b/backend/src/tests/api/v1/teams/__init__.py new file mode 100644 index 00000000..2a4d512c --- /dev/null +++ b/backend/src/tests/api/v1/teams/__init__.py @@ -0,0 +1 @@ +"""Package for testing the teams API.""" From c4e35b1146d60f3eec370d4e149b659da5cff7c7 Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 12 Jun 2024 20:39:45 +0200 Subject: [PATCH 109/410] feat: add teams API --- backend/src/kwai/api/v1/teams/__init__.py | 1 + backend/src/kwai/api/v1/teams/api.py | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 backend/src/kwai/api/v1/teams/__init__.py create mode 100644 backend/src/kwai/api/v1/teams/api.py diff --git a/backend/src/kwai/api/v1/teams/__init__.py b/backend/src/kwai/api/v1/teams/__init__.py new file mode 100644 index 00000000..52f3e4a9 --- /dev/null +++ b/backend/src/kwai/api/v1/teams/__init__.py @@ -0,0 +1 @@ +"""Package for the teams API.""" diff --git a/backend/src/kwai/api/v1/teams/api.py b/backend/src/kwai/api/v1/teams/api.py new file mode 100644 index 00000000..28759eb2 --- /dev/null +++ b/backend/src/kwai/api/v1/teams/api.py @@ -0,0 +1,12 @@ +"""Module that defines the teams API.""" + +from fastapi import APIRouter + +from kwai.api.v1.teams.schemas import TeamDocument + +router = APIRouter(tags=["teams"]) + + +@router.get("/teams") +async def get_teams() -> TeamDocument: + """Get all teams of the club.""" From 94e87f322111ae4379123de8f3bb2ba5fc9ececd Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 12 Jun 2024 20:40:22 +0200 Subject: [PATCH 110/410] chore: team members (WIP) --- backend/src/kwai/modules/club/get_teams.py | 27 ++++++++ .../kwai/modules/club/repositories/_tables.py | 13 ++++ .../club/repositories/team_db_repository.py | 68 ++++++++++++++++++- .../club/repositories/team_repository.py | 54 ++++++++++++++- 4 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 backend/src/kwai/modules/club/get_teams.py diff --git a/backend/src/kwai/modules/club/get_teams.py b/backend/src/kwai/modules/club/get_teams.py new file mode 100644 index 00000000..efbc6f80 --- /dev/null +++ b/backend/src/kwai/modules/club/get_teams.py @@ -0,0 +1,27 @@ +"""Module that implements the use case 'Get Teams'.""" + +from dataclasses import dataclass + +from kwai.core.domain.presenter import Presenter +from kwai.modules.club.domain.team import TeamEntity +from kwai.modules.training.teams.team_repository import TeamRepository + + +@dataclass(kw_only=True, frozen=True, slots=True) +class GetTeamsCommand: + """Input for the use case 'Get Teams'.""" + + offset: int + limit: int + + +class GetTeams: + """Implement the use case 'Get Teams'.""" + + def __init__(self, team_repo: TeamRepository, presenter: Presenter[TeamEntity]): + """Initialize the use case.""" + self._team_repo = team_repo + self._presenter = presenter + + def execute(self, command: GetTeamsCommand) -> None: + """Execute the use case.""" diff --git a/backend/src/kwai/modules/club/repositories/_tables.py b/backend/src/kwai/modules/club/repositories/_tables.py index 60832cee..6c1c08c5 100644 --- a/backend/src/kwai/modules/club/repositories/_tables.py +++ b/backend/src/kwai/modules/club/repositories/_tables.py @@ -383,3 +383,16 @@ class TeamMemberPersonRow(TableRow): gender: int birthdate: date nationality_id: int + + +@dataclass(kw_only=True, frozen=True, slots=True) +class TeamMembersRow(TableRow): + """Represents a row of the team members table.""" + + __table_name__ = "team_members" + + team_id: int + member_id: int + active: int + created_at: datetime + updated_at: datetime | None diff --git a/backend/src/kwai/modules/club/repositories/team_db_repository.py b/backend/src/kwai/modules/club/repositories/team_db_repository.py index 369f37d5..6fbcb523 100644 --- a/backend/src/kwai/modules/club/repositories/team_db_repository.py +++ b/backend/src/kwai/modules/club/repositories/team_db_repository.py @@ -1,15 +1,79 @@ """Module that implements a team repository for a database.""" +from dataclasses import dataclass +from typing import AsyncGenerator, Self + +from sql_smith.functions import on + from kwai.core.db.database import Database +from kwai.core.db.database_query import DatabaseQuery +from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.entity import Entity from kwai.modules.club.domain.team import TeamEntity, TeamIdentifier -from kwai.modules.club.repositories._tables import TeamRow -from kwai.modules.club.repositories.team_repository import TeamRepository +from kwai.modules.club.repositories._tables import ( + CountryRow, + TeamMemberPersonRow, + TeamMemberRow, + TeamMembersRow, + TeamRow, +) +from kwai.modules.club.repositories.team_repository import TeamQuery, TeamRepository + + +@dataclass(kw_only=True, frozen=True, slots=True) +class TeamQueryRow(JoinedTableRow): + """A data transfer object for the team query.""" + + team: TeamRow + team_members: TeamMembersRow + + +class TeamDbQuery(TeamQuery, DatabaseQuery): + """A team query for a database.""" + + def __init__(self, database: Database): + super().__init__(database) + + def init(self): + self._query.from_(TeamRow.__table_name__).inner_join( + TeamMembersRow.__table_name__, + on(TeamMembersRow.column("team_id"), TeamRow.column("id")), + ).inner_join( + TeamMemberRow.__table_name__, + on(TeamMemberRow.column("id"), TeamMembersRow.column("member_id")), + ).inner_join( + TeamMemberPersonRow.__table_name__, + on(TeamMemberPersonRow.column("id"), TeamMemberRow.column("person_id")), + ).inner_join( + CountryRow.__table_name__, + on(CountryRow.column("id"), TeamMemberPersonRow.column("nationality_id")), + ) + + @property + def columns(self): + pass + + def find_by_id(self, id_: TeamIdentifier) -> Self: + pass class TeamDbRepository(TeamRepository): """A team repository for a database.""" + def create_query(self) -> TeamQuery: + pass + + async def get(self, query: TeamQuery | None = None) -> TeamEntity: + pass + + def get_all( + self, + query: TeamQuery | None = None, + limit: int | None = None, + offset: int | None = None, + ) -> AsyncGenerator[TeamEntity, None]: + pass + def __init__(self, database: Database): self._database = database diff --git a/backend/src/kwai/modules/club/repositories/team_repository.py b/backend/src/kwai/modules/club/repositories/team_repository.py index d0f1c10d..ed482416 100644 --- a/backend/src/kwai/modules/club/repositories/team_repository.py +++ b/backend/src/kwai/modules/club/repositories/team_repository.py @@ -1,13 +1,65 @@ """Module that defines an interface for a team repository.""" from abc import ABC, abstractmethod +from typing import AsyncGenerator, Self -from kwai.modules.club.domain.team import TeamEntity +from kwai.core.domain.repository.query import Query +from kwai.modules.club.domain.team import TeamEntity, TeamIdentifier + + +class TeamNotFoundException(Exception): + """Raised when a team cannot be found.""" + + +class TeamQuery(Query, ABC): + """An interface for a team query.""" + + @abstractmethod + def find_by_id(self, id_: TeamIdentifier) -> Self: + """Find a team by its id.""" + raise NotImplementedError class TeamRepository(ABC): """An interface for a team repository.""" + @abstractmethod + def create_query(self) -> TeamQuery: + """Create a team query.""" + raise NotImplementedError + + @abstractmethod + async def get(self, query: TeamQuery | None = None) -> TeamEntity: + """Return the first returned element of the given query. + + Args: + query: The query to use for getting the first team. + + Raises: + TeamNotFoundException: If the team cannot be found. + """ + raise NotImplementedError + + @abstractmethod + def get_all( + self, + query: TeamQuery | None = None, + limit: int | None = None, + offset: int | None = None, + ) -> AsyncGenerator[TeamEntity, None]: + """Return all teams of the given query. + + Args: + query: The query to use for getting the teams. + limit: The maximum number of teams to return. + offset: The offset to use for fetching teams. + + Yields: + A team entity. + + """ + raise NotImplementedError + @abstractmethod async def create(self, team: TeamEntity) -> TeamEntity: """Save a new team.""" From 3ebdf2dcb31b658ad409bf53db062cc82e5a9d5b Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 12 Jun 2024 20:40:49 +0200 Subject: [PATCH 111/410] refactor: formatting --- backend/src/tests/api/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/tests/api/conftest.py b/backend/src/tests/api/conftest.py index 0ff62d7e..ff7a7eb6 100644 --- a/backend/src/tests/api/conftest.py +++ b/backend/src/tests/api/conftest.py @@ -1,7 +1,7 @@ """Module that defines fixtures for the api tests.""" + import pytest from fastapi.testclient import TestClient - from kwai.api.app import create_app from kwai.core.settings import get_settings from kwai.modules.identity.users.user_account import UserAccountEntity From 980e8e74c133fef5cf5882b52aaca5ebd8659547 Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 12 Jun 2024 20:53:47 +0200 Subject: [PATCH 112/410] refactor: introduce teams module --- backend/src/kwai/api/v1/teams/schemas.py | 4 +- .../kwai/modules/club/repositories/_tables.py | 70 ----------------- backend/src/kwai/modules/teams/__init__.py | 1 + .../src/kwai/modules/teams/domain/__init__.py | 1 + .../modules/{club => teams}/domain/team.py | 2 +- .../{club => teams}/domain/team_member.py | 0 .../kwai/modules/{club => teams}/get_teams.py | 2 +- .../modules/teams/repositories/__init__.py | 1 + .../modules/teams/repositories/_tables.py | 75 +++++++++++++++++++ .../repositories/team_db_repository.py | 6 +- .../repositories/team_member_db_repository.py | 7 +- .../repositories/team_member_repository.py | 2 +- .../repositories/team_repository.py | 2 +- .../src/tests/api/v1/teams/test_schemas.py | 4 +- .../src/tests/fixtures/club/team_members.py | 2 +- backend/src/tests/fixtures/club/teams.py | 4 +- backend/src/tests/modules/teams/__init__.py | 1 + .../tests/modules/teams/domain/__init__.py | 1 + .../modules/teams/repositories/__init__.py | 1 + .../repositories/test_team_db_repository.py | 0 .../repositories/test_team_member_db_query.py | 6 +- .../test_team_member_db_repository.py | 2 +- 22 files changed, 103 insertions(+), 91 deletions(-) create mode 100644 backend/src/kwai/modules/teams/__init__.py create mode 100644 backend/src/kwai/modules/teams/domain/__init__.py rename backend/src/kwai/modules/{club => teams}/domain/team.py (95%) rename backend/src/kwai/modules/{club => teams}/domain/team_member.py (100%) rename backend/src/kwai/modules/{club => teams}/get_teams.py (93%) create mode 100644 backend/src/kwai/modules/teams/repositories/__init__.py create mode 100644 backend/src/kwai/modules/teams/repositories/_tables.py rename backend/src/kwai/modules/{club => teams}/repositories/team_db_repository.py (92%) rename backend/src/kwai/modules/{club => teams}/repositories/team_member_db_repository.py (94%) rename backend/src/kwai/modules/{club => teams}/repositories/team_member_repository.py (95%) rename backend/src/kwai/modules/{club => teams}/repositories/team_repository.py (96%) create mode 100644 backend/src/tests/modules/teams/__init__.py create mode 100644 backend/src/tests/modules/teams/domain/__init__.py create mode 100644 backend/src/tests/modules/teams/repositories/__init__.py rename backend/src/tests/modules/{club => teams}/repositories/test_team_db_repository.py (100%) rename backend/src/tests/modules/{club => teams}/repositories/test_team_member_db_query.py (83%) rename backend/src/tests/modules/{club => teams}/repositories/test_team_member_db_repository.py (97%) diff --git a/backend/src/kwai/api/v1/teams/schemas.py b/backend/src/kwai/api/v1/teams/schemas.py index 8e8223f2..e31211c3 100644 --- a/backend/src/kwai/api/v1/teams/schemas.py +++ b/backend/src/kwai/api/v1/teams/schemas.py @@ -11,8 +11,8 @@ MemberResourceIdentifier, ) from kwai.core.json_api import Document, Relationship, ResourceData -from kwai.modules.club.domain.team import TeamEntity -from kwai.modules.club.domain.team_member import TeamMemberEntity +from kwai.modules.teams.domain.team import TeamEntity +from kwai.modules.teams.domain.team_member import TeamMemberEntity class TeamMemberAttributes(BaseModel): diff --git a/backend/src/kwai/modules/club/repositories/_tables.py b/backend/src/kwai/modules/club/repositories/_tables.py index 6c1c08c5..263205e0 100644 --- a/backend/src/kwai/modules/club/repositories/_tables.py +++ b/backend/src/kwai/modules/club/repositories/_tables.py @@ -17,7 +17,6 @@ from kwai.modules.club.domain.file_upload import FileUploadEntity from kwai.modules.club.domain.member import MemberEntity, MemberIdentifier from kwai.modules.club.domain.person import PersonEntity, PersonIdentifier -from kwai.modules.club.domain.team import TeamEntity from kwai.modules.club.domain.value_objects import ( Address, Birthdate, @@ -327,72 +326,3 @@ def persist(cls, coach: CoachEntity) -> Self: created_at=coach.traceable_time.created_at.timestamp, # type: ignore[arg-type] updated_at=coach.traceable_time.updated_at.timestamp, ) - - -@dataclass(kw_only=True, frozen=True, slots=True) -class TeamRow(TableRow): - """Represents a row of the teams table.""" - - __table_name__ = "teams" - - id: int - name: str - season_id: int | None - team_category_id: int | None - active: int - remark: str - created_at: datetime - updated_at: datetime | None - - @classmethod - def persist(cls, team: TeamEntity) -> Self: - return cls( - id=team.id.value, - name=team.name, - season_id=None, - team_category_id=None, - active=1 if team.is_active else 0, - remark=team.remark, - created_at=team.traceable_time.created_at.timestamp, # type: ignore[arg-type] - updated_at=team.traceable_time.updated_at.timestamp, - ) - - -@dataclass(kw_only=True, frozen=True, slots=True) -class TeamMemberRow(TableRow): - """Represents a row of the members table used for a team member.""" - - __table_name__ = "judo_members" - - id: int - uuid: str - license: str - license_end_date: date - person_id: int - - -@dataclass(kw_only=True, frozen=True, slots=True) -class TeamMemberPersonRow(TableRow): - """Represents a row of the persons table used for a team member.""" - - __table_name__ = "persons" - - id: int - firstname: str - lastname: str - gender: int - birthdate: date - nationality_id: int - - -@dataclass(kw_only=True, frozen=True, slots=True) -class TeamMembersRow(TableRow): - """Represents a row of the team members table.""" - - __table_name__ = "team_members" - - team_id: int - member_id: int - active: int - created_at: datetime - updated_at: datetime | None diff --git a/backend/src/kwai/modules/teams/__init__.py b/backend/src/kwai/modules/teams/__init__.py new file mode 100644 index 00000000..e805ce15 --- /dev/null +++ b/backend/src/kwai/modules/teams/__init__.py @@ -0,0 +1 @@ +"""Package for the teams module.""" diff --git a/backend/src/kwai/modules/teams/domain/__init__.py b/backend/src/kwai/modules/teams/domain/__init__.py new file mode 100644 index 00000000..cff76536 --- /dev/null +++ b/backend/src/kwai/modules/teams/domain/__init__.py @@ -0,0 +1 @@ +"""Package for domain models of the teams module.""" diff --git a/backend/src/kwai/modules/club/domain/team.py b/backend/src/kwai/modules/teams/domain/team.py similarity index 95% rename from backend/src/kwai/modules/club/domain/team.py rename to backend/src/kwai/modules/teams/domain/team.py index f53ab7aa..5d5cad7b 100644 --- a/backend/src/kwai/modules/club/domain/team.py +++ b/backend/src/kwai/modules/teams/domain/team.py @@ -3,7 +3,7 @@ from kwai.core.domain.entity import Entity from kwai.core.domain.value_objects.identifier import IntIdentifier from kwai.core.domain.value_objects.traceable_time import TraceableTime -from kwai.modules.club.domain.team_member import TeamMemberEntity +from kwai.modules.teams.domain.team_member import TeamMemberEntity TeamIdentifier = IntIdentifier diff --git a/backend/src/kwai/modules/club/domain/team_member.py b/backend/src/kwai/modules/teams/domain/team_member.py similarity index 100% rename from backend/src/kwai/modules/club/domain/team_member.py rename to backend/src/kwai/modules/teams/domain/team_member.py diff --git a/backend/src/kwai/modules/club/get_teams.py b/backend/src/kwai/modules/teams/get_teams.py similarity index 93% rename from backend/src/kwai/modules/club/get_teams.py rename to backend/src/kwai/modules/teams/get_teams.py index efbc6f80..ce584722 100644 --- a/backend/src/kwai/modules/club/get_teams.py +++ b/backend/src/kwai/modules/teams/get_teams.py @@ -3,7 +3,7 @@ from dataclasses import dataclass from kwai.core.domain.presenter import Presenter -from kwai.modules.club.domain.team import TeamEntity +from kwai.modules.teams.domain.team import TeamEntity from kwai.modules.training.teams.team_repository import TeamRepository diff --git a/backend/src/kwai/modules/teams/repositories/__init__.py b/backend/src/kwai/modules/teams/repositories/__init__.py new file mode 100644 index 00000000..96987a8f --- /dev/null +++ b/backend/src/kwai/modules/teams/repositories/__init__.py @@ -0,0 +1 @@ +"""Package for the repositories of the teams module.""" diff --git a/backend/src/kwai/modules/teams/repositories/_tables.py b/backend/src/kwai/modules/teams/repositories/_tables.py new file mode 100644 index 00000000..8ba5ba92 --- /dev/null +++ b/backend/src/kwai/modules/teams/repositories/_tables.py @@ -0,0 +1,75 @@ +from dataclasses import dataclass +from datetime import date, datetime +from typing import Self + +from kwai.core.db.table_row import TableRow +from kwai.modules.teams.domain.team import TeamEntity + + +@dataclass(kw_only=True, frozen=True, slots=True) +class TeamRow(TableRow): + """Represents a row of the teams table.""" + + __table_name__ = "teams" + + id: int + name: str + season_id: int | None + team_category_id: int | None + active: int + remark: str + created_at: datetime + updated_at: datetime | None + + @classmethod + def persist(cls, team: TeamEntity) -> Self: + return cls( + id=team.id.value, + name=team.name, + season_id=None, + team_category_id=None, + active=1 if team.is_active else 0, + remark=team.remark, + created_at=team.traceable_time.created_at.timestamp, # type: ignore[arg-type] + updated_at=team.traceable_time.updated_at.timestamp, + ) + + +@dataclass(kw_only=True, frozen=True, slots=True) +class TeamMemberRow(TableRow): + """Represents a row of the members table used for a team member.""" + + __table_name__ = "judo_members" + + id: int + uuid: str + license: str + license_end_date: date + person_id: int + + +@dataclass(kw_only=True, frozen=True, slots=True) +class TeamMemberPersonRow(TableRow): + """Represents a row of the persons table used for a team member.""" + + __table_name__ = "persons" + + id: int + firstname: str + lastname: str + gender: int + birthdate: date + nationality_id: int + + +@dataclass(kw_only=True, frozen=True, slots=True) +class TeamMembersRow(TableRow): + """Represents a row of the team members table.""" + + __table_name__ = "team_members" + + team_id: int + member_id: int + active: int + created_at: datetime + updated_at: datetime | None diff --git a/backend/src/kwai/modules/club/repositories/team_db_repository.py b/backend/src/kwai/modules/teams/repositories/team_db_repository.py similarity index 92% rename from backend/src/kwai/modules/club/repositories/team_db_repository.py rename to backend/src/kwai/modules/teams/repositories/team_db_repository.py index 6fbcb523..0028593c 100644 --- a/backend/src/kwai/modules/club/repositories/team_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_db_repository.py @@ -9,15 +9,17 @@ from kwai.core.db.database_query import DatabaseQuery from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.entity import Entity -from kwai.modules.club.domain.team import TeamEntity, TeamIdentifier from kwai.modules.club.repositories._tables import ( CountryRow, +) +from kwai.modules.teams.domain.team import TeamEntity, TeamIdentifier +from kwai.modules.teams.repositories._tables import ( TeamMemberPersonRow, TeamMemberRow, TeamMembersRow, TeamRow, ) -from kwai.modules.club.repositories.team_repository import TeamQuery, TeamRepository +from kwai.modules.teams.repositories.team_repository import TeamQuery, TeamRepository @dataclass(kw_only=True, frozen=True, slots=True) diff --git a/backend/src/kwai/modules/club/repositories/team_member_db_repository.py b/backend/src/kwai/modules/teams/repositories/team_member_db_repository.py similarity index 94% rename from backend/src/kwai/modules/club/repositories/team_member_db_repository.py rename to backend/src/kwai/modules/teams/repositories/team_member_db_repository.py index 3212c4b9..dc51ddd2 100644 --- a/backend/src/kwai/modules/club/repositories/team_member_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_member_db_repository.py @@ -11,14 +11,13 @@ from kwai.core.domain.value_objects.date import Date from kwai.core.domain.value_objects.name import Name from kwai.core.domain.value_objects.unique_id import UniqueId -from kwai.modules.club.domain.team_member import TeamMemberEntity, TeamMemberIdentifier from kwai.modules.club.domain.value_objects import Birthdate, Gender, License from kwai.modules.club.repositories._tables import ( CountryRow, - TeamMemberPersonRow, - TeamMemberRow, ) -from kwai.modules.club.repositories.team_member_repository import ( +from kwai.modules.teams.domain.team_member import TeamMemberEntity, TeamMemberIdentifier +from kwai.modules.teams.repositories._tables import TeamMemberPersonRow, TeamMemberRow +from kwai.modules.teams.repositories.team_member_repository import ( TeamMemberNotFoundException, TeamMemberQuery, TeamMemberRepository, diff --git a/backend/src/kwai/modules/club/repositories/team_member_repository.py b/backend/src/kwai/modules/teams/repositories/team_member_repository.py similarity index 95% rename from backend/src/kwai/modules/club/repositories/team_member_repository.py rename to backend/src/kwai/modules/teams/repositories/team_member_repository.py index ecc2d8b2..599c1c4e 100644 --- a/backend/src/kwai/modules/club/repositories/team_member_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_member_repository.py @@ -5,7 +5,7 @@ from kwai.core.domain.repository.query import Query from kwai.core.domain.value_objects.date import Date -from kwai.modules.club.domain.team_member import TeamMemberEntity, TeamMemberIdentifier +from kwai.modules.teams.domain.team_member import TeamMemberEntity, TeamMemberIdentifier class TeamMemberNotFoundException(Exception): diff --git a/backend/src/kwai/modules/club/repositories/team_repository.py b/backend/src/kwai/modules/teams/repositories/team_repository.py similarity index 96% rename from backend/src/kwai/modules/club/repositories/team_repository.py rename to backend/src/kwai/modules/teams/repositories/team_repository.py index ed482416..dd67d9ca 100644 --- a/backend/src/kwai/modules/club/repositories/team_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_repository.py @@ -4,7 +4,7 @@ from typing import AsyncGenerator, Self from kwai.core.domain.repository.query import Query -from kwai.modules.club.domain.team import TeamEntity, TeamIdentifier +from kwai.modules.teams.domain.team import TeamEntity, TeamIdentifier class TeamNotFoundException(Exception): diff --git a/backend/src/tests/api/v1/teams/test_schemas.py b/backend/src/tests/api/v1/teams/test_schemas.py index 6cb4993e..6f4a6322 100644 --- a/backend/src/tests/api/v1/teams/test_schemas.py +++ b/backend/src/tests/api/v1/teams/test_schemas.py @@ -9,9 +9,9 @@ from kwai.core.domain.value_objects.date import Date from kwai.core.domain.value_objects.name import Name from kwai.core.domain.value_objects.unique_id import UniqueId -from kwai.modules.club.domain.team import TeamEntity, TeamIdentifier -from kwai.modules.club.domain.team_member import TeamMemberEntity, TeamMemberIdentifier from kwai.modules.club.domain.value_objects import Birthdate, Gender, License +from kwai.modules.teams.domain.team import TeamEntity, TeamIdentifier +from kwai.modules.teams.domain.team_member import TeamMemberEntity, TeamMemberIdentifier from tests.fixtures.club.countries import * # noqa diff --git a/backend/src/tests/fixtures/club/team_members.py b/backend/src/tests/fixtures/club/team_members.py index 31b49f6b..b0b0e30a 100644 --- a/backend/src/tests/fixtures/club/team_members.py +++ b/backend/src/tests/fixtures/club/team_members.py @@ -2,7 +2,7 @@ import pytest from kwai.modules.club.domain.member import MemberEntity -from kwai.modules.club.domain.team_member import TeamMemberEntity +from kwai.modules.teams.domain.team_member import TeamMemberEntity @pytest.fixture diff --git a/backend/src/tests/fixtures/club/teams.py b/backend/src/tests/fixtures/club/teams.py index 94c0094d..fc028cad 100644 --- a/backend/src/tests/fixtures/club/teams.py +++ b/backend/src/tests/fixtures/club/teams.py @@ -3,8 +3,8 @@ import pytest from kwai.core.db.database import Database from kwai.core.db.uow import UnitOfWork -from kwai.modules.club.domain.team import TeamEntity -from kwai.modules.club.repositories.team_db_repository import TeamDbRepository +from kwai.modules.teams.domain.team import TeamEntity +from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository @pytest.fixture diff --git a/backend/src/tests/modules/teams/__init__.py b/backend/src/tests/modules/teams/__init__.py new file mode 100644 index 00000000..f2ba449e --- /dev/null +++ b/backend/src/tests/modules/teams/__init__.py @@ -0,0 +1 @@ +"""Package for testing the teams module.""" diff --git a/backend/src/tests/modules/teams/domain/__init__.py b/backend/src/tests/modules/teams/domain/__init__.py new file mode 100644 index 00000000..216cf9d5 --- /dev/null +++ b/backend/src/tests/modules/teams/domain/__init__.py @@ -0,0 +1 @@ +"""Package for testing teams domain models.""" diff --git a/backend/src/tests/modules/teams/repositories/__init__.py b/backend/src/tests/modules/teams/repositories/__init__.py new file mode 100644 index 00000000..2dde9a55 --- /dev/null +++ b/backend/src/tests/modules/teams/repositories/__init__.py @@ -0,0 +1 @@ +"""Package for testing the repositories of the teams module.""" diff --git a/backend/src/tests/modules/club/repositories/test_team_db_repository.py b/backend/src/tests/modules/teams/repositories/test_team_db_repository.py similarity index 100% rename from backend/src/tests/modules/club/repositories/test_team_db_repository.py rename to backend/src/tests/modules/teams/repositories/test_team_db_repository.py diff --git a/backend/src/tests/modules/club/repositories/test_team_member_db_query.py b/backend/src/tests/modules/teams/repositories/test_team_member_db_query.py similarity index 83% rename from backend/src/tests/modules/club/repositories/test_team_member_db_query.py rename to backend/src/tests/modules/teams/repositories/test_team_member_db_query.py index 9a9cee29..afc1deca 100644 --- a/backend/src/tests/modules/club/repositories/test_team_member_db_query.py +++ b/backend/src/tests/modules/teams/repositories/test_team_member_db_query.py @@ -3,9 +3,9 @@ import pytest from kwai.core.db.database import Database from kwai.core.domain.value_objects.date import Date -from kwai.modules.club.domain.team_member import TeamMemberIdentifier -from kwai.modules.club.repositories.team_member_db_repository import TeamMemberDbQuery -from kwai.modules.club.repositories.team_member_repository import TeamMemberQuery +from kwai.modules.teams.domain.team_member import TeamMemberIdentifier +from kwai.modules.teams.repositories.team_member_db_repository import TeamMemberDbQuery +from kwai.modules.teams.repositories.team_member_repository import TeamMemberQuery pytestmark = pytest.mark.db diff --git a/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py b/backend/src/tests/modules/teams/repositories/test_team_member_db_repository.py similarity index 97% rename from backend/src/tests/modules/club/repositories/test_team_member_db_repository.py rename to backend/src/tests/modules/teams/repositories/test_team_member_db_repository.py index 126896bd..78399f81 100644 --- a/backend/src/tests/modules/club/repositories/test_team_member_db_repository.py +++ b/backend/src/tests/modules/teams/repositories/test_team_member_db_repository.py @@ -4,7 +4,7 @@ from kwai.core.db.database import Database from kwai.core.domain.value_objects.date import Date from kwai.modules.club.domain.value_objects import Birthdate -from kwai.modules.club.repositories.team_member_db_repository import ( +from kwai.modules.teams.repositories.team_member_db_repository import ( TeamMemberDbRepository, ) From d0076f0d941165fb6ced20565f30dec838d9d972 Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 12 Jun 2024 21:11:18 +0200 Subject: [PATCH 113/410] test: add entity fixtures --- backend/src/tests/modules/teams/conftest.py | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 backend/src/tests/modules/teams/conftest.py diff --git a/backend/src/tests/modules/teams/conftest.py b/backend/src/tests/modules/teams/conftest.py new file mode 100644 index 00000000..28b3cf52 --- /dev/null +++ b/backend/src/tests/modules/teams/conftest.py @@ -0,0 +1,8 @@ +"""Module for common fixtures used for testing code of the club module.""" + +from tests.fixtures.club.countries import * # noqa +from tests.fixtures.club.contacts import * # noqa +from tests.fixtures.club.persons import * # noqa +from tests.fixtures.club.members import * # noqa +from tests.fixtures.club.coaches import * # noqa +from tests.fixtures.club.teams import * # noqa From 9eebfae63679e771012273b77620141eb5df2428 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 15 Jun 2024 14:36:26 +0200 Subject: [PATCH 114/410] refactor: move teams fixtures --- backend/src/tests/fixtures/teams/__init__.py | 1 + backend/src/tests/fixtures/{club => teams}/team_members.py | 0 backend/src/tests/modules/teams/conftest.py | 2 +- 3 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 backend/src/tests/fixtures/teams/__init__.py rename backend/src/tests/fixtures/{club => teams}/team_members.py (100%) diff --git a/backend/src/tests/fixtures/teams/__init__.py b/backend/src/tests/fixtures/teams/__init__.py new file mode 100644 index 00000000..533b46b0 --- /dev/null +++ b/backend/src/tests/fixtures/teams/__init__.py @@ -0,0 +1 @@ +"""Package for defining recurring fixtures for the teams bounded context.""" diff --git a/backend/src/tests/fixtures/club/team_members.py b/backend/src/tests/fixtures/teams/team_members.py similarity index 100% rename from backend/src/tests/fixtures/club/team_members.py rename to backend/src/tests/fixtures/teams/team_members.py diff --git a/backend/src/tests/modules/teams/conftest.py b/backend/src/tests/modules/teams/conftest.py index 28b3cf52..ea68a495 100644 --- a/backend/src/tests/modules/teams/conftest.py +++ b/backend/src/tests/modules/teams/conftest.py @@ -5,4 +5,4 @@ from tests.fixtures.club.persons import * # noqa from tests.fixtures.club.members import * # noqa from tests.fixtures.club.coaches import * # noqa -from tests.fixtures.club.teams import * # noqa +from tests.fixtures.teams.team_members import * # noqa From 1d8b74c2abe93313e13aa1aa62c8a3b7c9e8a5d4 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 15 Jun 2024 15:00:35 +0200 Subject: [PATCH 115/410] refactor: fixtures for teams moved --- backend/src/tests/fixtures/{club => teams}/teams.py | 0 backend/src/tests/modules/club/conftest.py | 1 - backend/src/tests/modules/teams/conftest.py | 1 + backend/src/tests/modules/training/conftest.py | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) rename backend/src/tests/fixtures/{club => teams}/teams.py (100%) diff --git a/backend/src/tests/fixtures/club/teams.py b/backend/src/tests/fixtures/teams/teams.py similarity index 100% rename from backend/src/tests/fixtures/club/teams.py rename to backend/src/tests/fixtures/teams/teams.py diff --git a/backend/src/tests/modules/club/conftest.py b/backend/src/tests/modules/club/conftest.py index 28b3cf52..f79f4fa2 100644 --- a/backend/src/tests/modules/club/conftest.py +++ b/backend/src/tests/modules/club/conftest.py @@ -5,4 +5,3 @@ from tests.fixtures.club.persons import * # noqa from tests.fixtures.club.members import * # noqa from tests.fixtures.club.coaches import * # noqa -from tests.fixtures.club.teams import * # noqa diff --git a/backend/src/tests/modules/teams/conftest.py b/backend/src/tests/modules/teams/conftest.py index ea68a495..11b8678e 100644 --- a/backend/src/tests/modules/teams/conftest.py +++ b/backend/src/tests/modules/teams/conftest.py @@ -5,4 +5,5 @@ from tests.fixtures.club.persons import * # noqa from tests.fixtures.club.members import * # noqa from tests.fixtures.club.coaches import * # noqa +from tests.fixtures.teams.teams import * # noqa from tests.fixtures.teams.team_members import * # noqa diff --git a/backend/src/tests/modules/training/conftest.py b/backend/src/tests/modules/training/conftest.py index 6e45b30f..48c65336 100644 --- a/backend/src/tests/modules/training/conftest.py +++ b/backend/src/tests/modules/training/conftest.py @@ -5,6 +5,6 @@ from tests.fixtures.club.countries import * # noqa from tests.fixtures.club.members import * # noqa from tests.fixtures.club.persons import * # noqa -from tests.fixtures.club.teams import * # noqa +from tests.fixtures.teams.teams import * # noqa from tests.fixtures.training.training_definitions import * # noqa from tests.fixtures.training.trainings import * # noqa From d11ae7121a24ff510257a7c903d945eea31bef3c Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 15 Jun 2024 15:30:24 +0200 Subject: [PATCH 116/410] refactor: rename TeamMemberEntity and add TeamMember dataclass --- backend/src/kwai/api/v1/teams/schemas.py | 4 +-- backend/src/kwai/modules/teams/domain/team.py | 6 ++--- .../kwai/modules/teams/domain/team_member.py | 18 ++++++++++--- .../repositories/team_member_db_repository.py | 14 +++++----- .../repositories/team_member_repository.py | 8 +++--- .../src/tests/api/v1/teams/test_schemas.py | 14 +++++----- .../src/tests/fixtures/teams/team_members.py | 26 +++++++++++-------- .../repositories/test_team_member_db_query.py | 4 +-- 8 files changed, 55 insertions(+), 39 deletions(-) diff --git a/backend/src/kwai/api/v1/teams/schemas.py b/backend/src/kwai/api/v1/teams/schemas.py index e31211c3..d27f0762 100644 --- a/backend/src/kwai/api/v1/teams/schemas.py +++ b/backend/src/kwai/api/v1/teams/schemas.py @@ -12,7 +12,7 @@ ) from kwai.core.json_api import Document, Relationship, ResourceData from kwai.modules.teams.domain.team import TeamEntity -from kwai.modules.teams.domain.team_member import TeamMemberEntity +from kwai.modules.teams.domain.team_member import MemberEntity class TeamMemberAttributes(BaseModel): @@ -46,7 +46,7 @@ class TeamMemberDocument(Document[TeamMemberResource, TeamMemberInclude]): """A JSON:API document for one or more team members.""" @classmethod - def create(cls, team_member: TeamMemberEntity) -> Self: + def create(cls, team_member: MemberEntity) -> Self: """Create a team member document.""" nationality_document = CountryDocument.create(team_member.nationality) diff --git a/backend/src/kwai/modules/teams/domain/team.py b/backend/src/kwai/modules/teams/domain/team.py index 5d5cad7b..4abbb9f4 100644 --- a/backend/src/kwai/modules/teams/domain/team.py +++ b/backend/src/kwai/modules/teams/domain/team.py @@ -3,7 +3,7 @@ from kwai.core.domain.entity import Entity from kwai.core.domain.value_objects.identifier import IntIdentifier from kwai.core.domain.value_objects.traceable_time import TraceableTime -from kwai.modules.teams.domain.team_member import TeamMemberEntity +from kwai.modules.teams.domain.team_member import MemberEntity TeamIdentifier = IntIdentifier @@ -18,7 +18,7 @@ def __init__( name: str, active: bool = True, remark: str = "", - members: list[TeamMemberEntity] = None, + members: list[MemberEntity] = None, traceable_time: TraceableTime | None = None, ): super().__init__(id_ or TeamIdentifier()) @@ -49,7 +49,7 @@ def traceable_time(self) -> TraceableTime: return self._traceable_time @property - def members(self) -> list[TeamMemberEntity]: + def members(self) -> list[MemberEntity]: """Return the members. Note: the returned list is a copy. diff --git a/backend/src/kwai/modules/teams/domain/team_member.py b/backend/src/kwai/modules/teams/domain/team_member.py index 5cd327d3..1227880f 100644 --- a/backend/src/kwai/modules/teams/domain/team_member.py +++ b/backend/src/kwai/modules/teams/domain/team_member.py @@ -1,16 +1,19 @@ """Module for defining the team member entity.""" +from dataclasses import dataclass + from kwai.core.domain.entity import Entity from kwai.core.domain.value_objects.identifier import IntIdentifier from kwai.core.domain.value_objects.name import Name +from kwai.core.domain.value_objects.traceable_time import TraceableTime from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.club.domain.country import CountryEntity from kwai.modules.club.domain.value_objects import Birthdate, Gender, License -TeamMemberIdentifier = IntIdentifier +MemberIdentifier = IntIdentifier -class TeamMemberEntity(Entity[TeamMemberIdentifier]): +class MemberEntity(Entity[MemberIdentifier]): """A team member entity. A team member entity is an entity which holds specific information of a member @@ -20,7 +23,7 @@ class TeamMemberEntity(Entity[TeamMemberIdentifier]): def __init__( self, *, - id_: TeamMemberIdentifier, + id_: MemberIdentifier, uuid: UniqueId, name: Name, license: License, @@ -65,3 +68,12 @@ def nationality(self) -> CountryEntity: def gender(self) -> Gender: """Return the gender.""" return self._gender + + +@dataclass(kw_only=True, frozen=True, slots=True) +class TeamMember: + """Represent a member of a team.""" + + active: bool + member: MemberEntity + traceable_time: TraceableTime diff --git a/backend/src/kwai/modules/teams/repositories/team_member_db_repository.py b/backend/src/kwai/modules/teams/repositories/team_member_db_repository.py index dc51ddd2..cbe4d919 100644 --- a/backend/src/kwai/modules/teams/repositories/team_member_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_member_db_repository.py @@ -15,7 +15,7 @@ from kwai.modules.club.repositories._tables import ( CountryRow, ) -from kwai.modules.teams.domain.team_member import TeamMemberEntity, TeamMemberIdentifier +from kwai.modules.teams.domain.team_member import MemberEntity, MemberIdentifier from kwai.modules.teams.repositories._tables import TeamMemberPersonRow, TeamMemberRow from kwai.modules.teams.repositories.team_member_repository import ( TeamMemberNotFoundException, @@ -32,10 +32,10 @@ class TeamMemberQueryRow(JoinedTableRow): person: TeamMemberPersonRow country: CountryRow - def create_entity(self) -> TeamMemberEntity: + def create_entity(self) -> MemberEntity: """Create a team member entity from a row.""" - return TeamMemberEntity( - id_=TeamMemberIdentifier(self.member.id), + return MemberEntity( + id_=MemberIdentifier(self.member.id), uuid=UniqueId.create_from_string(self.member.uuid), name=Name(first_name=self.person.firstname, last_name=self.person.lastname), license=License( @@ -70,7 +70,7 @@ def columns(self): def count_column(self): return TeamMemberRow.column("id") - def find_by_id(self, id_: TeamMemberIdentifier) -> Self: + def find_by_id(self, id_: MemberIdentifier) -> Self: self._query.and_where(TeamMemberRow.field("id").eq(id_.value)) return self @@ -95,7 +95,7 @@ def __init__(self, database: Database): def create_query(self) -> TeamMemberQuery: return TeamMemberDbQuery(self._database) - async def get(self, query: TeamMemberQuery | None = None) -> TeamMemberEntity: + async def get(self, query: TeamMemberQuery | None = None) -> MemberEntity: team_member_iterator = self.get_all(query) try: return await anext(team_member_iterator) @@ -107,7 +107,7 @@ async def get_all( query: TeamMemberQuery | None = None, limit: int | None = None, offset: int | None = None, - ) -> AsyncGenerator[TeamMemberEntity, None]: + ) -> AsyncGenerator[MemberEntity, None]: query = query or self.create_query() async for row in query.fetch(limit, offset): diff --git a/backend/src/kwai/modules/teams/repositories/team_member_repository.py b/backend/src/kwai/modules/teams/repositories/team_member_repository.py index 599c1c4e..9b78120f 100644 --- a/backend/src/kwai/modules/teams/repositories/team_member_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_member_repository.py @@ -5,7 +5,7 @@ from kwai.core.domain.repository.query import Query from kwai.core.domain.value_objects.date import Date -from kwai.modules.teams.domain.team_member import TeamMemberEntity, TeamMemberIdentifier +from kwai.modules.teams.domain.team_member import MemberEntity, MemberIdentifier class TeamMemberNotFoundException(Exception): @@ -16,7 +16,7 @@ class TeamMemberQuery(Query, ABC): """An interface for a team member query.""" @abstractmethod - def find_by_id(self, id_: TeamMemberIdentifier) -> Self: + def find_by_id(self, id_: MemberIdentifier) -> Self: """Find a team member by its id.""" raise NotImplementedError @@ -35,7 +35,7 @@ def create_query(self) -> TeamMemberQuery: raise NotImplementedError @abstractmethod - async def get(self, query: TeamMemberQuery | None = None) -> TeamMemberEntity: + async def get(self, query: TeamMemberQuery | None = None) -> MemberEntity: """Return the first returned element of the given query. Args: @@ -52,7 +52,7 @@ def get_all( query: TeamMemberQuery | None = None, limit: int | None = None, offset: int | None = None, - ) -> AsyncGenerator[TeamMemberEntity, None]: + ) -> AsyncGenerator[MemberEntity, None]: """Return all team members of the given query. Args: diff --git a/backend/src/tests/api/v1/teams/test_schemas.py b/backend/src/tests/api/v1/teams/test_schemas.py index 6f4a6322..83d7b418 100644 --- a/backend/src/tests/api/v1/teams/test_schemas.py +++ b/backend/src/tests/api/v1/teams/test_schemas.py @@ -11,16 +11,16 @@ from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.club.domain.value_objects import Birthdate, Gender, License from kwai.modules.teams.domain.team import TeamEntity, TeamIdentifier -from kwai.modules.teams.domain.team_member import TeamMemberEntity, TeamMemberIdentifier +from kwai.modules.teams.domain.team_member import MemberEntity, MemberIdentifier from tests.fixtures.club.countries import * # noqa @pytest.fixture -def team_member(country_japan) -> TeamMemberEntity: +def team_member(country_japan) -> MemberEntity: """A fixture for a team member.""" - return TeamMemberEntity( - id_=TeamMemberIdentifier(1), + return MemberEntity( + id_=MemberIdentifier(1), name=Name(first_name="Jigoro", last_name="Kano"), uuid=UniqueId.generate(), license=License(number="1234", end_date=Date.today().add(years=1)), @@ -31,7 +31,7 @@ def team_member(country_japan) -> TeamMemberEntity: @pytest.fixture -def expected_team_member_json(team_member: TeamMemberEntity) -> dict[str, Any]: +def expected_team_member_json(team_member: MemberEntity) -> dict[str, Any]: """A fixture for a JSON:API resource of a team member.""" return { "data": { @@ -65,7 +65,7 @@ def expected_team_member_json(team_member: TeamMemberEntity) -> dict[str, Any]: def test_create_team_member_document( - team_member: TeamMemberEntity, expected_team_member_json: dict[str, Any] + team_member: MemberEntity, expected_team_member_json: dict[str, Any] ): """Test the creation of a JSON:API document for a team member resource.""" team_member_document = TeamMemberDocument.create(team_member) @@ -76,7 +76,7 @@ def test_create_team_member_document( @pytest.fixture -def team(team_member: TeamMemberEntity) -> TeamEntity: +def team(team_member: MemberEntity) -> TeamEntity: """A fixture for a team entity.""" return TeamEntity( id_=TeamIdentifier(1), diff --git a/backend/src/tests/fixtures/teams/team_members.py b/backend/src/tests/fixtures/teams/team_members.py index b0b0e30a..f5e72ea9 100644 --- a/backend/src/tests/fixtures/teams/team_members.py +++ b/backend/src/tests/fixtures/teams/team_members.py @@ -1,24 +1,28 @@ """Module for defining factory fixtures for team members.""" import pytest -from kwai.modules.club.domain.member import MemberEntity -from kwai.modules.teams.domain.team_member import TeamMemberEntity +from kwai.core.domain.value_objects.traceable_time import TraceableTime +from kwai.modules.teams.domain.team_member import MemberEntity, TeamMember @pytest.fixture def make_team_member(make_member): """A factory fixture for a team member.""" - def _make_team_member(member: MemberEntity | None = None) -> TeamMemberEntity: + def _make_team_member(member: MemberEntity | None = None) -> TeamMember: member = member or make_member() - return TeamMemberEntity( - id_=member.id, - uuid=member.uuid, - name=member.name, - license=member.license, - birthdate=member.person.birthdate, - nationality=member.person.nationality, - gender=member.person.gender, + return TeamMember( + active=True, + member=MemberEntity( + id_=member.id, + uuid=member.uuid, + name=member.name, + license=member.license, + birthdate=member.person.birthdate, + nationality=member.person.nationality, + gender=member.person.gender, + ), + traceable_time=TraceableTime(), ) return _make_team_member diff --git a/backend/src/tests/modules/teams/repositories/test_team_member_db_query.py b/backend/src/tests/modules/teams/repositories/test_team_member_db_query.py index afc1deca..16203c33 100644 --- a/backend/src/tests/modules/teams/repositories/test_team_member_db_query.py +++ b/backend/src/tests/modules/teams/repositories/test_team_member_db_query.py @@ -3,7 +3,7 @@ import pytest from kwai.core.db.database import Database from kwai.core.domain.value_objects.date import Date -from kwai.modules.teams.domain.team_member import TeamMemberIdentifier +from kwai.modules.teams.domain.team_member import MemberIdentifier from kwai.modules.teams.repositories.team_member_db_repository import TeamMemberDbQuery from kwai.modules.teams.repositories.team_member_repository import TeamMemberQuery @@ -18,7 +18,7 @@ def query(database: Database) -> TeamMemberQuery: async def test_filter_by_id(query: TeamMemberQuery): """Test filtering by id.""" - query.find_by_id(TeamMemberIdentifier(1)) + query.find_by_id(MemberIdentifier(1)) try: await query.fetch_one() except Exception as exc: From 49b10bdfea3f0cfab5f9b048e8a77f4167c22111 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 15 Jun 2024 15:50:47 +0200 Subject: [PATCH 117/410] refactor: use TeamMember --- backend/src/kwai/api/v1/teams/schemas.py | 28 +++++++++++-------- backend/src/kwai/modules/teams/domain/team.py | 6 ++-- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/backend/src/kwai/api/v1/teams/schemas.py b/backend/src/kwai/api/v1/teams/schemas.py index d27f0762..cc7bddf7 100644 --- a/backend/src/kwai/api/v1/teams/schemas.py +++ b/backend/src/kwai/api/v1/teams/schemas.py @@ -10,14 +10,15 @@ CountryResourceIdentifier, MemberResourceIdentifier, ) -from kwai.core.json_api import Document, Relationship, ResourceData +from kwai.core.json_api import Document, Relationship, ResourceData, ResourceMeta from kwai.modules.teams.domain.team import TeamEntity -from kwai.modules.teams.domain.team_member import MemberEntity +from kwai.modules.teams.domain.team_member import TeamMember class TeamMemberAttributes(BaseModel): """Attributes for a team member.""" + active: bool first_name: str last_name: str license_number: str @@ -46,19 +47,24 @@ class TeamMemberDocument(Document[TeamMemberResource, TeamMemberInclude]): """A JSON:API document for one or more team members.""" @classmethod - def create(cls, team_member: MemberEntity) -> Self: + def create(cls, team_member: TeamMember) -> Self: """Create a team member document.""" - nationality_document = CountryDocument.create(team_member.nationality) + nationality_document = CountryDocument.create(team_member.member.nationality) team_member_resource = TeamMemberResource( - id=str(team_member.uuid), + id=str(team_member.member.uuid), attributes=TeamMemberAttributes( - first_name=team_member.name.first_name, - last_name=team_member.name.last_name, - license_number=team_member.license.number, - license_end_date=str(team_member.license.end_date), - gender=team_member.gender, - birthdate=str(team_member.birthdate), + active=team_member.active, + first_name=team_member.member.name.first_name, + last_name=team_member.member.name.last_name, + license_number=team_member.member.license.number, + license_end_date=str(team_member.member.license.end_date), + gender=team_member.member.gender, + birthdate=str(team_member.member.birthdate), + ), + meta=ResourceMeta( + created_at=str(team_member.traceable_time.created_at), + updated_at=str(team_member.traceable_time.updated_at), ), ) team_member_resource.relationships = TeamMemberRelationships( diff --git a/backend/src/kwai/modules/teams/domain/team.py b/backend/src/kwai/modules/teams/domain/team.py index 4abbb9f4..806e5b3b 100644 --- a/backend/src/kwai/modules/teams/domain/team.py +++ b/backend/src/kwai/modules/teams/domain/team.py @@ -3,7 +3,7 @@ from kwai.core.domain.entity import Entity from kwai.core.domain.value_objects.identifier import IntIdentifier from kwai.core.domain.value_objects.traceable_time import TraceableTime -from kwai.modules.teams.domain.team_member import MemberEntity +from kwai.modules.teams.domain.team_member import TeamMember TeamIdentifier = IntIdentifier @@ -18,7 +18,7 @@ def __init__( name: str, active: bool = True, remark: str = "", - members: list[MemberEntity] = None, + members: list[TeamMember] = None, traceable_time: TraceableTime | None = None, ): super().__init__(id_ or TeamIdentifier()) @@ -49,7 +49,7 @@ def traceable_time(self) -> TraceableTime: return self._traceable_time @property - def members(self) -> list[MemberEntity]: + def members(self) -> list[TeamMember]: """Return the members. Note: the returned list is a copy. From 34309ef4c2e9eca9fefd6dd2b4ccb0f887ee0d14 Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 18 Jun 2024 20:28:54 +0200 Subject: [PATCH 118/410] refactor: rename team_member into member --- .../modules/teams/repositories/_tables.py | 6 +- ..._repository.py => member_db_repository.py} | 59 ++++++++++--------- ...ber_repository.py => member_repository.py} | 24 ++++---- .../teams/repositories/team_db_repository.py | 20 +++---- .../src/tests/fixtures/teams/team_members.py | 14 +++++ ...er_db_query.py => test_member_db_query.py} | 14 ++--- ...sitory.py => test_member_db_repository.py} | 34 +++++------ 7 files changed, 93 insertions(+), 78 deletions(-) rename backend/src/kwai/modules/teams/repositories/{team_member_db_repository.py => member_db_repository.py} (61%) rename backend/src/kwai/modules/teams/repositories/{team_member_repository.py => member_repository.py} (69%) rename backend/src/tests/modules/teams/repositories/{test_team_member_db_query.py => test_member_db_query.py} (69%) rename backend/src/tests/modules/teams/repositories/{test_team_member_db_repository.py => test_member_db_repository.py} (73%) diff --git a/backend/src/kwai/modules/teams/repositories/_tables.py b/backend/src/kwai/modules/teams/repositories/_tables.py index 8ba5ba92..d6a8cca1 100644 --- a/backend/src/kwai/modules/teams/repositories/_tables.py +++ b/backend/src/kwai/modules/teams/repositories/_tables.py @@ -36,7 +36,7 @@ def persist(cls, team: TeamEntity) -> Self: @dataclass(kw_only=True, frozen=True, slots=True) -class TeamMemberRow(TableRow): +class MemberRow(TableRow): """Represents a row of the members table used for a team member.""" __table_name__ = "judo_members" @@ -49,7 +49,7 @@ class TeamMemberRow(TableRow): @dataclass(kw_only=True, frozen=True, slots=True) -class TeamMemberPersonRow(TableRow): +class MemberPersonRow(TableRow): """Represents a row of the persons table used for a team member.""" __table_name__ = "persons" @@ -63,7 +63,7 @@ class TeamMemberPersonRow(TableRow): @dataclass(kw_only=True, frozen=True, slots=True) -class TeamMembersRow(TableRow): +class TeamMemberRow(TableRow): """Represents a row of the team members table.""" __table_name__ = "team_members" diff --git a/backend/src/kwai/modules/teams/repositories/team_member_db_repository.py b/backend/src/kwai/modules/teams/repositories/member_db_repository.py similarity index 61% rename from backend/src/kwai/modules/teams/repositories/team_member_db_repository.py rename to backend/src/kwai/modules/teams/repositories/member_db_repository.py index cbe4d919..b42639ce 100644 --- a/backend/src/kwai/modules/teams/repositories/team_member_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/member_db_repository.py @@ -16,20 +16,23 @@ CountryRow, ) from kwai.modules.teams.domain.team_member import MemberEntity, MemberIdentifier -from kwai.modules.teams.repositories._tables import TeamMemberPersonRow, TeamMemberRow -from kwai.modules.teams.repositories.team_member_repository import ( - TeamMemberNotFoundException, - TeamMemberQuery, - TeamMemberRepository, +from kwai.modules.teams.repositories._tables import ( + MemberPersonRow, + MemberRow, +) +from kwai.modules.teams.repositories.member_repository import ( + MemberNotFoundException, + MemberQuery, + MemberRepository, ) @dataclass(kw_only=True, frozen=True, slots=True) -class TeamMemberQueryRow(JoinedTableRow): - """A data transfer object for the team member query.""" +class MemberQueryRow(JoinedTableRow): + """A data transfer object for the member query.""" - member: TeamMemberRow - person: TeamMemberPersonRow + member: MemberRow + person: MemberPersonRow country: CountryRow def create_entity(self) -> MemberEntity: @@ -48,67 +51,65 @@ def create_entity(self) -> MemberEntity: ) -class TeamMemberDbQuery(TeamMemberQuery, DatabaseQuery): +class MemberDbQuery(MemberQuery, DatabaseQuery): """A team member query for a database.""" def __init__(self, database: Database): super().__init__(database) def init(self): - self._query.from_(TeamMemberRow.__table_name__).inner_join( - TeamMemberPersonRow.__table_name__, - on(TeamMemberPersonRow.column("id"), TeamMemberRow.column("person_id")), + self._query.from_(MemberRow.__table_name__).inner_join( + MemberPersonRow.__table_name__, + on(MemberPersonRow.column("id"), MemberRow.column("person_id")), ).inner_join( CountryRow.__table_name__, - on(CountryRow.column("id"), TeamMemberPersonRow.column("nationality_id")), + on(CountryRow.column("id"), MemberPersonRow.column("nationality_id")), ) @property def columns(self): - return TeamMemberQueryRow.get_aliases() + return MemberQueryRow.get_aliases() def count_column(self): - return TeamMemberRow.column("id") + return MemberRow.column("id") def find_by_id(self, id_: MemberIdentifier) -> Self: - self._query.and_where(TeamMemberRow.field("id").eq(id_.value)) + self._query.and_where(MemberRow.field("id").eq(id_.value)) return self def find_by_birthdate(self, start_date: Date, end_date: Date | None = None) -> Self: if end_date is None: - self._query.and_where( - TeamMemberPersonRow.field("birthdate").gte(start_date) - ) + self._query.and_where(MemberPersonRow.field("birthdate").gte(start_date)) else: self._query.and_where( - TeamMemberPersonRow.field("birthdate").between(start_date, end_date) + MemberPersonRow.field("birthdate").between(start_date, end_date) ) return self -class TeamMemberDbRepository(TeamMemberRepository): - """A team member repository for a database.""" +class MemberDbRepository(MemberRepository): + """A member repository for a database.""" def __init__(self, database: Database): self._database = database - def create_query(self) -> TeamMemberQuery: - return TeamMemberDbQuery(self._database) + def create_query(self) -> MemberQuery: + return MemberDbQuery(self._database) - async def get(self, query: TeamMemberQuery | None = None) -> MemberEntity: + async def get(self, query: MemberQuery | None = None) -> MemberEntity: team_member_iterator = self.get_all(query) try: return await anext(team_member_iterator) except StopAsyncIteration: - raise TeamMemberNotFoundException("Member not found") from None + raise MemberNotFoundException("Member not found") from None async def get_all( self, - query: TeamMemberQuery | None = None, + query: MemberQuery | None = None, limit: int | None = None, offset: int | None = None, ) -> AsyncGenerator[MemberEntity, None]: query = query or self.create_query() async for row in query.fetch(limit, offset): - yield TeamMemberQueryRow.map(row).create_entity() + yield MemberQueryRow.map(row).create_entity() diff --git a/backend/src/kwai/modules/teams/repositories/team_member_repository.py b/backend/src/kwai/modules/teams/repositories/member_repository.py similarity index 69% rename from backend/src/kwai/modules/teams/repositories/team_member_repository.py rename to backend/src/kwai/modules/teams/repositories/member_repository.py index 9b78120f..8e2e8816 100644 --- a/backend/src/kwai/modules/teams/repositories/team_member_repository.py +++ b/backend/src/kwai/modules/teams/repositories/member_repository.py @@ -1,4 +1,4 @@ -"""Module for defining the team member repository interface.""" +"""Module for defining the member repository interface.""" from abc import ABC, abstractmethod from typing import AsyncGenerator, Self @@ -8,12 +8,12 @@ from kwai.modules.teams.domain.team_member import MemberEntity, MemberIdentifier -class TeamMemberNotFoundException(Exception): - """Raised when a team member does not exist.""" +class MemberNotFoundException(Exception): + """Raised when a member does not exist.""" -class TeamMemberQuery(Query, ABC): - """An interface for a team member query.""" +class MemberQuery(Query, ABC): + """An interface for a member query.""" @abstractmethod def find_by_id(self, id_: MemberIdentifier) -> Self: @@ -26,34 +26,34 @@ def find_by_birthdate(self, start_date: Date, end_date: Date | None = None) -> S raise NotImplementedError -class TeamMemberRepository(ABC): - """An interface for a team member repository.""" +class MemberRepository(ABC): + """An interface for a member repository.""" @abstractmethod - def create_query(self) -> TeamMemberQuery: + def create_query(self) -> MemberQuery: """Create a query for querying team members.""" raise NotImplementedError @abstractmethod - async def get(self, query: TeamMemberQuery | None = None) -> MemberEntity: + async def get(self, query: MemberQuery | None = None) -> MemberEntity: """Return the first returned element of the given query. Args: query: The query to use for getting the first member. Raises: - TeamMemberNotFoundException: If the team member is not found. + MemberNotFoundException: If the member is not found. """ raise NotImplementedError @abstractmethod def get_all( self, - query: TeamMemberQuery | None = None, + query: MemberQuery | None = None, limit: int | None = None, offset: int | None = None, ) -> AsyncGenerator[MemberEntity, None]: - """Return all team members of the given query. + """Return all members of the given query. Args: query: The query to use for getting the members. diff --git a/backend/src/kwai/modules/teams/repositories/team_db_repository.py b/backend/src/kwai/modules/teams/repositories/team_db_repository.py index 0028593c..9a02b78c 100644 --- a/backend/src/kwai/modules/teams/repositories/team_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_db_repository.py @@ -14,9 +14,9 @@ ) from kwai.modules.teams.domain.team import TeamEntity, TeamIdentifier from kwai.modules.teams.repositories._tables import ( - TeamMemberPersonRow, + MemberPersonRow, + MemberRow, TeamMemberRow, - TeamMembersRow, TeamRow, ) from kwai.modules.teams.repositories.team_repository import TeamQuery, TeamRepository @@ -27,7 +27,7 @@ class TeamQueryRow(JoinedTableRow): """A data transfer object for the team query.""" team: TeamRow - team_members: TeamMembersRow + team_members: TeamMemberRow class TeamDbQuery(TeamQuery, DatabaseQuery): @@ -38,17 +38,17 @@ def __init__(self, database: Database): def init(self): self._query.from_(TeamRow.__table_name__).inner_join( - TeamMembersRow.__table_name__, - on(TeamMembersRow.column("team_id"), TeamRow.column("id")), - ).inner_join( TeamMemberRow.__table_name__, - on(TeamMemberRow.column("id"), TeamMembersRow.column("member_id")), + on(TeamMemberRow.column("team_id"), TeamRow.column("id")), + ).inner_join( + MemberRow.__table_name__, + on(MemberRow.column("id"), TeamMemberRow.column("member_id")), ).inner_join( - TeamMemberPersonRow.__table_name__, - on(TeamMemberPersonRow.column("id"), TeamMemberRow.column("person_id")), + MemberPersonRow.__table_name__, + on(MemberPersonRow.column("id"), MemberRow.column("person_id")), ).inner_join( CountryRow.__table_name__, - on(CountryRow.column("id"), TeamMemberPersonRow.column("nationality_id")), + on(CountryRow.column("id"), MemberPersonRow.column("nationality_id")), ) @property diff --git a/backend/src/tests/fixtures/teams/team_members.py b/backend/src/tests/fixtures/teams/team_members.py index f5e72ea9..8b48d555 100644 --- a/backend/src/tests/fixtures/teams/team_members.py +++ b/backend/src/tests/fixtures/teams/team_members.py @@ -2,6 +2,7 @@ import pytest from kwai.core.domain.value_objects.traceable_time import TraceableTime +from kwai.modules.teams.domain.team import TeamEntity from kwai.modules.teams.domain.team_member import MemberEntity, TeamMember @@ -26,3 +27,16 @@ def _make_team_member(member: MemberEntity | None = None) -> TeamMember: ) return _make_team_member + + +@pytest.fixture +def make_team_member_in_db(make_team_member, make_member_in_db, make_team_in_db): + """A factory fixture for a team member in a database.""" + + def _make_team_member_in_db( + member: MemberEntity | None = None, team: TeamEntity | None = None + ) -> TeamMember: + member = member or make_team_member(make_member_in_db()) + return member + + return _make_team_member_in_db diff --git a/backend/src/tests/modules/teams/repositories/test_team_member_db_query.py b/backend/src/tests/modules/teams/repositories/test_member_db_query.py similarity index 69% rename from backend/src/tests/modules/teams/repositories/test_team_member_db_query.py rename to backend/src/tests/modules/teams/repositories/test_member_db_query.py index 16203c33..fea8016e 100644 --- a/backend/src/tests/modules/teams/repositories/test_team_member_db_query.py +++ b/backend/src/tests/modules/teams/repositories/test_member_db_query.py @@ -4,19 +4,19 @@ from kwai.core.db.database import Database from kwai.core.domain.value_objects.date import Date from kwai.modules.teams.domain.team_member import MemberIdentifier -from kwai.modules.teams.repositories.team_member_db_repository import TeamMemberDbQuery -from kwai.modules.teams.repositories.team_member_repository import TeamMemberQuery +from kwai.modules.teams.repositories.member_db_repository import MemberDbQuery +from kwai.modules.teams.repositories.member_repository import MemberQuery pytestmark = pytest.mark.db @pytest.fixture -def query(database: Database) -> TeamMemberQuery: +def query(database: Database) -> MemberQuery: """A fixture for a team member query.""" - return TeamMemberDbQuery(database) + return MemberDbQuery(database) -async def test_filter_by_id(query: TeamMemberQuery): +async def test_filter_by_id(query: MemberQuery): """Test filtering by id.""" query.find_by_id(MemberIdentifier(1)) try: @@ -25,7 +25,7 @@ async def test_filter_by_id(query: TeamMemberQuery): pytest.fail(f"An exception occurred: {exc}") -async def test_filter_by_birthdate_without_end_date(query: TeamMemberQuery): +async def test_filter_by_birthdate_without_end_date(query: MemberQuery): """Test filtering by birthdate.""" query.find_by_birthdate(Date.create(2015, 1, 1)) try: @@ -34,7 +34,7 @@ async def test_filter_by_birthdate_without_end_date(query: TeamMemberQuery): pytest.fail(f"An exception occurred: {exc}") -async def test_filter_by_birthdate(query: TeamMemberQuery): +async def test_filter_by_birthdate(query: MemberQuery): """Test filtering by birthdate between two dates.""" query.find_by_birthdate(Date.create(2015, 1, 1), Date.create(2015, 1, 31)) try: diff --git a/backend/src/tests/modules/teams/repositories/test_team_member_db_repository.py b/backend/src/tests/modules/teams/repositories/test_member_db_repository.py similarity index 73% rename from backend/src/tests/modules/teams/repositories/test_team_member_db_repository.py rename to backend/src/tests/modules/teams/repositories/test_member_db_repository.py index 78399f81..0e6941db 100644 --- a/backend/src/tests/modules/teams/repositories/test_team_member_db_repository.py +++ b/backend/src/tests/modules/teams/repositories/test_member_db_repository.py @@ -4,30 +4,30 @@ from kwai.core.db.database import Database from kwai.core.domain.value_objects.date import Date from kwai.modules.club.domain.value_objects import Birthdate -from kwai.modules.teams.repositories.team_member_db_repository import ( - TeamMemberDbRepository, +from kwai.modules.teams.repositories.member_db_repository import ( + MemberDbRepository, ) pytestmark = pytest.mark.db async def test_get_all(database: Database, make_member_in_db): - """Test getting all team members.""" + """Test getting all members.""" member = await make_member_in_db() - repo = TeamMemberDbRepository(database) - team_members = {team_member.id: team_member async for team_member in repo.get_all()} - assert team_members is not None - assert member.id in team_members, "The team member should be returned." + repo = MemberDbRepository(database) + members = {member.id: member async for member in repo.get_all()} + assert members is not None + assert member.id in members, "The member should be returned." async def test_get_by_id(database: Database, make_member_in_db): - """Test get team member by its ids.""" + """Test get member by its ids.""" member = await make_member_in_db() - repo = TeamMemberDbRepository(database) + repo = MemberDbRepository(database) query = repo.create_query() query.find_by_id(member.id) - team_member = await repo.get(query) - assert team_member is not None + member = await repo.get(query) + assert member is not None async def test_get_by_birthdate( @@ -54,11 +54,11 @@ async def test_get_by_birthdate( ) ) - repo = TeamMemberDbRepository(database) + repo = MemberDbRepository(database) query = repo.create_query() query.find_by_birthdate(birthdate.date) - team_member = await repo.get(query) - assert team_member is not None + member = await repo.get(query) + assert member is not None async def test_get_by_birthdate_between_dates( @@ -84,10 +84,10 @@ async def test_get_by_birthdate_between_dates( ) ) ) - repo = TeamMemberDbRepository(database) + repo = MemberDbRepository(database) query = repo.create_query() start_date = Date.create(year=1990, month=1, day=1) end_date = Date.create(year=1990, month=12, day=31) query.find_by_birthdate(start_date, end_date) - team_member = await repo.get(query) - assert team_member is not None + member = await repo.get(query) + assert member is not None From 0233980a2a02d740df93db500688d7838f64c604 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 22 Jun 2024 16:30:28 +0200 Subject: [PATCH 119/410] refactor: add CountryRow to _tables.py --- .../modules/teams/repositories/_tables.py | 34 ++++++ .../repositories/member_db_repository.py | 4 +- .../repositories/team_member_db_query.py | 105 ++++++++++++++++++ 3 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 backend/src/kwai/modules/teams/repositories/team_member_db_query.py diff --git a/backend/src/kwai/modules/teams/repositories/_tables.py b/backend/src/kwai/modules/teams/repositories/_tables.py index d6a8cca1..c8469dc7 100644 --- a/backend/src/kwai/modules/teams/repositories/_tables.py +++ b/backend/src/kwai/modules/teams/repositories/_tables.py @@ -3,6 +3,7 @@ from typing import Self from kwai.core.db.table_row import TableRow +from kwai.modules.club.domain.country import CountryEntity, CountryIdentifier from kwai.modules.teams.domain.team import TeamEntity @@ -73,3 +74,36 @@ class TeamMemberRow(TableRow): active: int created_at: datetime updated_at: datetime | None + + +@dataclass(kw_only=True, frozen=True, slots=True) +class CountryRow(TableRow): + """Represent a row of the countries table. + + Attributes: + id: The id of the country. + iso_2: The ISO 2 code of the country. + iso_3: The ISO 3 code of the country. + """ + + __table_name__ = "countries" + + id: int | None = None + iso_2: str + iso_3: str + name: str + created_at: datetime + updated_at: datetime | None + + def create_country(self) -> CountryEntity: + """Create a Country value object from the row. + + Returns: + A country value object. + """ + return CountryEntity( + id_=CountryIdentifier(self.id), + iso_2=self.iso_2, + iso_3=self.iso_3, + name=self.name, + ) diff --git a/backend/src/kwai/modules/teams/repositories/member_db_repository.py b/backend/src/kwai/modules/teams/repositories/member_db_repository.py index b42639ce..aacb4be5 100644 --- a/backend/src/kwai/modules/teams/repositories/member_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/member_db_repository.py @@ -12,11 +12,9 @@ from kwai.core.domain.value_objects.name import Name from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.club.domain.value_objects import Birthdate, Gender, License -from kwai.modules.club.repositories._tables import ( - CountryRow, -) from kwai.modules.teams.domain.team_member import MemberEntity, MemberIdentifier from kwai.modules.teams.repositories._tables import ( + CountryRow, MemberPersonRow, MemberRow, ) diff --git a/backend/src/kwai/modules/teams/repositories/team_member_db_query.py b/backend/src/kwai/modules/teams/repositories/team_member_db_query.py new file mode 100644 index 00000000..3a281150 --- /dev/null +++ b/backend/src/kwai/modules/teams/repositories/team_member_db_query.py @@ -0,0 +1,105 @@ +"""Module that defines a database query for team members.""" + +from collections import defaultdict +from dataclasses import dataclass +from typing import Self + +from sql_smith.functions import on + +from kwai.core.db.database_query import DatabaseQuery +from kwai.core.db.table_row import JoinedTableRow +from kwai.core.domain.value_objects.date import Date +from kwai.core.domain.value_objects.name import Name +from kwai.core.domain.value_objects.unique_id import UniqueId +from kwai.modules.club.domain.value_objects import Birthdate, Gender, License +from kwai.modules.teams.domain.team import TeamIdentifier +from kwai.modules.teams.domain.team_member import ( + MemberEntity, + MemberIdentifier, + TeamMember, +) +from kwai.modules.teams.repositories._tables import ( + CountryRow, + MemberPersonRow, + MemberRow, + TeamMemberRow, +) + + +@dataclass(frozen=True, kw_only=True, slots=True) +class TeamMemberQueryRow(JoinedTableRow): + """A data transfer object for the team member query.""" + + team_member: TeamMemberRow + member: MemberRow + person: MemberPersonRow + country: CountryRow + + def create_team_member(self) -> TeamMember: + """Create a team member from a row.""" + return TeamMember( + active=self.team_member.active, + member=MemberEntity( + id_=MemberIdentifier(self.member.id), + uuid=UniqueId.create_from_string(self.member.uuid), + name=Name( + first_name=self.person.firstname, last_name=self.person.lastname + ), + license=License( + number=self.member.license, + end_date=Date.create_from_date(self.member.license_end_date), + ), + birthdate=Birthdate(Date.create_from_date(self.person.birthdate)), + gender=Gender(self.person.gender), + nationality=self.country.create_country(), + ), + ) + + +class TeamMemberDbQuery(DatabaseQuery): + """A database query for getting team members.""" + + def init(self): + self._query.from_(TeamMemberRow.__table_name__).left_join( + MemberRow.__table_name__, + on(TeamMemberRow.column("member_id"), MemberRow.column("id")), + ).join( + MemberPersonRow.__table_name__, + on(MemberRow.column("person_id"), MemberPersonRow.column("id")), + ).inner_join( + CountryRow.__table_name__, + on(CountryRow.column("id"), MemberPersonRow.column("nationality_id")), + ) + + @property + def columns(self): + return TeamMemberQueryRow.get_aliases() + + def filter_by_teams(self, *ids: TeamIdentifier) -> Self: + """Filter by teams. + + Only the rows that belong to the teams with the given ids, will be returned. + """ + unpacked_ids = tuple(i.value for i in ids) + self._query.and_where(TeamMemberRow.field("team_id").in_(*unpacked_ids)) + return self + + async def fetch_team_members(self) -> dict[TeamIdentifier, list[TeamMember]]: + """Fetch team members. + + A specialized fetch method that already transforms the rows into TeamMember + objects. + + Returns: + A dictionary that contains the list of team members for each team. + The key is the identifier of the team. + """ + result: dict[TeamIdentifier, list[TeamMember]] = defaultdict(list) + + async for row in self.fetch(): + team_member_row = TeamMemberQueryRow.map(row) + result[TeamIdentifier(team_member_row.team_member.team_id)].append( + team_member_row.create_team_member() + ) + + return result From 87a30719e62baedbd107ea4296bcaaea0f333821 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 22 Jun 2024 16:49:27 +0200 Subject: [PATCH 120/410] fix: add missing fields for team member --- .../modules/teams/repositories/team_member_db_query.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/src/kwai/modules/teams/repositories/team_member_db_query.py b/backend/src/kwai/modules/teams/repositories/team_member_db_query.py index 3a281150..8935e106 100644 --- a/backend/src/kwai/modules/teams/repositories/team_member_db_query.py +++ b/backend/src/kwai/modules/teams/repositories/team_member_db_query.py @@ -10,6 +10,8 @@ from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.value_objects.date import Date from kwai.core.domain.value_objects.name import Name +from kwai.core.domain.value_objects.timestamp import Timestamp +from kwai.core.domain.value_objects.traceable_time import TraceableTime from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.club.domain.value_objects import Birthdate, Gender, License from kwai.modules.teams.domain.team import TeamIdentifier @@ -38,7 +40,7 @@ class TeamMemberQueryRow(JoinedTableRow): def create_team_member(self) -> TeamMember: """Create a team member from a row.""" return TeamMember( - active=self.team_member.active, + active=self.team_member.active == 1, member=MemberEntity( id_=MemberIdentifier(self.member.id), uuid=UniqueId.create_from_string(self.member.uuid), @@ -53,6 +55,10 @@ def create_team_member(self) -> TeamMember: gender=Gender(self.person.gender), nationality=self.country.create_country(), ), + traceable_time=TraceableTime( + created_at=Timestamp(self.team_member.created_at), + updated_at=Timestamp(self.team_member.updated_at), + ), ) From 5a5d89b4bf26493ae625e2a736d855ee4d036b94 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 22 Jun 2024 16:52:49 +0200 Subject: [PATCH 121/410] tests: add test for TeamMemberDbQuery --- .../repositories/test_team_member_db_query.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 backend/src/tests/modules/teams/repositories/test_team_member_db_query.py diff --git a/backend/src/tests/modules/teams/repositories/test_team_member_db_query.py b/backend/src/tests/modules/teams/repositories/test_team_member_db_query.py new file mode 100644 index 00000000..33428a3a --- /dev/null +++ b/backend/src/tests/modules/teams/repositories/test_team_member_db_query.py @@ -0,0 +1,21 @@ +"""Module for testing the TeamMemberDbQuery class.""" + +import pytest +from kwai.core.db.database import Database +from kwai.modules.teams.domain.team import TeamIdentifier +from kwai.modules.teams.repositories.team_member_db_query import TeamMemberDbQuery + + +@pytest.fixture +def query(database: Database) -> TeamMemberDbQuery: + """A fixture for a team member database query.""" + return TeamMemberDbQuery(database) + + +async def test_filter_by_teams(query: TeamMemberDbQuery): + """Test filter by teams.""" + query.filter_by_teams(TeamIdentifier(1)) + try: + await query.fetch_team_members() + except Exception as exc: + pytest.fail(f"An exception occurred: f{exc}") From c92a613ca3b0a010b628fb889f680e744064a2ba Mon Sep 17 00:00:00 2001 From: zumuta Date: Sun, 23 Jun 2024 15:51:31 +0200 Subject: [PATCH 122/410] feat: add __str__ and __repr__ --- backend/src/kwai/modules/teams/domain/team_member.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/backend/src/kwai/modules/teams/domain/team_member.py b/backend/src/kwai/modules/teams/domain/team_member.py index 1227880f..8b98ad2d 100644 --- a/backend/src/kwai/modules/teams/domain/team_member.py +++ b/backend/src/kwai/modules/teams/domain/team_member.py @@ -14,9 +14,9 @@ class MemberEntity(Entity[MemberIdentifier]): - """A team member entity. + """A member entity. - A team member entity is an entity which holds specific information of a member + A member entity is an entity which holds specific information of a member that can be used for a member of a team. """ @@ -39,6 +39,14 @@ def __init__( self._nationality = nationality self._gender = gender + def __str__(self) -> str: + """Return a string of this entity.""" + return f"{self._uuid} - {self._name}" + + def __repr__(self) -> str: + """Return a representation of this entity.""" + return f"<{self.__class__.__name__} id={self.id}, uuid={self.uuid}, name={self.name}>" + @property def name(self) -> Name: """Return the name.""" From 8e4e54b9638d14c17fe5f0e27a978da1db2cbdc8 Mon Sep 17 00:00:00 2001 From: zumuta Date: Thu, 27 Jun 2024 21:48:53 +0200 Subject: [PATCH 123/410] feat: add __repr__ and __str__ --- backend/src/kwai/modules/teams/domain/team.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/backend/src/kwai/modules/teams/domain/team.py b/backend/src/kwai/modules/teams/domain/team.py index 806e5b3b..500add4d 100644 --- a/backend/src/kwai/modules/teams/domain/team.py +++ b/backend/src/kwai/modules/teams/domain/team.py @@ -28,6 +28,14 @@ def __init__( self._members = [] if members is None else members.copy() self._traceable_time = traceable_time or TraceableTime() + def __str__(self): + """Return string representation of the team entity.""" + return f"" + + def __repr__(self): + """Return representation of the team entity.""" + return f"<{self.__class__.__name__} id={self.id} name={self.name!r}>" + @property def name(self) -> str: """Return the name of the team.""" From ac71e2f554c48f301588ed50b0654b9630ab7fc5 Mon Sep 17 00:00:00 2001 From: zumuta Date: Thu, 27 Jun 2024 21:49:46 +0200 Subject: [PATCH 124/410] feat: process team members --- .../modules/teams/repositories/_tables.py | 24 +++++- .../teams/repositories/team_db_repository.py | 75 ++++++++++++++++--- .../repositories/test_team_db_repository.py | 11 +++ 3 files changed, 99 insertions(+), 11 deletions(-) diff --git a/backend/src/kwai/modules/teams/repositories/_tables.py b/backend/src/kwai/modules/teams/repositories/_tables.py index c8469dc7..2e97c368 100644 --- a/backend/src/kwai/modules/teams/repositories/_tables.py +++ b/backend/src/kwai/modules/teams/repositories/_tables.py @@ -3,8 +3,11 @@ from typing import Self from kwai.core.db.table_row import TableRow +from kwai.core.domain.value_objects.timestamp import Timestamp +from kwai.core.domain.value_objects.traceable_time import TraceableTime from kwai.modules.club.domain.country import CountryEntity, CountryIdentifier -from kwai.modules.teams.domain.team import TeamEntity +from kwai.modules.teams.domain.team import TeamEntity, TeamIdentifier +from kwai.modules.teams.domain.team_member import MemberEntity, TeamMember @dataclass(kw_only=True, frozen=True, slots=True) @@ -22,6 +25,15 @@ class TeamRow(TableRow): created_at: datetime updated_at: datetime | None + def create_entity(self, team_members: list[TeamMember]) -> TeamEntity: + return TeamEntity( + id_=TeamIdentifier(self.id), + name=self.name, + active=self.active == 1, + remark=self.remark, + members=team_members, + ) + @classmethod def persist(cls, team: TeamEntity) -> Self: return cls( @@ -75,6 +87,16 @@ class TeamMemberRow(TableRow): created_at: datetime updated_at: datetime | None + def create_team_member(self, member: MemberEntity): + return TeamMember( + active=True if self.active == 1 else False, + member=member, + traceable_time=TraceableTime( + created_at=Timestamp(self.created_at), + updated_at=Timestamp(self.updated_at), + ), + ) + @dataclass(kw_only=True, frozen=True, slots=True) class CountryRow(TableRow): diff --git a/backend/src/kwai/modules/teams/repositories/team_db_repository.py b/backend/src/kwai/modules/teams/repositories/team_db_repository.py index 9a02b78c..223bb1b3 100644 --- a/backend/src/kwai/modules/teams/repositories/team_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_db_repository.py @@ -1,7 +1,7 @@ """Module that implements a team repository for a database.""" from dataclasses import dataclass -from typing import AsyncGenerator, Self +from typing import Any, AsyncGenerator, Self from sql_smith.functions import on @@ -9,11 +9,15 @@ from kwai.core.db.database_query import DatabaseQuery from kwai.core.db.table_row import JoinedTableRow from kwai.core.domain.entity import Entity -from kwai.modules.club.repositories._tables import ( - CountryRow, -) +from kwai.core.domain.value_objects.date import Date +from kwai.core.domain.value_objects.name import Name +from kwai.core.domain.value_objects.unique_id import UniqueId +from kwai.core.functions import async_groupby +from kwai.modules.club.domain.value_objects import Birthdate, Gender, License from kwai.modules.teams.domain.team import TeamEntity, TeamIdentifier +from kwai.modules.teams.domain.team_member import MemberEntity, MemberIdentifier from kwai.modules.teams.repositories._tables import ( + CountryRow, MemberPersonRow, MemberRow, TeamMemberRow, @@ -23,11 +27,54 @@ @dataclass(kw_only=True, frozen=True, slots=True) -class TeamQueryRow(JoinedTableRow): +class MemberPersonCountryMixin: + """Dataclass for a member related row.""" + + member: MemberRow + member_person: MemberPersonRow + country: CountryRow + + def create_member_entity(self) -> MemberEntity: + """Create a member entity from a row.""" + return MemberEntity( + id_=MemberIdentifier(self.member.id), + name=Name( + first_name=self.member_person.firstname, + last_name=self.member_person.lastname, + ), + license=License( + number=self.member.license, + end_date=Date.create_from_date(self.member.license_end_date), + ), + birthdate=Birthdate( + date=Date.create_from_date(self.member_person.birthdate) + ), + nationality=self.country.create_country(), + gender=Gender(self.member_person.gender), + uuid=UniqueId.create_from_string(self.member.uuid), + ) + + +@dataclass(kw_only=True, frozen=True, slots=True) +class TeamQueryRow(MemberPersonCountryMixin, JoinedTableRow): """A data transfer object for the team query.""" team: TeamRow - team_members: TeamMemberRow + team_member: TeamMemberRow + + @classmethod + def create_entity(cls, rows: list[dict[str, Any]]) -> TeamEntity: + """Create a team entity from a group of rows.""" + team_query_row = cls.map(rows[0]) + team_members = [] + for row in rows: + mapped_row = cls.map(row) + team_members.append( + mapped_row.team_member.create_team_member( + mapped_row.create_member_entity() + ) + ) + return team_query_row.team.create_entity(team_members) class TeamDbQuery(TeamQuery, DatabaseQuery): @@ -53,7 +100,7 @@ def init(self): @property def columns(self): - pass + return TeamQueryRow.get_aliases() def find_by_id(self, id_: TeamIdentifier) -> Self: pass @@ -63,18 +110,26 @@ class TeamDbRepository(TeamRepository): """A team repository for a database.""" def create_query(self) -> TeamQuery: - pass + return TeamDbQuery(self._database) async def get(self, query: TeamQuery | None = None) -> TeamEntity: pass - def get_all( + async def get_all( self, query: TeamQuery | None = None, limit: int | None = None, offset: int | None = None, ) -> AsyncGenerator[TeamEntity, None]: - pass + if query is None: + query = self.create_query() + + group_by_column = "team_id" + row_iterator = query.fetch(limit=limit, offset=offset) + async for _, group in async_groupby( + row_iterator, key=lambda row: row[group_by_column] + ): + yield TeamQueryRow.create_entity(group) def __init__(self, database: Database): self._database = database diff --git a/backend/src/tests/modules/teams/repositories/test_team_db_repository.py b/backend/src/tests/modules/teams/repositories/test_team_db_repository.py index 54658177..3d343ae0 100644 --- a/backend/src/tests/modules/teams/repositories/test_team_db_repository.py +++ b/backend/src/tests/modules/teams/repositories/test_team_db_repository.py @@ -1,6 +1,8 @@ """Module for testing the team db repository.""" import pytest +from kwai.core.db.database import Database +from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository pytestmark = pytest.mark.db @@ -9,3 +11,12 @@ async def test_create_team(make_team_in_db): """Test creating a team in the database.""" team = await make_team_in_db() assert team is not None, "There should be a team in the database." + + +async def test_get_all_teams(database: Database): + """Test getting all teams in the database.""" + teams_iterator = TeamDbRepository(database).get_all() + assert teams_iterator is not None, "There should be a team in the database." + + async for team in teams_iterator: + print(team) From 5ac198a476bb559f93dbfd97e59bba0b1d6d6331 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 28 Jun 2024 17:29:10 +0200 Subject: [PATCH 125/410] refactor: move JsonApiPresenter to core --- backend/src/kwai/api/v1/club/presenters.py | 13 +------------ backend/src/kwai/core/json_api.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/backend/src/kwai/api/v1/club/presenters.py b/backend/src/kwai/api/v1/club/presenters.py index 4ff283bd..ba0025d1 100644 --- a/backend/src/kwai/api/v1/club/presenters.py +++ b/backend/src/kwai/api/v1/club/presenters.py @@ -2,7 +2,7 @@ from kwai.api.v1.club.schemas.member import MemberDocument from kwai.core.domain.presenter import AsyncPresenter, IterableResult, Presenter -from kwai.core.json_api import Error, ErrorSource, Meta +from kwai.core.json_api import Error, ErrorSource, JsonApiPresenter, Meta from kwai.modules.club.domain.member import MemberEntity from kwai.modules.club.import_members import ( FailureMemberImportResult, @@ -11,17 +11,6 @@ ) -class JsonApiPresenter[Document]: - """An interface for a presenter that generates a JSON:API document.""" - - def __init__(self): - self._document: Document = None - - def get_document(self) -> Document: - """Return the JSON:API document.""" - return self._document - - class JsonApiMemberPresenter(JsonApiPresenter[MemberDocument], Presenter[MemberEntity]): """A presenter that transform a member entity into a JSON:API document.""" diff --git a/backend/src/kwai/core/json_api.py b/backend/src/kwai/core/json_api.py index 5c19eafb..e09d377c 100644 --- a/backend/src/kwai/core/json_api.py +++ b/backend/src/kwai/core/json_api.py @@ -185,3 +185,14 @@ class PaginationModel(BaseModel): offset: int | None = Field(Query(default=None, alias="page[offset]")) limit: int | None = Field(Query(default=None, alias="page[limit]")) + + +class JsonApiPresenter[Document]: + """An interface for a presenter that generates a JSON:API document.""" + + def __init__(self): + self._document: Document = None + + def get_document(self) -> Document: + """Return the JSON:API document.""" + return self._document From a728f36485aa69f11dc1a7178dd4e4080c37db31 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 28 Jun 2024 22:04:54 +0200 Subject: [PATCH 126/410] chore: add __repr__ to Document --- backend/src/kwai/core/json_api.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/backend/src/kwai/core/json_api.py b/backend/src/kwai/core/json_api.py index e09d377c..931e4e10 100644 --- a/backend/src/kwai/core/json_api.py +++ b/backend/src/kwai/core/json_api.py @@ -128,6 +128,16 @@ def resources(self) -> list[T_RESOURCE]: assert isinstance(self.data, list) return self.data + def __repr__(self): + """Return representation of a document.""" + if isinstance(self.data, list): + if len(self.data) > 0: + return f"<{self.__class__.__name__} type={self.data[0].type}[]>" + else: + return f"<{self.__class__.__name__} type=[]>" + else: + return f"<{self.__class__.__name__} type={self.data.type}>" + @classmethod def __get_pydantic_json_schema__( cls, From 355913c352a8490b0344afa3a4d5d2db59ff3025 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 28 Jun 2024 22:05:55 +0200 Subject: [PATCH 127/410] fix: member can be None, when team has no members --- .../modules/teams/repositories/_tables.py | 42 +++++++++---------- .../teams/repositories/team_db_repository.py | 17 +++++--- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/backend/src/kwai/modules/teams/repositories/_tables.py b/backend/src/kwai/modules/teams/repositories/_tables.py index 2e97c368..1b131430 100644 --- a/backend/src/kwai/modules/teams/repositories/_tables.py +++ b/backend/src/kwai/modules/teams/repositories/_tables.py @@ -21,7 +21,7 @@ class TeamRow(TableRow): season_id: int | None team_category_id: int | None active: int - remark: str + remark: str | None created_at: datetime updated_at: datetime | None @@ -30,7 +30,7 @@ def create_entity(self, team_members: list[TeamMember]) -> TeamEntity: id_=TeamIdentifier(self.id), name=self.name, active=self.active == 1, - remark=self.remark, + remark=self.remark or "", members=team_members, ) @@ -54,11 +54,11 @@ class MemberRow(TableRow): __table_name__ = "judo_members" - id: int - uuid: str - license: str - license_end_date: date - person_id: int + id: int | None + uuid: str | None + license: str | None + license_end_date: date | None + person_id: int | None @dataclass(kw_only=True, frozen=True, slots=True) @@ -67,12 +67,12 @@ class MemberPersonRow(TableRow): __table_name__ = "persons" - id: int - firstname: str - lastname: str - gender: int - birthdate: date - nationality_id: int + id: int | None + firstname: str | None + lastname: str | None + gender: int | None + birthdate: date | None + nationality_id: int | None @dataclass(kw_only=True, frozen=True, slots=True) @@ -81,10 +81,10 @@ class TeamMemberRow(TableRow): __table_name__ = "team_members" - team_id: int - member_id: int - active: int - created_at: datetime + team_id: int | None + member_id: int | None + active: int | None + created_at: datetime | None updated_at: datetime | None def create_team_member(self, member: MemberEntity): @@ -111,10 +111,10 @@ class CountryRow(TableRow): __table_name__ = "countries" id: int | None = None - iso_2: str - iso_3: str - name: str - created_at: datetime + iso_2: str | None + iso_3: str | None + name: str | None + created_at: datetime | None updated_at: datetime | None def create_country(self) -> CountryEntity: diff --git a/backend/src/kwai/modules/teams/repositories/team_db_repository.py b/backend/src/kwai/modules/teams/repositories/team_db_repository.py index 223bb1b3..a791303e 100644 --- a/backend/src/kwai/modules/teams/repositories/team_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_db_repository.py @@ -69,6 +69,9 @@ def create_entity(cls, rows: list[dict[str, Any]]) -> TeamEntity: team_members = [] for row in rows: mapped_row = cls.map(row) + if mapped_row.member.id is None: + continue + team_members.append( mapped_row.team_member.create_team_member( mapped_row.create_member_entity() @@ -84,16 +87,16 @@ def __init__(self, database: Database): super().__init__(database) def init(self): - self._query.from_(TeamRow.__table_name__).inner_join( + self._query.from_(TeamRow.__table_name__).left_join( TeamMemberRow.__table_name__, - on(TeamMemberRow.column("team_id"), TeamRow.column("id")), - ).inner_join( + on(TeamRow.column("id"), TeamMemberRow.column("team_id")), + ).left_join( MemberRow.__table_name__, on(MemberRow.column("id"), TeamMemberRow.column("member_id")), - ).inner_join( + ).left_join( MemberPersonRow.__table_name__, on(MemberPersonRow.column("id"), MemberRow.column("person_id")), - ).inner_join( + ).left_join( CountryRow.__table_name__, on(CountryRow.column("id"), MemberPersonRow.column("nationality_id")), ) @@ -102,6 +105,10 @@ def init(self): def columns(self): return TeamQueryRow.get_aliases() + @property + def count_column(self) -> str: + return TeamRow.column("id") + def find_by_id(self, id_: TeamIdentifier) -> Self: pass From c8f5b551ae10c25abf57facd6e09d5e2f1ec1149 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 28 Jun 2024 22:06:20 +0200 Subject: [PATCH 128/410] feat: implement Get Teams use case --- backend/src/kwai/modules/teams/get_teams.py | 25 ++++++++++---- .../src/tests/modules/teams/test_get_teams.py | 34 +++++++++++++++++++ 2 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 backend/src/tests/modules/teams/test_get_teams.py diff --git a/backend/src/kwai/modules/teams/get_teams.py b/backend/src/kwai/modules/teams/get_teams.py index ce584722..5bb7d91b 100644 --- a/backend/src/kwai/modules/teams/get_teams.py +++ b/backend/src/kwai/modules/teams/get_teams.py @@ -2,26 +2,39 @@ from dataclasses import dataclass -from kwai.core.domain.presenter import Presenter +from kwai.core.domain.presenter import AsyncPresenter, IterableResult from kwai.modules.teams.domain.team import TeamEntity -from kwai.modules.training.teams.team_repository import TeamRepository +from kwai.modules.teams.repositories.team_repository import TeamRepository @dataclass(kw_only=True, frozen=True, slots=True) class GetTeamsCommand: """Input for the use case 'Get Teams'.""" - offset: int - limit: int + offset: int | None = None + limit: int | None = None class GetTeams: """Implement the use case 'Get Teams'.""" - def __init__(self, team_repo: TeamRepository, presenter: Presenter[TeamEntity]): + def __init__( + self, + team_repo: TeamRepository, + presenter: AsyncPresenter[IterableResult[TeamEntity]], + ): """Initialize the use case.""" self._team_repo = team_repo self._presenter = presenter - def execute(self, command: GetTeamsCommand) -> None: + async def execute(self, command: GetTeamsCommand) -> None: """Execute the use case.""" + query = self._team_repo.create_query() + await self._presenter.present( + IterableResult( + count=await query.count(), + limit=command.limit, + offset=command.offset, + iterator=self._team_repo.get_all(query, command.offset, command.limit), + ) + ) diff --git a/backend/src/tests/modules/teams/test_get_teams.py b/backend/src/tests/modules/teams/test_get_teams.py new file mode 100644 index 00000000..89468733 --- /dev/null +++ b/backend/src/tests/modules/teams/test_get_teams.py @@ -0,0 +1,34 @@ +"""Module for defining tests for the use case 'Get Teams'.""" + +from kwai.core.db.database import Database +from kwai.core.domain.presenter import AsyncPresenter, IterableResult +from kwai.modules.teams.domain.team import TeamEntity +from kwai.modules.teams.get_teams import GetTeams, GetTeamsCommand +from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository + + +class TestPresenter(AsyncPresenter[IterableResult[TeamEntity]]): + """A dummy presenter for checking the use case result.""" + + def __init__(self): + super().__init__() + self._count = 0 + + @property + def count(self): + """Return the count.""" + return self._count + + async def present(self, use_case_result: IterableResult[TeamEntity]) -> None: + async for _ in use_case_result.iterator: + self._count += 1 + + +async def test_get_teams(database: Database, make_team_in_db): + """Test get teams.""" + await make_team_in_db() + command = GetTeamsCommand() + presenter = TestPresenter() + await GetTeams(TeamDbRepository(database), presenter).execute(command) + print(presenter.count) + assert presenter.count > 0, "There should be at least one team." From e5c2e377ad437aaf2dd847286801262af1e01fec Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 28 Jun 2024 22:06:42 +0200 Subject: [PATCH 129/410] feat: add teams api --- backend/src/kwai/api/app.py | 3 +++ backend/src/kwai/api/v1/teams/api.py | 17 +++++++++++++++-- backend/src/kwai/api/v1/teams/presenters.py | 21 +++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 backend/src/kwai/api/v1/teams/presenters.py diff --git a/backend/src/kwai/api/app.py b/backend/src/kwai/api/app.py index 9871545e..f6be12fb 100644 --- a/backend/src/kwai/api/app.py +++ b/backend/src/kwai/api/app.py @@ -1,4 +1,5 @@ """Module that implements a factory method for a FastAPI application.""" + import os import sys import uuid @@ -14,6 +15,7 @@ from kwai.api.v1.news.api import api_router as news_api_router from kwai.api.v1.pages.api import api_router as pages_api_router from kwai.api.v1.portal.api import api_router as portal_api_router +from kwai.api.v1.teams.api import router as teams_api_router from kwai.api.v1.trainings.api import api_router as training_api_router from kwai.core.settings import LoggerSettings, Settings, get_settings @@ -114,6 +116,7 @@ async def log(request: Request, call_next): app.include_router(portal_api_router, prefix="/api/v1") app.include_router(pages_api_router, prefix="/api/v1") app.include_router(news_api_router, prefix="/api/v1") + app.include_router(teams_api_router, prefix="/api/v1") app.include_router(training_api_router, prefix="/api/v1") app.include_router(club_api_router, prefix="/api/v1") diff --git a/backend/src/kwai/api/v1/teams/api.py b/backend/src/kwai/api/v1/teams/api.py index 28759eb2..ef19841b 100644 --- a/backend/src/kwai/api/v1/teams/api.py +++ b/backend/src/kwai/api/v1/teams/api.py @@ -1,12 +1,25 @@ """Module that defines the teams API.""" -from fastapi import APIRouter +from typing import Annotated +from fastapi import APIRouter, Depends + +from kwai.api.dependencies import create_database +from kwai.api.v1.teams.presenters import JsonApiTeamsPresenter from kwai.api.v1.teams.schemas import TeamDocument +from kwai.core.db.database import Database +from kwai.modules.teams.get_teams import GetTeams, GetTeamsCommand +from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository router = APIRouter(tags=["teams"]) @router.get("/teams") -async def get_teams() -> TeamDocument: +async def get_teams( + database: Annotated[Database, Depends(create_database)], +) -> TeamDocument: """Get all teams of the club.""" + presenter = JsonApiTeamsPresenter() + command = GetTeamsCommand(offset=0, limit=0) + await GetTeams(TeamDbRepository(database), presenter).execute(command) + return presenter.get_document() diff --git a/backend/src/kwai/api/v1/teams/presenters.py b/backend/src/kwai/api/v1/teams/presenters.py new file mode 100644 index 00000000..674de802 --- /dev/null +++ b/backend/src/kwai/api/v1/teams/presenters.py @@ -0,0 +1,21 @@ +"""Module for defining presenters of the teams api.""" + +from kwai.api.v1.teams.schemas import TeamDocument +from kwai.core.domain.presenter import AsyncPresenter, IterableResult +from kwai.core.json_api import JsonApiPresenter, Meta +from kwai.modules.teams.domain.team import TeamEntity + + +class JsonApiTeamsPresenter( + JsonApiPresenter[TeamDocument], AsyncPresenter[IterableResult[TeamEntity]] +): + """A presenter that transforms an iterator of teams into a JSON:API document.""" + + async def present(self, result: IterableResult[TeamEntity]) -> None: + self._document = TeamDocument( + meta=Meta(count=result.count, offset=result.offset, limit=result.limit), + data=[], + ) + async for team in result.iterator: + team_document = TeamDocument.create(team) + self._document.merge(team_document) From 03e703012279df1abe025a527ae46310bcb3d279 Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 2 Jul 2024 21:12:13 +0200 Subject: [PATCH 130/410] docs: add 'containers' --- backend/docs/architecture.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/docs/architecture.md b/backend/docs/architecture.md index caf63a18..f97dbf98 100644 --- a/backend/docs/architecture.md +++ b/backend/docs/architecture.md @@ -19,8 +19,8 @@ outdated, we only need to change these value objects. > domain. Dependency injection containers are only used on the outside. There should not be any magic code in the domain. -So, dependency injection can only be used in the API entry code, the CLI entry code, ... From there on, the dependency -should be passed as an argument (and passing it down should be done using an interface). +So, dependency injection containers can only be used in the API entry code, the CLI entry code, ... From there on, +the dependency should be passed as an argument (and passing it down should be done using an interface). Actors ====== From 3c682cc301ba0ec42023b09a0bc62f5c62e95765 Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 2 Jul 2024 21:28:10 +0200 Subject: [PATCH 131/410] refactor: move some common schemas, resource identifiers, ... --- .../src/kwai/api/v1/club/schemas/contact.py | 7 ++--- .../src/kwai/api/v1/club/schemas/member.py | 2 +- .../src/kwai/api/v1/club/schemas/person.py | 4 +-- .../src/kwai/api/v1/club/schemas/resources.py | 6 ----- backend/src/kwai/api/v1/resources.py | 11 ++++++++ .../{club/schemas/country.py => schemas.py} | 4 +-- backend/src/kwai/api/v1/teams/resources.py | 11 ++++++++ backend/src/kwai/api/v1/teams/schemas.py | 14 +++++----- .../src/tests/api/v1/club/schemas/conftest.py | 22 +--------------- backend/src/tests/api/v1/conftest.py | 26 +++++++++++++++++++ .../test_country.py => test_schemas.py} | 4 +-- 11 files changed, 64 insertions(+), 47 deletions(-) create mode 100644 backend/src/kwai/api/v1/resources.py rename backend/src/kwai/api/v1/{club/schemas/country.py => schemas.py} (87%) create mode 100644 backend/src/kwai/api/v1/teams/resources.py create mode 100644 backend/src/tests/api/v1/conftest.py rename backend/src/tests/api/v1/{club/schemas/test_country.py => test_schemas.py} (82%) diff --git a/backend/src/kwai/api/v1/club/schemas/contact.py b/backend/src/kwai/api/v1/club/schemas/contact.py index 4a2a5fee..60cee1d9 100644 --- a/backend/src/kwai/api/v1/club/schemas/contact.py +++ b/backend/src/kwai/api/v1/club/schemas/contact.py @@ -4,14 +4,11 @@ from pydantic import BaseModel, Field -from kwai.api.v1.club.schemas.country import ( - CountryDocument, - CountryResource, -) from kwai.api.v1.club.schemas.resources import ( ContactResourceIdentifier, - CountryResourceIdentifier, ) +from kwai.api.v1.resources import CountryResourceIdentifier +from kwai.api.v1.schemas import CountryDocument, CountryResource from kwai.core.json_api import Document, Relationship, ResourceData, ResourceMeta from kwai.modules.club.domain.contact import ContactEntity diff --git a/backend/src/kwai/api/v1/club/schemas/member.py b/backend/src/kwai/api/v1/club/schemas/member.py index 347cf311..d9cf468f 100644 --- a/backend/src/kwai/api/v1/club/schemas/member.py +++ b/backend/src/kwai/api/v1/club/schemas/member.py @@ -5,7 +5,6 @@ from pydantic import BaseModel, Field from kwai.api.v1.club.schemas.contact import ContactResource -from kwai.api.v1.club.schemas.country import CountryResource from kwai.api.v1.club.schemas.person import ( PersonDocument, PersonResource, @@ -14,6 +13,7 @@ MemberResourceIdentifier, PersonResourceIdentifier, ) +from kwai.api.v1.schemas import CountryResource from kwai.core.json_api import Document, Relationship, ResourceData, ResourceMeta from kwai.modules.club.domain.member import MemberEntity diff --git a/backend/src/kwai/api/v1/club/schemas/person.py b/backend/src/kwai/api/v1/club/schemas/person.py index 829bfd1c..dc9acaa3 100644 --- a/backend/src/kwai/api/v1/club/schemas/person.py +++ b/backend/src/kwai/api/v1/club/schemas/person.py @@ -5,12 +5,12 @@ from pydantic import BaseModel, Field from kwai.api.v1.club.schemas.contact import ContactDocument, ContactResource -from kwai.api.v1.club.schemas.country import CountryDocument, CountryResource from kwai.api.v1.club.schemas.resources import ( ContactResourceIdentifier, - CountryResourceIdentifier, PersonResourceIdentifier, ) +from kwai.api.v1.resources import CountryResourceIdentifier +from kwai.api.v1.schemas import CountryDocument, CountryResource from kwai.core.json_api import Document, Relationship, ResourceData, ResourceMeta from kwai.modules.club.domain.person import PersonEntity diff --git a/backend/src/kwai/api/v1/club/schemas/resources.py b/backend/src/kwai/api/v1/club/schemas/resources.py index c94f3004..2f3464c2 100644 --- a/backend/src/kwai/api/v1/club/schemas/resources.py +++ b/backend/src/kwai/api/v1/club/schemas/resources.py @@ -23,12 +23,6 @@ class ContactResourceIdentifier(ResourceIdentifier): type: Literal["contacts"] = "contacts" -class CountryResourceIdentifier(ResourceIdentifier): - """A JSON:API resource identifier for a country.""" - - type: Literal["countries"] = "countries" - - class UploadResourceIdentifier(ResourceIdentifier): """A JSON:API resource identifier for a upload.""" diff --git a/backend/src/kwai/api/v1/resources.py b/backend/src/kwai/api/v1/resources.py new file mode 100644 index 00000000..9ecb7e4f --- /dev/null +++ b/backend/src/kwai/api/v1/resources.py @@ -0,0 +1,11 @@ +"""Module that defines common JSON:API resource identifiers.""" + +from typing import Literal + +from kwai.core.json_api import ResourceIdentifier + + +class CountryResourceIdentifier(ResourceIdentifier): + """A JSON:API resource identifier for a country.""" + + type: Literal["countries"] = "countries" diff --git a/backend/src/kwai/api/v1/club/schemas/country.py b/backend/src/kwai/api/v1/schemas.py similarity index 87% rename from backend/src/kwai/api/v1/club/schemas/country.py rename to backend/src/kwai/api/v1/schemas.py index b3a6947d..5d7ce22b 100644 --- a/backend/src/kwai/api/v1/club/schemas/country.py +++ b/backend/src/kwai/api/v1/schemas.py @@ -1,10 +1,10 @@ -"""Module for defining the JSON:API resource for a country.""" +"""Module for defining common JSON:API schemas.""" from typing import Self from pydantic import BaseModel -from kwai.api.v1.club.schemas.resources import CountryResourceIdentifier +from kwai.api.v1.resources import CountryResourceIdentifier from kwai.core.json_api import Document, ResourceData from kwai.modules.club.domain.country import CountryEntity diff --git a/backend/src/kwai/api/v1/teams/resources.py b/backend/src/kwai/api/v1/teams/resources.py new file mode 100644 index 00000000..69814d28 --- /dev/null +++ b/backend/src/kwai/api/v1/teams/resources.py @@ -0,0 +1,11 @@ +"""Module that defines all JSON:API resource identifiers for the team API.""" + +from typing import Literal + +from kwai.core.json_api import ResourceIdentifier + + +class TeamMemberResourceIdentifier(ResourceIdentifier): + """A JSON:API resource identifier for a team member.""" + + type: Literal["team_members"] = "team_members" diff --git a/backend/src/kwai/api/v1/teams/schemas.py b/backend/src/kwai/api/v1/teams/schemas.py index cc7bddf7..525adef6 100644 --- a/backend/src/kwai/api/v1/teams/schemas.py +++ b/backend/src/kwai/api/v1/teams/schemas.py @@ -5,11 +5,9 @@ from pydantic import BaseModel, Field from kwai.api.schemas.resources import TeamResourceIdentifier -from kwai.api.v1.club.schemas.country import CountryDocument, CountryResource -from kwai.api.v1.club.schemas.resources import ( - CountryResourceIdentifier, - MemberResourceIdentifier, -) +from kwai.api.v1.resources import CountryResourceIdentifier +from kwai.api.v1.schemas import CountryDocument, CountryResource +from kwai.api.v1.teams.resources import TeamMemberResourceIdentifier from kwai.core.json_api import Document, Relationship, ResourceData, ResourceMeta from kwai.modules.teams.domain.team import TeamEntity from kwai.modules.teams.domain.team_member import TeamMember @@ -34,7 +32,7 @@ class TeamMemberRelationships(BaseModel): class TeamMemberResource( - MemberResourceIdentifier, + TeamMemberResourceIdentifier, ResourceData[TeamMemberAttributes, TeamMemberRelationships], ): """A JSON:API resource for a team member.""" @@ -87,7 +85,7 @@ class TeamAttributes(BaseModel): class TeamRelationships(BaseModel): """Relationships for a team JSON:API resource.""" - members: Relationship[MemberResourceIdentifier] + members: Relationship[TeamMemberResourceIdentifier] class TeamResource( @@ -117,7 +115,7 @@ def create(cls, team: TeamEntity) -> Self: name=team.name, active=team.is_active, remark=team.remark ), relationships=TeamRelationships( - members=Relationship[MemberResourceIdentifier]( + members=Relationship[TeamMemberResourceIdentifier]( data=team_member_document.resources ) ), diff --git a/backend/src/tests/api/v1/club/schemas/conftest.py b/backend/src/tests/api/v1/club/schemas/conftest.py index 3fb686d7..45b82928 100644 --- a/backend/src/tests/api/v1/club/schemas/conftest.py +++ b/backend/src/tests/api/v1/club/schemas/conftest.py @@ -7,31 +7,11 @@ from kwai.core.domain.value_objects.email_address import EmailAddress from kwai.core.domain.value_objects.name import Name from kwai.modules.club.domain.contact import ContactEntity, ContactIdentifier -from kwai.modules.club.domain.country import CountryEntity, CountryIdentifier +from kwai.modules.club.domain.country import CountryEntity from kwai.modules.club.domain.person import PersonEntity, PersonIdentifier from kwai.modules.club.domain.value_objects import Address, Birthdate, Gender -@pytest.fixture -def country() -> CountryEntity: - """A fixture for a country.""" - return CountryEntity( - id_=CountryIdentifier(1), iso_2="JP", iso_3="JPN", name="Japan" - ) - - -@pytest.fixture -def expected_country_json() -> dict[str, Any]: - """A fixture for a JSON:API resource of a country.""" - return { - "data": { - "id": "1", - "type": "countries", - "attributes": {"iso_2": "JP", "iso_3": "JPN", "name": "Japan"}, - } - } - - @pytest.fixture def contact(country: CountryEntity) -> ContactEntity: """A fixture for a contact entity.""" diff --git a/backend/src/tests/api/v1/conftest.py b/backend/src/tests/api/v1/conftest.py new file mode 100644 index 00000000..c6944908 --- /dev/null +++ b/backend/src/tests/api/v1/conftest.py @@ -0,0 +1,26 @@ +"""Module for defining reusable fixtures.""" + +from typing import Any + +import pytest +from kwai.modules.club.domain.country import CountryEntity, CountryIdentifier + + +@pytest.fixture +def country() -> CountryEntity: + """A fixture for a country.""" + return CountryEntity( + id_=CountryIdentifier(1), iso_2="JP", iso_3="JPN", name="Japan" + ) + + +@pytest.fixture +def expected_country_json() -> dict[str, Any]: + """A fixture for a JSON:API resource of a country.""" + return { + "data": { + "id": "1", + "type": "countries", + "attributes": {"iso_2": "JP", "iso_3": "JPN", "name": "Japan"}, + } + } diff --git a/backend/src/tests/api/v1/club/schemas/test_country.py b/backend/src/tests/api/v1/test_schemas.py similarity index 82% rename from backend/src/tests/api/v1/club/schemas/test_country.py rename to backend/src/tests/api/v1/test_schemas.py index d6175ed1..603eb1e4 100644 --- a/backend/src/tests/api/v1/club/schemas/test_country.py +++ b/backend/src/tests/api/v1/test_schemas.py @@ -1,10 +1,10 @@ -"""Module for testing the country JSON:API resource.""" +"""Module for testing the common JSON:API schemas.""" import json from typing import Any from deepdiff import DeepDiff -from kwai.api.v1.club.schemas.country import CountryDocument +from kwai.api.v1.schemas import CountryDocument from kwai.modules.club.domain.country import CountryEntity From e7163691ec53d3e4625dc7e295107270523dbd28 Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 2 Jul 2024 21:45:37 +0200 Subject: [PATCH 132/410] refactor: use team_members --- backend/src/kwai/api/v1/teams/schemas.py | 4 +- .../src/tests/api/v1/teams/test_schemas.py | 58 ++++++++++++------- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/backend/src/kwai/api/v1/teams/schemas.py b/backend/src/kwai/api/v1/teams/schemas.py index 525adef6..44915176 100644 --- a/backend/src/kwai/api/v1/teams/schemas.py +++ b/backend/src/kwai/api/v1/teams/schemas.py @@ -85,7 +85,7 @@ class TeamAttributes(BaseModel): class TeamRelationships(BaseModel): """Relationships for a team JSON:API resource.""" - members: Relationship[TeamMemberResourceIdentifier] + team_members: Relationship[TeamMemberResourceIdentifier] class TeamResource( @@ -115,7 +115,7 @@ def create(cls, team: TeamEntity) -> Self: name=team.name, active=team.is_active, remark=team.remark ), relationships=TeamRelationships( - members=Relationship[TeamMemberResourceIdentifier]( + team_members=Relationship[TeamMemberResourceIdentifier]( data=team_member_document.resources ) ), diff --git a/backend/src/tests/api/v1/teams/test_schemas.py b/backend/src/tests/api/v1/teams/test_schemas.py index 83d7b418..0bba85cf 100644 --- a/backend/src/tests/api/v1/teams/test_schemas.py +++ b/backend/src/tests/api/v1/teams/test_schemas.py @@ -8,47 +8,61 @@ from kwai.api.v1.teams.schemas import TeamDocument, TeamMemberDocument from kwai.core.domain.value_objects.date import Date from kwai.core.domain.value_objects.name import Name +from kwai.core.domain.value_objects.traceable_time import TraceableTime from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.club.domain.value_objects import Birthdate, Gender, License from kwai.modules.teams.domain.team import TeamEntity, TeamIdentifier -from kwai.modules.teams.domain.team_member import MemberEntity, MemberIdentifier +from kwai.modules.teams.domain.team_member import ( + MemberEntity, + MemberIdentifier, + TeamMember, +) from tests.fixtures.club.countries import * # noqa @pytest.fixture -def team_member(country_japan) -> MemberEntity: +def team_member(country_japan) -> TeamMember: """A fixture for a team member.""" - return MemberEntity( - id_=MemberIdentifier(1), - name=Name(first_name="Jigoro", last_name="Kano"), - uuid=UniqueId.generate(), - license=License(number="1234", end_date=Date.today().add(years=1)), - birthdate=Birthdate(Date.create(year=1860, month=10, day=28)), - gender=Gender.MALE, - nationality=country_japan, + return TeamMember( + active=True, + member=MemberEntity( + id_=MemberIdentifier(1), + name=Name(first_name="Jigoro", last_name="Kano"), + uuid=UniqueId.generate(), + license=License(number="1234", end_date=Date.today().add(years=1)), + birthdate=Birthdate(Date.create(year=1860, month=10, day=28)), + gender=Gender.MALE, + nationality=country_japan, + ), + traceable_time=TraceableTime(), ) @pytest.fixture -def expected_team_member_json(team_member: MemberEntity) -> dict[str, Any]: +def expected_team_member_json(team_member: TeamMember) -> dict[str, Any]: """A fixture for a JSON:API resource of a team member.""" return { "data": { - "id": str(team_member.uuid), - "type": "members", + "id": str(team_member.member.uuid), + "type": "team_members", + "meta": { + "created_at": str(team_member.traceable_time.created_at), + "updated_at": str(team_member.traceable_time.updated_at), + }, "attributes": { + "active": True, "first_name": "Jigoro", "last_name": "Kano", - "gender": team_member.gender.value, - "birthdate": str(team_member.birthdate), - "license_number": team_member.license.number, - "license_end_date": str(team_member.license.end_date), + "gender": team_member.member.gender.value, + "birthdate": str(team_member.member.birthdate), + "license_number": team_member.member.license.number, + "license_end_date": str(team_member.member.license.end_date), }, "relationships": { "nationality": { "data": { - "id": str(team_member.nationality.id), + "id": str(team_member.member.nationality.id), "type": "countries", } } @@ -56,7 +70,7 @@ def expected_team_member_json(team_member: MemberEntity) -> dict[str, Any]: }, "included": [ { - "id": str(team_member.nationality.id), + "id": str(team_member.member.nationality.id), "type": "countries", "attributes": {"iso_2": "JP", "iso_3": "JPN", "name": "Japan"}, } @@ -65,7 +79,7 @@ def expected_team_member_json(team_member: MemberEntity) -> dict[str, Any]: def test_create_team_member_document( - team_member: MemberEntity, expected_team_member_json: dict[str, Any] + team_member: TeamMember, expected_team_member_json: dict[str, Any] ): """Test the creation of a JSON:API document for a team member resource.""" team_member_document = TeamMemberDocument.create(team_member) @@ -76,7 +90,7 @@ def test_create_team_member_document( @pytest.fixture -def team(team_member: MemberEntity) -> TeamEntity: +def team(team_member: TeamMember) -> TeamEntity: """A fixture for a team entity.""" return TeamEntity( id_=TeamIdentifier(1), @@ -94,7 +108,7 @@ def expected_team_json(team: TeamEntity, expected_team_member_json) -> dict[str, "type": "teams", "attributes": {"name": "U11", "remark": "", "active": True}, "relationships": { - "members": { + "team_members": { "data": [ { "id": expected_team_member_json["data"]["id"], From 3d27f3cb4ba4b4acda352c25ad5092ba9b2e02a3 Mon Sep 17 00:00:00 2001 From: zumuta Date: Thu, 4 Jul 2024 18:20:26 +0200 Subject: [PATCH 133/410] feat: implement find_by_id --- .../teams/repositories/team_db_repository.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/backend/src/kwai/modules/teams/repositories/team_db_repository.py b/backend/src/kwai/modules/teams/repositories/team_db_repository.py index a791303e..13765b04 100644 --- a/backend/src/kwai/modules/teams/repositories/team_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_db_repository.py @@ -23,7 +23,11 @@ TeamMemberRow, TeamRow, ) -from kwai.modules.teams.repositories.team_repository import TeamQuery, TeamRepository +from kwai.modules.teams.repositories.team_repository import ( + TeamNotFoundException, + TeamQuery, + TeamRepository, +) @dataclass(kw_only=True, frozen=True, slots=True) @@ -110,7 +114,8 @@ def count_column(self) -> str: return TeamRow.column("id") def find_by_id(self, id_: TeamIdentifier) -> Self: - pass + self._query.and_where(TeamRow.field("id").eq(id_.value)) + return self class TeamDbRepository(TeamRepository): @@ -120,7 +125,11 @@ def create_query(self) -> TeamQuery: return TeamDbQuery(self._database) async def get(self, query: TeamQuery | None = None) -> TeamEntity: - pass + team_iterator = self.get_all(query) + try: + return await anext(team_iterator) + except StopIteration: + raise TeamNotFoundException("Team not found") from None async def get_all( self, From 8cc9316435b35d51f6c7c750c9e691d3ef257a11 Mon Sep 17 00:00:00 2001 From: zumuta Date: Thu, 4 Jul 2024 18:21:24 +0200 Subject: [PATCH 134/410] feat: Get Team use case --- backend/src/kwai/modules/teams/get_team.py | 33 ++++++++++++++++++ .../src/tests/modules/teams/test_get_team.py | 34 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 backend/src/kwai/modules/teams/get_team.py create mode 100644 backend/src/tests/modules/teams/test_get_team.py diff --git a/backend/src/kwai/modules/teams/get_team.py b/backend/src/kwai/modules/teams/get_team.py new file mode 100644 index 00000000..5d5a6724 --- /dev/null +++ b/backend/src/kwai/modules/teams/get_team.py @@ -0,0 +1,33 @@ +"""Module that implements the use case 'Get Team'.""" + +from dataclasses import dataclass + +from kwai.core.domain.presenter import Presenter +from kwai.modules.teams.domain.team import TeamEntity, TeamIdentifier +from kwai.modules.teams.repositories.team_repository import TeamRepository + + +@dataclass(kw_only=True, frozen=True, slots=True) +class GetTeamCommand: + """Input for the use case 'Get Team'.""" + + id: int + + +class GetTeam: + """Implement the use case 'Get Teams'.""" + + def __init__( + self, + team_repo: TeamRepository, + presenter: Presenter[TeamEntity], + ): + """Initialize the use case.""" + self._team_repo = team_repo + self._presenter = presenter + + async def execute(self, command: GetTeamCommand) -> None: + """Execute the use case.""" + query = self._team_repo.create_query() + query.find_by_id(TeamIdentifier(command.id)) + self._presenter.present(await self._team_repo.get(query)) diff --git a/backend/src/tests/modules/teams/test_get_team.py b/backend/src/tests/modules/teams/test_get_team.py new file mode 100644 index 00000000..0214c646 --- /dev/null +++ b/backend/src/tests/modules/teams/test_get_team.py @@ -0,0 +1,34 @@ +"""Module for defining tests for the use case 'Get Teams'.""" + +from kwai.core.db.database import Database +from kwai.core.domain.presenter import Presenter +from kwai.modules.teams.domain.team import TeamEntity +from kwai.modules.teams.get_team import GetTeam, GetTeamCommand +from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository + + +class TestPresenter(Presenter[TeamEntity]): + """A dummy presenter for checking the use case result.""" + + def __init__(self): + super().__init__() + self._entity = None + + @property + def entity(self): + """Return the entity.""" + return self._entity + + def present(self, use_case_result: TeamEntity) -> None: + self._entity = use_case_result + + +async def test_get_teams(database: Database, make_team_in_db): + """Test get teams.""" + team = await make_team_in_db() + print(team) + command = GetTeamCommand(id=team.id.value) + presenter = TestPresenter() + await GetTeam(TeamDbRepository(database), presenter).execute(command) + assert presenter.entity is not None, "The team should exist" + assert presenter.entity.id == team.id, "The team should be found" From 9954cced61e9ece7115162b0ce1f83b062690896 Mon Sep 17 00:00:00 2001 From: zumuta Date: Thu, 4 Jul 2024 18:21:37 +0200 Subject: [PATCH 135/410] feat: get team --- backend/src/kwai/api/v1/teams/api.py | 15 ++++++++++++++- backend/src/kwai/api/v1/teams/presenters.py | 9 ++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/backend/src/kwai/api/v1/teams/api.py b/backend/src/kwai/api/v1/teams/api.py index ef19841b..717fd725 100644 --- a/backend/src/kwai/api/v1/teams/api.py +++ b/backend/src/kwai/api/v1/teams/api.py @@ -5,9 +5,10 @@ from fastapi import APIRouter, Depends from kwai.api.dependencies import create_database -from kwai.api.v1.teams.presenters import JsonApiTeamsPresenter +from kwai.api.v1.teams.presenters import JsonApiTeamPresenter, JsonApiTeamsPresenter from kwai.api.v1.teams.schemas import TeamDocument from kwai.core.db.database import Database +from kwai.modules.teams.get_team import GetTeam, GetTeamCommand from kwai.modules.teams.get_teams import GetTeams, GetTeamsCommand from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository @@ -23,3 +24,15 @@ async def get_teams( command = GetTeamsCommand(offset=0, limit=0) await GetTeams(TeamDbRepository(database), presenter).execute(command) return presenter.get_document() + + +@router.get("/teams/{id}") +async def get_team( + id: int, + database: Annotated[Database, Depends(create_database)], +) -> TeamDocument: + """Get the team with the given id.""" + presenter = JsonApiTeamPresenter() + command = GetTeamCommand(id=id) + await GetTeam(TeamDbRepository(database), presenter).execute(command) + return presenter.get_document() diff --git a/backend/src/kwai/api/v1/teams/presenters.py b/backend/src/kwai/api/v1/teams/presenters.py index 674de802..be1bed86 100644 --- a/backend/src/kwai/api/v1/teams/presenters.py +++ b/backend/src/kwai/api/v1/teams/presenters.py @@ -1,11 +1,18 @@ """Module for defining presenters of the teams api.""" from kwai.api.v1.teams.schemas import TeamDocument -from kwai.core.domain.presenter import AsyncPresenter, IterableResult +from kwai.core.domain.presenter import AsyncPresenter, IterableResult, Presenter from kwai.core.json_api import JsonApiPresenter, Meta from kwai.modules.teams.domain.team import TeamEntity +class JsonApiTeamPresenter(JsonApiPresenter[TeamDocument], Presenter[TeamEntity]): + """A presenter that transform a team entity into a JSON:API document.""" + + def present(self, team: TeamEntity) -> None: + self._document = TeamDocument.create(team) + + class JsonApiTeamsPresenter( JsonApiPresenter[TeamDocument], AsyncPresenter[IterableResult[TeamEntity]] ): From eb5c5ed446b8598e19bc94b14a4994034520ea03 Mon Sep 17 00:00:00 2001 From: zumuta Date: Thu, 4 Jul 2024 20:31:01 +0200 Subject: [PATCH 136/410] refactor: rename find_by_id into filter_by_id --- backend/src/kwai/modules/teams/get_team.py | 2 +- .../src/kwai/modules/teams/repositories/team_db_repository.py | 2 +- backend/src/kwai/modules/teams/repositories/team_repository.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/kwai/modules/teams/get_team.py b/backend/src/kwai/modules/teams/get_team.py index 5d5a6724..9fff9c6c 100644 --- a/backend/src/kwai/modules/teams/get_team.py +++ b/backend/src/kwai/modules/teams/get_team.py @@ -29,5 +29,5 @@ def __init__( async def execute(self, command: GetTeamCommand) -> None: """Execute the use case.""" query = self._team_repo.create_query() - query.find_by_id(TeamIdentifier(command.id)) + query.filter_by_id(TeamIdentifier(command.id)) self._presenter.present(await self._team_repo.get(query)) diff --git a/backend/src/kwai/modules/teams/repositories/team_db_repository.py b/backend/src/kwai/modules/teams/repositories/team_db_repository.py index 13765b04..53c4b344 100644 --- a/backend/src/kwai/modules/teams/repositories/team_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_db_repository.py @@ -113,7 +113,7 @@ def columns(self): def count_column(self) -> str: return TeamRow.column("id") - def find_by_id(self, id_: TeamIdentifier) -> Self: + def filter_by_id(self, id_: TeamIdentifier) -> Self: self._query.and_where(TeamRow.field("id").eq(id_.value)) return self diff --git a/backend/src/kwai/modules/teams/repositories/team_repository.py b/backend/src/kwai/modules/teams/repositories/team_repository.py index dd67d9ca..32658293 100644 --- a/backend/src/kwai/modules/teams/repositories/team_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_repository.py @@ -15,7 +15,7 @@ class TeamQuery(Query, ABC): """An interface for a team query.""" @abstractmethod - def find_by_id(self, id_: TeamIdentifier) -> Self: + def filter_by_id(self, id_: TeamIdentifier) -> Self: """Find a team by its id.""" raise NotImplementedError From 7f7a74ba5fa58677d2f802a74ffa23f8123b8164 Mon Sep 17 00:00:00 2001 From: zumuta Date: Thu, 4 Jul 2024 20:31:51 +0200 Subject: [PATCH 137/410] refactor: rename find methods into filter --- .../kwai/modules/teams/repositories/member_db_repository.py | 6 ++++-- .../kwai/modules/teams/repositories/member_repository.py | 6 ++++-- .../modules/teams/repositories/test_member_db_query.py | 6 +++--- .../modules/teams/repositories/test_member_db_repository.py | 6 +++--- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/backend/src/kwai/modules/teams/repositories/member_db_repository.py b/backend/src/kwai/modules/teams/repositories/member_db_repository.py index aacb4be5..898f2707 100644 --- a/backend/src/kwai/modules/teams/repositories/member_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/member_db_repository.py @@ -71,11 +71,13 @@ def columns(self): def count_column(self): return MemberRow.column("id") - def find_by_id(self, id_: MemberIdentifier) -> Self: + def filter_by_id(self, id_: MemberIdentifier) -> Self: self._query.and_where(MemberRow.field("id").eq(id_.value)) return self - def find_by_birthdate(self, start_date: Date, end_date: Date | None = None) -> Self: + def filter_by_birthdate( + self, start_date: Date, end_date: Date | None = None + ) -> Self: if end_date is None: self._query.and_where(MemberPersonRow.field("birthdate").gte(start_date)) else: diff --git a/backend/src/kwai/modules/teams/repositories/member_repository.py b/backend/src/kwai/modules/teams/repositories/member_repository.py index 8e2e8816..05d802ca 100644 --- a/backend/src/kwai/modules/teams/repositories/member_repository.py +++ b/backend/src/kwai/modules/teams/repositories/member_repository.py @@ -16,12 +16,14 @@ class MemberQuery(Query, ABC): """An interface for a member query.""" @abstractmethod - def find_by_id(self, id_: MemberIdentifier) -> Self: + def filter_by_id(self, id_: MemberIdentifier) -> Self: """Find a team member by its id.""" raise NotImplementedError @abstractmethod - def find_by_birthdate(self, start_date: Date, end_date: Date | None = None) -> Self: + def filter_by_birthdate( + self, start_date: Date, end_date: Date | None = None + ) -> Self: """Find team members by their birthdate.""" raise NotImplementedError diff --git a/backend/src/tests/modules/teams/repositories/test_member_db_query.py b/backend/src/tests/modules/teams/repositories/test_member_db_query.py index fea8016e..489172b4 100644 --- a/backend/src/tests/modules/teams/repositories/test_member_db_query.py +++ b/backend/src/tests/modules/teams/repositories/test_member_db_query.py @@ -18,7 +18,7 @@ def query(database: Database) -> MemberQuery: async def test_filter_by_id(query: MemberQuery): """Test filtering by id.""" - query.find_by_id(MemberIdentifier(1)) + query.filter_by_id(MemberIdentifier(1)) try: await query.fetch_one() except Exception as exc: @@ -27,7 +27,7 @@ async def test_filter_by_id(query: MemberQuery): async def test_filter_by_birthdate_without_end_date(query: MemberQuery): """Test filtering by birthdate.""" - query.find_by_birthdate(Date.create(2015, 1, 1)) + query.filter_by_birthdate(Date.create(2015, 1, 1)) try: await query.fetch_one() except Exception as exc: @@ -36,7 +36,7 @@ async def test_filter_by_birthdate_without_end_date(query: MemberQuery): async def test_filter_by_birthdate(query: MemberQuery): """Test filtering by birthdate between two dates.""" - query.find_by_birthdate(Date.create(2015, 1, 1), Date.create(2015, 1, 31)) + query.filter_by_birthdate(Date.create(2015, 1, 1), Date.create(2015, 1, 31)) try: await query.fetch_one() except Exception as exc: diff --git a/backend/src/tests/modules/teams/repositories/test_member_db_repository.py b/backend/src/tests/modules/teams/repositories/test_member_db_repository.py index 0e6941db..6de9ff96 100644 --- a/backend/src/tests/modules/teams/repositories/test_member_db_repository.py +++ b/backend/src/tests/modules/teams/repositories/test_member_db_repository.py @@ -25,7 +25,7 @@ async def test_get_by_id(database: Database, make_member_in_db): member = await make_member_in_db() repo = MemberDbRepository(database) query = repo.create_query() - query.find_by_id(member.id) + query.filter_by_id(member.id) member = await repo.get(query) assert member is not None @@ -56,7 +56,7 @@ async def test_get_by_birthdate( repo = MemberDbRepository(database) query = repo.create_query() - query.find_by_birthdate(birthdate.date) + query.filter_by_birthdate(birthdate.date) member = await repo.get(query) assert member is not None @@ -88,6 +88,6 @@ async def test_get_by_birthdate_between_dates( query = repo.create_query() start_date = Date.create(year=1990, month=1, day=1) end_date = Date.create(year=1990, month=12, day=31) - query.find_by_birthdate(start_date, end_date) + query.filter_by_birthdate(start_date, end_date) member = await repo.get(query) assert member is not None From 27612a333f1c89054b747982ead6a01fd5e35e4e Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 9 Jul 2024 19:50:28 +0200 Subject: [PATCH 138/410] fix: add delete team members when deleting a team --- .../kwai/modules/teams/repositories/team_db_repository.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/src/kwai/modules/teams/repositories/team_db_repository.py b/backend/src/kwai/modules/teams/repositories/team_db_repository.py index 53c4b344..b4b97343 100644 --- a/backend/src/kwai/modules/teams/repositories/team_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_db_repository.py @@ -3,7 +3,7 @@ from dataclasses import dataclass from typing import Any, AsyncGenerator, Self -from sql_smith.functions import on +from sql_smith.functions import field, on from kwai.core.db.database import Database from kwai.core.db.database_query import DatabaseQuery @@ -157,4 +157,10 @@ async def create(self, team: TeamEntity) -> TeamEntity: return Entity.replace(team, id_=TeamIdentifier(new_team_id)) async def delete(self, team: TeamEntity) -> None: + delete_team_members_query = ( + self._database.create_query_factory() + .delete(TeamMemberRow.__table_name__) + .where(field("team_id").eq(team.id.value)) + ) + await self._database.execute(delete_team_members_query) await self._database.delete(team.id.value, TeamRow.__table_name__) From 2734b8451998497025d89540e8999697beb5e631 Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 9 Jul 2024 20:49:06 +0200 Subject: [PATCH 139/410] fix: catch StopAsyncIteration instead of StopIteration --- .../src/kwai/modules/teams/repositories/team_db_repository.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/kwai/modules/teams/repositories/team_db_repository.py b/backend/src/kwai/modules/teams/repositories/team_db_repository.py index b4b97343..d2f4103c 100644 --- a/backend/src/kwai/modules/teams/repositories/team_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_db_repository.py @@ -127,8 +127,8 @@ def create_query(self) -> TeamQuery: async def get(self, query: TeamQuery | None = None) -> TeamEntity: team_iterator = self.get_all(query) try: - return await anext(team_iterator) - except StopIteration: + await anext(team_iterator) + except StopAsyncIteration: raise TeamNotFoundException("Team not found") from None async def get_all( From f1416d9c7751ad4158f9d9e9e1a7270c478fee9b Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 9 Jul 2024 20:50:30 +0200 Subject: [PATCH 140/410] test: add test for delete team --- .../teams/repositories/test_team_db_repository.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/backend/src/tests/modules/teams/repositories/test_team_db_repository.py b/backend/src/tests/modules/teams/repositories/test_team_db_repository.py index 3d343ae0..5d8530e2 100644 --- a/backend/src/tests/modules/teams/repositories/test_team_db_repository.py +++ b/backend/src/tests/modules/teams/repositories/test_team_db_repository.py @@ -3,6 +3,7 @@ import pytest from kwai.core.db.database import Database from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository +from kwai.modules.teams.repositories.team_repository import TeamNotFoundException pytestmark = pytest.mark.db @@ -17,6 +18,16 @@ async def test_get_all_teams(database: Database): """Test getting all teams in the database.""" teams_iterator = TeamDbRepository(database).get_all() assert teams_iterator is not None, "There should be a team in the database." + assert ( + await anext(teams_iterator) is not None + ), "There should be a team in the database." - async for team in teams_iterator: - print(team) + +async def test_delete_team(database: Database, make_team_in_db): + """Test deleting a team in the database.""" + team_repo = TeamDbRepository(database) + team = await make_team_in_db() + await team_repo.delete(team) + + with pytest.raises(TeamNotFoundException): + await team_repo.get(team_repo.create_query().filter_by_id(team.id)) From 1d16811a48850fb6ed43b706cd8ba64bcf4cd9f3 Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 10 Jul 2024 19:42:59 +0200 Subject: [PATCH 141/410] fix: remove print --- backend/src/tests/modules/teams/test_get_team.py | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/tests/modules/teams/test_get_team.py b/backend/src/tests/modules/teams/test_get_team.py index 0214c646..4ef41f70 100644 --- a/backend/src/tests/modules/teams/test_get_team.py +++ b/backend/src/tests/modules/teams/test_get_team.py @@ -26,7 +26,6 @@ def present(self, use_case_result: TeamEntity) -> None: async def test_get_teams(database: Database, make_team_in_db): """Test get teams.""" team = await make_team_in_db() - print(team) command = GetTeamCommand(id=team.id.value) presenter = TestPresenter() await GetTeam(TeamDbRepository(database), presenter).execute(command) From 8f4a446452d8a92379731f6b1aa7430cab1c825f Mon Sep 17 00:00:00 2001 From: zumuta Date: Thu, 11 Jul 2024 20:13:18 +0200 Subject: [PATCH 142/410] fix: return the entity --- .../src/kwai/modules/teams/repositories/team_db_repository.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/kwai/modules/teams/repositories/team_db_repository.py b/backend/src/kwai/modules/teams/repositories/team_db_repository.py index d2f4103c..ea6a6392 100644 --- a/backend/src/kwai/modules/teams/repositories/team_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_db_repository.py @@ -127,7 +127,7 @@ def create_query(self) -> TeamQuery: async def get(self, query: TeamQuery | None = None) -> TeamEntity: team_iterator = self.get_all(query) try: - await anext(team_iterator) + return await anext(team_iterator) except StopAsyncIteration: raise TeamNotFoundException("Team not found") from None From bc0c5bdb5d4a760602d178b30af690839283f169 Mon Sep 17 00:00:00 2001 From: zumuta Date: Thu, 11 Jul 2024 20:15:45 +0200 Subject: [PATCH 143/410] test: add test for get team --- .../modules/teams/repositories/test_team_db_repository.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/backend/src/tests/modules/teams/repositories/test_team_db_repository.py b/backend/src/tests/modules/teams/repositories/test_team_db_repository.py index 5d8530e2..b12dbe11 100644 --- a/backend/src/tests/modules/teams/repositories/test_team_db_repository.py +++ b/backend/src/tests/modules/teams/repositories/test_team_db_repository.py @@ -14,6 +14,14 @@ async def test_create_team(make_team_in_db): assert team is not None, "There should be a team in the database." +async def test_get_team(database: Database, make_team_in_db): + """Test getting a team from the database.""" + team = await make_team_in_db() + repo = TeamDbRepository(database) + team = repo.get(repo.create_query().filter_by_id(team.id)) + assert team is not None, "There should be a team in the database." + + async def test_get_all_teams(database: Database): """Test getting all teams in the database.""" teams_iterator = TeamDbRepository(database).get_all() From 112290c9c53c114a02641ebbc283c6bd9e579a0d Mon Sep 17 00:00:00 2001 From: zumuta Date: Thu, 11 Jul 2024 20:16:21 +0200 Subject: [PATCH 144/410] feat: add delete team --- backend/src/kwai/modules/teams/delete_team.py | 40 +++++++++++++++++++ .../tests/modules/teams/test_delete_team.py | 18 +++++++++ 2 files changed, 58 insertions(+) create mode 100644 backend/src/kwai/modules/teams/delete_team.py create mode 100644 backend/src/tests/modules/teams/test_delete_team.py diff --git a/backend/src/kwai/modules/teams/delete_team.py b/backend/src/kwai/modules/teams/delete_team.py new file mode 100644 index 00000000..b8e59b95 --- /dev/null +++ b/backend/src/kwai/modules/teams/delete_team.py @@ -0,0 +1,40 @@ +"""Module that defines the use case "Delete Team".""" + +from dataclasses import dataclass + +from kwai.modules.teams.domain.team import TeamIdentifier +from kwai.modules.teams.repositories.team_repository import TeamRepository + + +@dataclass(kw_only=True, frozen=True, slots=True) +class DeleteTeamCommand: + """Input for the use case DeleteTeam.""" + + id: int + + +class DeleteTeam: + """Use case for deleting a team.""" + + def __init__(self, repo: TeamRepository): + """Initialize the use case. + + Args: + repo: A repository for deleting a team. + """ + self._repo = repo + + async def execute(self, command: DeleteTeamCommand) -> None: + """Execute the use case. + + Args: + command: The input for the use case. + + Raises: + TeamNotFoundException: If the team does not exist. + """ + team = await self._repo.get( + self._repo.create_query().filter_by_id(TeamIdentifier(command.id)) + ) + # TODO: check if the team is not attached to one or more trainings... + await self._repo.delete(team) diff --git a/backend/src/tests/modules/teams/test_delete_team.py b/backend/src/tests/modules/teams/test_delete_team.py new file mode 100644 index 00000000..552fad09 --- /dev/null +++ b/backend/src/tests/modules/teams/test_delete_team.py @@ -0,0 +1,18 @@ +"""Module for testing the Delete Team use case.""" + +import pytest +from kwai.core.db.database import Database +from kwai.modules.teams.delete_team import DeleteTeam, DeleteTeamCommand +from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository +from kwai.modules.teams.repositories.team_repository import TeamNotFoundException + + +async def test_delete_team(database: Database, make_team_in_db): + """Test deleting a team.""" + team = await make_team_in_db() + command = DeleteTeamCommand(id=team.id.value) + team_repo = TeamDbRepository(database) + await DeleteTeam(team_repo).execute(command) + + with pytest.raises(TeamNotFoundException): + await team_repo.get(team_repo.create_query().filter_by_id(team.id)) From 4c6b20ef3641fc1c0b3ebdd115e8af70e8ff7763 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 12 Jul 2024 11:52:10 +0200 Subject: [PATCH 145/410] refactor: ruff --- backend/src/tests/api/v1/club/endpoints/test_members.py | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/tests/api/v1/club/endpoints/test_members.py b/backend/src/tests/api/v1/club/endpoints/test_members.py index dbfbeab8..fc95b90c 100644 --- a/backend/src/tests/api/v1/club/endpoints/test_members.py +++ b/backend/src/tests/api/v1/club/endpoints/test_members.py @@ -3,7 +3,6 @@ import pytest from fastapi import status from fastapi.testclient import TestClient - from kwai.core.domain.value_objects.unique_id import UniqueId pytestmark = pytest.mark.api From a05e5c2e90246c35804f5344d49a41af9a8c1617 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 12 Jul 2024 11:52:26 +0200 Subject: [PATCH 146/410] feat: get/delete teams api --- backend/src/kwai/api/v1/teams/api.py | 48 +++++++++++++++++++-- backend/src/kwai/api/v1/teams/presenters.py | 17 +++++++- backend/src/tests/api/v1/teams/conftest.py | 3 ++ backend/src/tests/api/v1/teams/test_api.py | 28 ++++++++++++ 4 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 backend/src/tests/api/v1/teams/conftest.py create mode 100644 backend/src/tests/api/v1/teams/test_api.py diff --git a/backend/src/kwai/api/v1/teams/api.py b/backend/src/kwai/api/v1/teams/api.py index 717fd725..01dc8201 100644 --- a/backend/src/kwai/api/v1/teams/api.py +++ b/backend/src/kwai/api/v1/teams/api.py @@ -2,15 +2,22 @@ from typing import Annotated -from fastapi import APIRouter, Depends +from fastapi import APIRouter, Depends, HTTPException, status -from kwai.api.dependencies import create_database -from kwai.api.v1.teams.presenters import JsonApiTeamPresenter, JsonApiTeamsPresenter -from kwai.api.v1.teams.schemas import TeamDocument +from kwai.api.dependencies import create_database, get_current_user +from kwai.api.v1.teams.presenters import ( + JsonApiTeamMembersPresenter, + JsonApiTeamPresenter, + JsonApiTeamsPresenter, +) +from kwai.api.v1.teams.schemas import TeamDocument, TeamMemberDocument from kwai.core.db.database import Database +from kwai.modules.identity.users.user import UserEntity +from kwai.modules.teams.delete_team import DeleteTeam, DeleteTeamCommand from kwai.modules.teams.get_team import GetTeam, GetTeamCommand from kwai.modules.teams.get_teams import GetTeams, GetTeamsCommand from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository +from kwai.modules.training.teams.team_repository import TeamNotFoundException router = APIRouter(tags=["teams"]) @@ -36,3 +43,36 @@ async def get_team( command = GetTeamCommand(id=id) await GetTeam(TeamDbRepository(database), presenter).execute(command) return presenter.get_document() + + +@router.get("/teams/{id}/members") +async def get_team_members( + id: int, + database: Annotated[Database, Depends(create_database)], +) -> TeamMemberDocument: + """Get the member of the team with the given id.""" + presenter = JsonApiTeamMembersPresenter() + command = GetTeamCommand(id=id) + await GetTeam(TeamDbRepository(database), presenter).execute(command) + return presenter.get_document() + + +@router.delete( + "/teams/{id}", + status_code=status.HTTP_200_OK, + responses={status.HTTP_404_NOT_FOUND: {"description": "Team not found"}}, +) +async def delete_team( + id: int, + database: Annotated[Database, Depends(create_database)], + user: Annotated[UserEntity, Depends(get_current_user)], +): + """Delete the team with the given id.""" + command = DeleteTeamCommand(id=id) + + try: + await DeleteTeam(TeamDbRepository(database)).execute(command) + except TeamNotFoundException as ex: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=str(ex) + ) from ex diff --git a/backend/src/kwai/api/v1/teams/presenters.py b/backend/src/kwai/api/v1/teams/presenters.py index be1bed86..d936a6a4 100644 --- a/backend/src/kwai/api/v1/teams/presenters.py +++ b/backend/src/kwai/api/v1/teams/presenters.py @@ -1,6 +1,6 @@ """Module for defining presenters of the teams api.""" -from kwai.api.v1.teams.schemas import TeamDocument +from kwai.api.v1.teams.schemas import TeamDocument, TeamMemberDocument from kwai.core.domain.presenter import AsyncPresenter, IterableResult, Presenter from kwai.core.json_api import JsonApiPresenter, Meta from kwai.modules.teams.domain.team import TeamEntity @@ -26,3 +26,18 @@ async def present(self, result: IterableResult[TeamEntity]) -> None: async for team in result.iterator: team_document = TeamDocument.create(team) self._document.merge(team_document) + + +class JsonApiTeamMembersPresenter( + JsonApiPresenter[TeamMemberDocument], Presenter[TeamEntity] +): + """A presenter that transforms team members into a JSON:API document.""" + + def present(self, use_case_result: TeamEntity) -> None: + self._document = TeamMemberDocument( + meta=Meta(count=len(use_case_result.members)), + data=[], + ) + for member in use_case_result.members: + team_member_document = TeamMemberDocument.create(member) + self._document.merge(team_member_document) diff --git a/backend/src/tests/api/v1/teams/conftest.py b/backend/src/tests/api/v1/teams/conftest.py new file mode 100644 index 00000000..d610caeb --- /dev/null +++ b/backend/src/tests/api/v1/teams/conftest.py @@ -0,0 +1,3 @@ +"""Module for defining common fixtures for testing the teams endpoints.""" + +from tests.fixtures.teams.teams import * # noqa diff --git a/backend/src/tests/api/v1/teams/test_api.py b/backend/src/tests/api/v1/teams/test_api.py new file mode 100644 index 00000000..bbdd0d27 --- /dev/null +++ b/backend/src/tests/api/v1/teams/test_api.py @@ -0,0 +1,28 @@ +"""Module for testing the teams API.""" + +import pytest +from fastapi import status +from fastapi.testclient import TestClient + +pytestmark = pytest.mark.api + + +async def test_get_team(client: TestClient, make_team_in_db): + """Test /api/v1/teams endpoint for getting a team.""" + team = await make_team_in_db() + response = client.get(f"/api/v1/teams/{team.id}") + assert response.status_code == status.HTTP_200_OK + + +async def test_get_teams(client: TestClient, make_team_in_db): + """Test /api/v1/teams endpoint for getting all teams.""" + await make_team_in_db() + response = client.get("/api/v1/teams") + assert response.status_code == status.HTTP_200_OK + + +async def test_delete_team(secure_client: TestClient, make_team_in_db): + """Test /api/v1/teams endpoint for deleting a team.""" + team = await make_team_in_db() + response = secure_client.delete(f"/api/v1/teams/{team.id}") + assert response.status_code == status.HTTP_200_OK From 33bac52b31b0ef9f98f110c12677eacd35d85c96 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 12 Jul 2024 12:23:53 +0200 Subject: [PATCH 147/410] fix: add pytestmark db --- backend/src/tests/modules/teams/test_delete_team.py | 2 ++ backend/src/tests/modules/teams/test_get_team.py | 3 +++ backend/src/tests/modules/teams/test_get_teams.py | 3 +++ 3 files changed, 8 insertions(+) diff --git a/backend/src/tests/modules/teams/test_delete_team.py b/backend/src/tests/modules/teams/test_delete_team.py index 552fad09..96d7d4e6 100644 --- a/backend/src/tests/modules/teams/test_delete_team.py +++ b/backend/src/tests/modules/teams/test_delete_team.py @@ -6,6 +6,8 @@ from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository from kwai.modules.teams.repositories.team_repository import TeamNotFoundException +pytestmark = pytest.mark.db + async def test_delete_team(database: Database, make_team_in_db): """Test deleting a team.""" diff --git a/backend/src/tests/modules/teams/test_get_team.py b/backend/src/tests/modules/teams/test_get_team.py index 4ef41f70..4e7f6f1b 100644 --- a/backend/src/tests/modules/teams/test_get_team.py +++ b/backend/src/tests/modules/teams/test_get_team.py @@ -1,11 +1,14 @@ """Module for defining tests for the use case 'Get Teams'.""" +import pytest from kwai.core.db.database import Database from kwai.core.domain.presenter import Presenter from kwai.modules.teams.domain.team import TeamEntity from kwai.modules.teams.get_team import GetTeam, GetTeamCommand from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository +pytestmark = pytest.mark.db + class TestPresenter(Presenter[TeamEntity]): """A dummy presenter for checking the use case result.""" diff --git a/backend/src/tests/modules/teams/test_get_teams.py b/backend/src/tests/modules/teams/test_get_teams.py index 89468733..cbd9fe99 100644 --- a/backend/src/tests/modules/teams/test_get_teams.py +++ b/backend/src/tests/modules/teams/test_get_teams.py @@ -1,11 +1,14 @@ """Module for defining tests for the use case 'Get Teams'.""" +import pytest from kwai.core.db.database import Database from kwai.core.domain.presenter import AsyncPresenter, IterableResult from kwai.modules.teams.domain.team import TeamEntity from kwai.modules.teams.get_teams import GetTeams, GetTeamsCommand from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository +pytestmark = pytest.mark.db + class TestPresenter(AsyncPresenter[IterableResult[TeamEntity]]): """A dummy presenter for checking the use case result.""" From 9d0ce123bf4e47abc8ca63f24454021c280a2b5c Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 12 Jul 2024 12:24:22 +0200 Subject: [PATCH 148/410] feat: add create team use case --- backend/src/kwai/modules/teams/create_team.py | 37 ++++++++++++++++++ .../tests/modules/teams/test_create_team.py | 38 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 backend/src/kwai/modules/teams/create_team.py create mode 100644 backend/src/tests/modules/teams/test_create_team.py diff --git a/backend/src/kwai/modules/teams/create_team.py b/backend/src/kwai/modules/teams/create_team.py new file mode 100644 index 00000000..f9e090c6 --- /dev/null +++ b/backend/src/kwai/modules/teams/create_team.py @@ -0,0 +1,37 @@ +"""Module that defines the use case 'Create Team'.""" + +from dataclasses import dataclass + +from kwai.core.domain.presenter import Presenter +from kwai.modules.teams.domain.team import TeamEntity +from kwai.modules.teams.repositories.team_repository import TeamRepository + + +@dataclass(kw_only=True, frozen=True, slots=True) +class CreateTeamCommand: + """Input for the use case 'Create Team'.""" + + name: str + active: bool + remark: str + + +class CreateTeam: + """Use case 'Create Team'.""" + + def __init__(self, team_repo: TeamRepository, presenter: Presenter[TeamEntity]): + """Initialize the use case. + + Args: + team_repo: A repository that creates the team. + presenter: A presenter for a team entity. + """ + self._team_repo = team_repo + self._presenter = presenter + + async def execute(self, command: CreateTeamCommand) -> None: + """Executes the use case.""" + team = TeamEntity( + name=command.name, active=command.active, remark=command.remark + ) + self._presenter.present(await self._team_repo.create(team)) diff --git a/backend/src/tests/modules/teams/test_create_team.py b/backend/src/tests/modules/teams/test_create_team.py new file mode 100644 index 00000000..6e183a66 --- /dev/null +++ b/backend/src/tests/modules/teams/test_create_team.py @@ -0,0 +1,38 @@ +"""Module that tests the Create Team use case.""" + +import pytest +from kwai.core.db.database import Database +from kwai.core.domain.presenter import Presenter +from kwai.modules.teams.create_team import CreateTeam, CreateTeamCommand +from kwai.modules.teams.domain.team import TeamEntity +from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository + +pytestmark = pytest.mark.db + + +class TestPresenter(Presenter[TeamEntity]): + """A dummy presenter for checking the use case result.""" + + def __init__(self): + self._entity = None + + @property + def entity(self) -> TeamEntity: + """Return the entity.""" + return self._entity + + def present(self, use_case_result: TeamEntity) -> None: + self._entity = use_case_result + + +async def test_create_team(database: Database, make_team) -> None: + """Test the use case 'Create Team'.""" + presenter = TestPresenter() + team = make_team() + command = CreateTeamCommand( + name=team.name, + active=team.is_active, + remark=team.remark, + ) + await CreateTeam(TeamDbRepository(database), presenter).execute((command)) + assert presenter.entity is not None, "The team should be created" From 89691079359edbcc4afc64e8e3c1ac64007e916d Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 12 Jul 2024 13:14:23 +0200 Subject: [PATCH 149/410] feat: add create team --- backend/src/kwai/api/v1/teams/api.py | 20 ++++++++++++++++++++ backend/src/tests/api/v1/teams/test_api.py | 17 +++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/backend/src/kwai/api/v1/teams/api.py b/backend/src/kwai/api/v1/teams/api.py index 01dc8201..8627db70 100644 --- a/backend/src/kwai/api/v1/teams/api.py +++ b/backend/src/kwai/api/v1/teams/api.py @@ -12,7 +12,9 @@ ) from kwai.api.v1.teams.schemas import TeamDocument, TeamMemberDocument from kwai.core.db.database import Database +from kwai.core.db.uow import UnitOfWork from kwai.modules.identity.users.user import UserEntity +from kwai.modules.teams.create_team import CreateTeam, CreateTeamCommand from kwai.modules.teams.delete_team import DeleteTeam, DeleteTeamCommand from kwai.modules.teams.get_team import GetTeam, GetTeamCommand from kwai.modules.teams.get_teams import GetTeams, GetTeamsCommand @@ -57,6 +59,24 @@ async def get_team_members( return presenter.get_document() +@router.post("/teams", status_code=status.HTTP_201_CREATED) +async def create_team( + resource: TeamDocument, + database: Annotated[Database, Depends(create_database)], + user: Annotated[UserEntity, Depends(get_current_user)], +) -> TeamDocument: + """Create a new team.""" + command = CreateTeamCommand( + name=resource.data.attributes.name, + active=resource.data.attributes.active, + remark=resource.data.attributes.remark, + ) + team_presenter = JsonApiTeamPresenter() + async with UnitOfWork(database): + await CreateTeam(TeamDbRepository(database), team_presenter).execute(command) + return team_presenter.get_document() + + @router.delete( "/teams/{id}", status_code=status.HTTP_200_OK, diff --git a/backend/src/tests/api/v1/teams/test_api.py b/backend/src/tests/api/v1/teams/test_api.py index bbdd0d27..06927d76 100644 --- a/backend/src/tests/api/v1/teams/test_api.py +++ b/backend/src/tests/api/v1/teams/test_api.py @@ -26,3 +26,20 @@ async def test_delete_team(secure_client: TestClient, make_team_in_db): team = await make_team_in_db() response = secure_client.delete(f"/api/v1/teams/{team.id}") assert response.status_code == status.HTTP_200_OK + + +async def test_create_team(secure_client: TestClient, make_team): + """Test /api/v1/teams endpoint for creating a team.""" + team = make_team() + payload = { + "data": { + "type": "teams", + "attributes": { + "name": team.name, + "active": team.is_active, + "remark": team.remark, + }, + } + } + response = secure_client.post("/api/v1/teams", json=payload) + assert response.status_code == status.HTTP_201_CREATED From e9b746fcd28e57357dbf2d44c451f443dac5d7db Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 12 Jul 2024 13:15:15 +0200 Subject: [PATCH 150/410] fix: use unit of work in delete --- backend/src/kwai/api/v1/teams/api.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/kwai/api/v1/teams/api.py b/backend/src/kwai/api/v1/teams/api.py index 8627db70..08a1a118 100644 --- a/backend/src/kwai/api/v1/teams/api.py +++ b/backend/src/kwai/api/v1/teams/api.py @@ -91,7 +91,8 @@ async def delete_team( command = DeleteTeamCommand(id=id) try: - await DeleteTeam(TeamDbRepository(database)).execute(command) + async with UnitOfWork(database): + await DeleteTeam(TeamDbRepository(database)).execute(command) except TeamNotFoundException as ex: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=str(ex) From 2cbea648ea53ddbab7911e2bf39f4659eb47cc14 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 12 Jul 2024 14:26:04 +0200 Subject: [PATCH 151/410] feat: add update team --- .../teams/repositories/team_db_repository.py | 5 +++++ .../modules/teams/repositories/team_repository.py | 4 ++++ .../teams/repositories/test_team_db_repository.py | 13 +++++++++++++ 3 files changed, 22 insertions(+) diff --git a/backend/src/kwai/modules/teams/repositories/team_db_repository.py b/backend/src/kwai/modules/teams/repositories/team_db_repository.py index ea6a6392..548523fe 100644 --- a/backend/src/kwai/modules/teams/repositories/team_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_db_repository.py @@ -164,3 +164,8 @@ async def delete(self, team: TeamEntity) -> None: ) await self._database.execute(delete_team_members_query) await self._database.delete(team.id.value, TeamRow.__table_name__) + + async def update(self, team: TeamEntity) -> TeamEntity: + await self._database.update( + team.id.value, TeamRow.__table_name__, TeamRow.persist(team) + ) diff --git a/backend/src/kwai/modules/teams/repositories/team_repository.py b/backend/src/kwai/modules/teams/repositories/team_repository.py index 32658293..b3f34899 100644 --- a/backend/src/kwai/modules/teams/repositories/team_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_repository.py @@ -67,3 +67,7 @@ async def create(self, team: TeamEntity) -> TeamEntity: @abstractmethod async def delete(self, team: TeamEntity) -> None: """Delete a team.""" + + @abstractmethod + async def update(self, team: TeamEntity) -> TeamEntity: + """Update a team.""" diff --git a/backend/src/tests/modules/teams/repositories/test_team_db_repository.py b/backend/src/tests/modules/teams/repositories/test_team_db_repository.py index b12dbe11..3e33a038 100644 --- a/backend/src/tests/modules/teams/repositories/test_team_db_repository.py +++ b/backend/src/tests/modules/teams/repositories/test_team_db_repository.py @@ -2,6 +2,7 @@ import pytest from kwai.core.db.database import Database +from kwai.core.domain.entity import Entity from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository from kwai.modules.teams.repositories.team_repository import TeamNotFoundException @@ -39,3 +40,15 @@ async def test_delete_team(database: Database, make_team_in_db): with pytest.raises(TeamNotFoundException): await team_repo.get(team_repo.create_query().filter_by_id(team.id)) + + +async def test_update_team(database: Database, make_team_in_db): + """Test updating a team in the database.""" + team_repo = TeamDbRepository(database) + team = await make_team_in_db() + + team = Entity.replace(team, remark="This is a test.") + await team_repo.update(team) + + team = await team_repo.get(team_repo.create_query().filter_by_id(team.id)) + assert team.remark == "This is a test.", "The team should be updated." From 01653e8be2fd64a36153601d8c4c3730dbd6c6fd Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 12 Jul 2024 14:26:32 +0200 Subject: [PATCH 152/410] fix: add await on get --- .../tests/modules/teams/repositories/test_team_db_repository.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/tests/modules/teams/repositories/test_team_db_repository.py b/backend/src/tests/modules/teams/repositories/test_team_db_repository.py index 3e33a038..24ca8a13 100644 --- a/backend/src/tests/modules/teams/repositories/test_team_db_repository.py +++ b/backend/src/tests/modules/teams/repositories/test_team_db_repository.py @@ -19,7 +19,7 @@ async def test_get_team(database: Database, make_team_in_db): """Test getting a team from the database.""" team = await make_team_in_db() repo = TeamDbRepository(database) - team = repo.get(repo.create_query().filter_by_id(team.id)) + team = await repo.get(repo.create_query().filter_by_id(team.id)) assert team is not None, "There should be a team in the database." From dc82df9cb17d0a2684e61277f7cc2d9d650cbee2 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 12 Jul 2024 14:34:31 +0200 Subject: [PATCH 153/410] test: add TeamPresenter fixture --- backend/src/tests/modules/teams/conftest.py | 34 ++++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/backend/src/tests/modules/teams/conftest.py b/backend/src/tests/modules/teams/conftest.py index 11b8678e..6ea191ce 100644 --- a/backend/src/tests/modules/teams/conftest.py +++ b/backend/src/tests/modules/teams/conftest.py @@ -1,9 +1,35 @@ """Module for common fixtures used for testing code of the club module.""" -from tests.fixtures.club.countries import * # noqa +import pytest +from kwai.core.domain.presenter import Presenter +from kwai.modules.teams.domain.team import TeamEntity + +from tests.fixtures.club.coaches import * # noqa from tests.fixtures.club.contacts import * # noqa -from tests.fixtures.club.persons import * # noqa +from tests.fixtures.club.countries import * # noqa from tests.fixtures.club.members import * # noqa -from tests.fixtures.club.coaches import * # noqa -from tests.fixtures.teams.teams import * # noqa +from tests.fixtures.club.persons import * # noqa from tests.fixtures.teams.team_members import * # noqa +from tests.fixtures.teams.teams import * # noqa + + +class TestPresenter(Presenter[TeamEntity]): + """A dummy presenter for checking the use case result.""" + + def __init__(self): + super().__init__() + self._entity = None + + @property + def entity(self): + """Return the entity.""" + return self._entity + + def present(self, use_case_result: TeamEntity) -> None: + self._entity = use_case_result + + +@pytest.fixture +def team_presenter() -> TestPresenter: + """A fixture for a team presenter.""" + return TestPresenter() From f83602bd00b56d2c97fc51bfe8db58fdb8b125f8 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 12 Jul 2024 14:34:53 +0200 Subject: [PATCH 154/410] test: add test for Update Team use case --- .../tests/modules/teams/test_update_team.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 backend/src/tests/modules/teams/test_update_team.py diff --git a/backend/src/tests/modules/teams/test_update_team.py b/backend/src/tests/modules/teams/test_update_team.py new file mode 100644 index 00000000..c9a51eaa --- /dev/null +++ b/backend/src/tests/modules/teams/test_update_team.py @@ -0,0 +1,23 @@ +"""Module for testing the 'Update Team' use case.""" + +import pytest +from kwai.core.db.database import Database +from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository +from kwai.modules.teams.update_team import UpdateTeam, UpdateTeamCommand + +pytestmark = pytest.mark.db + + +async def test_update_team(database: Database, make_team_in_db, team_presenter): + """Test the use case 'Update Team'.""" + team = await make_team_in_db() + command = UpdateTeamCommand( + id=team.id.value, + name=team.name, + active=team.is_active, + remark="This is a test.", + ) + await UpdateTeam(TeamDbRepository(database), team_presenter).execute(command) + assert ( + team_presenter.entity.remark == "This is a test." + ), "The team should be updated." From 5cad3567f2cb403652ba617cd59497c882ee9a6e Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 12 Jul 2024 14:37:42 +0200 Subject: [PATCH 155/410] refactor: use team_presenter fixture --- .../tests/modules/teams/test_create_team.py | 24 +++-------------- .../src/tests/modules/teams/test_get_team.py | 27 +++---------------- 2 files changed, 7 insertions(+), 44 deletions(-) diff --git a/backend/src/tests/modules/teams/test_create_team.py b/backend/src/tests/modules/teams/test_create_team.py index 6e183a66..fc2afe4f 100644 --- a/backend/src/tests/modules/teams/test_create_team.py +++ b/backend/src/tests/modules/teams/test_create_team.py @@ -2,37 +2,19 @@ import pytest from kwai.core.db.database import Database -from kwai.core.domain.presenter import Presenter from kwai.modules.teams.create_team import CreateTeam, CreateTeamCommand -from kwai.modules.teams.domain.team import TeamEntity from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository pytestmark = pytest.mark.db -class TestPresenter(Presenter[TeamEntity]): - """A dummy presenter for checking the use case result.""" - - def __init__(self): - self._entity = None - - @property - def entity(self) -> TeamEntity: - """Return the entity.""" - return self._entity - - def present(self, use_case_result: TeamEntity) -> None: - self._entity = use_case_result - - -async def test_create_team(database: Database, make_team) -> None: +async def test_create_team(database: Database, make_team, team_presenter) -> None: """Test the use case 'Create Team'.""" - presenter = TestPresenter() team = make_team() command = CreateTeamCommand( name=team.name, active=team.is_active, remark=team.remark, ) - await CreateTeam(TeamDbRepository(database), presenter).execute((command)) - assert presenter.entity is not None, "The team should be created" + await CreateTeam(TeamDbRepository(database), team_presenter).execute((command)) + assert team_presenter.entity is not None, "The team should be created" diff --git a/backend/src/tests/modules/teams/test_get_team.py b/backend/src/tests/modules/teams/test_get_team.py index 4e7f6f1b..b852f7e2 100644 --- a/backend/src/tests/modules/teams/test_get_team.py +++ b/backend/src/tests/modules/teams/test_get_team.py @@ -2,35 +2,16 @@ import pytest from kwai.core.db.database import Database -from kwai.core.domain.presenter import Presenter -from kwai.modules.teams.domain.team import TeamEntity from kwai.modules.teams.get_team import GetTeam, GetTeamCommand from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository pytestmark = pytest.mark.db -class TestPresenter(Presenter[TeamEntity]): - """A dummy presenter for checking the use case result.""" - - def __init__(self): - super().__init__() - self._entity = None - - @property - def entity(self): - """Return the entity.""" - return self._entity - - def present(self, use_case_result: TeamEntity) -> None: - self._entity = use_case_result - - -async def test_get_teams(database: Database, make_team_in_db): +async def test_get_teams(database: Database, make_team_in_db, team_presenter): """Test get teams.""" team = await make_team_in_db() command = GetTeamCommand(id=team.id.value) - presenter = TestPresenter() - await GetTeam(TeamDbRepository(database), presenter).execute(command) - assert presenter.entity is not None, "The team should exist" - assert presenter.entity.id == team.id, "The team should be found" + await GetTeam(TeamDbRepository(database), team_presenter).execute(command) + assert team_presenter.entity is not None, "The team should exist" + assert team_presenter.entity.id == team.id, "The team should be found" From 5b02c1886c75535996538c234afb0082527f2ef1 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 12 Jul 2024 14:37:56 +0200 Subject: [PATCH 156/410] feat: Update team use case --- backend/src/kwai/modules/teams/update_team.py | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 backend/src/kwai/modules/teams/update_team.py diff --git a/backend/src/kwai/modules/teams/update_team.py b/backend/src/kwai/modules/teams/update_team.py new file mode 100644 index 00000000..e52fb1df --- /dev/null +++ b/backend/src/kwai/modules/teams/update_team.py @@ -0,0 +1,53 @@ +"""Module that defines the Update Team use case.""" + +from dataclasses import dataclass + +from kwai.core.domain.entity import Entity +from kwai.core.domain.presenter import Presenter +from kwai.modules.teams.domain.team import TeamEntity, TeamIdentifier +from kwai.modules.teams.repositories.team_repository import TeamRepository + + +@dataclass(frozen=True, kw_only=True, slots=True) +class UpdateTeamCommand: + """Input for the Update Team use case.""" + + id: int + name: str + active: bool + remark: str + + +class UpdateTeam: + """Use case for updating a team.""" + + def __init__(self, team_repo: TeamRepository, presenter: Presenter[TeamEntity]): + """Initialize the use case. + + Args: + team_repo: A repository for updating the team. + presenter: A presenter for a team entity. + """ + self._team_repo = team_repo + self._presenter = presenter + + async def execute(self, command: UpdateTeamCommand) -> None: + """Execute the use case. + + Raises: + TeamNotFoundException: raise when the team does not exist. + """ + team = await self._team_repo.get( + self._team_repo.create_query().filter_by_id(TeamIdentifier(command.id)) + ) + + team = Entity.replace( + team, + name=command.name, + active=command.active, + remark=command.remark, + traceable_time=team.traceable_time.mark_for_update(), + ) + await self._team_repo.update(team) + + self._presenter.present(team) From a6305fbb99afeb5c4e0187c21acba79a94572aa8 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 12 Jul 2024 15:30:51 +0200 Subject: [PATCH 157/410] feat: Update team api --- backend/src/kwai/api/v1/teams/api.py | 49 ++++++++++++++++------ backend/src/tests/api/v1/teams/test_api.py | 21 ++++++++++ 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/backend/src/kwai/api/v1/teams/api.py b/backend/src/kwai/api/v1/teams/api.py index 08a1a118..8658f119 100644 --- a/backend/src/kwai/api/v1/teams/api.py +++ b/backend/src/kwai/api/v1/teams/api.py @@ -19,6 +19,7 @@ from kwai.modules.teams.get_team import GetTeam, GetTeamCommand from kwai.modules.teams.get_teams import GetTeams, GetTeamsCommand from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository +from kwai.modules.teams.update_team import UpdateTeam, UpdateTeamCommand from kwai.modules.training.teams.team_repository import TeamNotFoundException router = APIRouter(tags=["teams"]) @@ -47,18 +48,6 @@ async def get_team( return presenter.get_document() -@router.get("/teams/{id}/members") -async def get_team_members( - id: int, - database: Annotated[Database, Depends(create_database)], -) -> TeamMemberDocument: - """Get the member of the team with the given id.""" - presenter = JsonApiTeamMembersPresenter() - command = GetTeamCommand(id=id) - await GetTeam(TeamDbRepository(database), presenter).execute(command) - return presenter.get_document() - - @router.post("/teams", status_code=status.HTTP_201_CREATED) async def create_team( resource: TeamDocument, @@ -77,6 +66,30 @@ async def create_team( return team_presenter.get_document() +@router.patch( + "/teams/{id}", + status_code=status.HTTP_200_OK, + responses={status.HTTP_404_NOT_FOUND: {"description": "Team not found"}}, +) +async def update_team( + id: int, + resource: TeamDocument, + database: Annotated[Database, Depends(create_database)], + user: Annotated[UserEntity, Depends(get_current_user)], +) -> TeamDocument: + """Update an existing team.""" + command = UpdateTeamCommand( + id=id, + name=resource.data.attributes.name, + active=resource.data.attributes.active, + remark=resource.data.attributes.remark, + ) + team_presenter = JsonApiTeamPresenter() + async with UnitOfWork(database): + await UpdateTeam(TeamDbRepository(database), team_presenter).execute(command) + return team_presenter.get_document() + + @router.delete( "/teams/{id}", status_code=status.HTTP_200_OK, @@ -97,3 +110,15 @@ async def delete_team( raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=str(ex) ) from ex + + +@router.get("/teams/{id}/members") +async def get_team_members( + id: int, + database: Annotated[Database, Depends(create_database)], +) -> TeamMemberDocument: + """Get the member of the team with the given id.""" + presenter = JsonApiTeamMembersPresenter() + command = GetTeamCommand(id=id) + await GetTeam(TeamDbRepository(database), presenter).execute(command) + return presenter.get_document() diff --git a/backend/src/tests/api/v1/teams/test_api.py b/backend/src/tests/api/v1/teams/test_api.py index 06927d76..2ad13e39 100644 --- a/backend/src/tests/api/v1/teams/test_api.py +++ b/backend/src/tests/api/v1/teams/test_api.py @@ -43,3 +43,24 @@ async def test_create_team(secure_client: TestClient, make_team): } response = secure_client.post("/api/v1/teams", json=payload) assert response.status_code == status.HTTP_201_CREATED + + +async def test_update_team(secure_client: TestClient, make_team_in_db): + """Test /api/v1/teams endpoint for updating a team.""" + team = await make_team_in_db() + payload = { + "data": { + "id": str(team.id), + "type": "teams", + "attributes": { + "name": team.name, + "active": team.is_active, + "remark": "This is a test", + }, + } + } + response = secure_client.patch(f"/api/v1/teams/{team.id}", json=payload) + assert response.status_code == status.HTTP_200_OK + assert ( + response.json()["data"]["attributes"]["remark"] == "This is a test" + ), "The team should be updated." From ff5dc06393ab24f2a922b4930902944660073816 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 23 Aug 2024 15:21:01 +0200 Subject: [PATCH 158/410] feat: Manifest --- backend/src/kwai/frontend/manifest.py | 71 +++++++++++ backend/src/tests/frontend/__init__.py | 1 + backend/src/tests/frontend/data/manifest.json | 114 ++++++++++++++++++ backend/src/tests/frontend/test_manifest.py | 57 +++++++++ 4 files changed, 243 insertions(+) create mode 100644 backend/src/kwai/frontend/manifest.py create mode 100644 backend/src/tests/frontend/__init__.py create mode 100644 backend/src/tests/frontend/data/manifest.json create mode 100644 backend/src/tests/frontend/test_manifest.py diff --git a/backend/src/kwai/frontend/manifest.py b/backend/src/kwai/frontend/manifest.py new file mode 100644 index 00000000..5ef5606d --- /dev/null +++ b/backend/src/kwai/frontend/manifest.py @@ -0,0 +1,71 @@ +"""Module that defines a class for handling the manifest file of Vite.""" + +import json +from dataclasses import dataclass, field +from pathlib import Path +from typing import Self + + +@dataclass(frozen=True, kw_only=True, slots=True) +class Chunk: + """An entry of a manifest file.""" + + src: str | None = None + name: str | None = None + entry: bool = False + dynamic_entry: bool = False + file: str + css: list[str] = field(default_factory=list) + assets: list[str] = field(default_factory=list) + imports: list[str] = field(default_factory=list) + dynamic_imports: list[str] = field(default_factory=list) + + +class Manifest: + """Class for handling a manifest file of Vite.""" + + def __init__(self, entries: dict[str, Chunk]) -> None: + """Initialize the Manifest class.""" + self._entries = entries + + @property + def chunks(self): + """Return the entries.""" + return self._entries.copy() + + def has_chunk(self, entry_name: str): + """Check if the entry exists in the manifest file.""" + return entry_name in self._entries + + def get_chunk(self, entry_name: str) -> Chunk: + """Return the entry with the given name.""" + return self._entries[entry_name] + + @classmethod + def load_from_file(cls, file_path: Path) -> Self: + """Load the manifest from a file.""" + with open(file_path, "r") as manifest_file: + return cls.load_from_string(manifest_file.read()) + + @classmethod + def load_from_string(cls, content: str) -> Self: + """Load the manifest from a string.""" + entries: dict[str, Chunk] = {} + json_data = json.loads(content) + for k, v in json_data.items(): + if not isinstance(v, dict): + continue + entry = Chunk( + src=v.get("src", None), + name=v.get("name", None), + entry=v.get("isEntry", False), + dynamic_entry=v.get("isDynamicEntry", False), + file=v.get("file"), + css=v.get("css", []), + assets=v.get("assets", []), + imports=v.get("imports", []), + dynamic_imports=v.get("dynamicImports", []), + ) + entries[k] = entry + + return cls(entries=entries) diff --git a/backend/src/tests/frontend/__init__.py b/backend/src/tests/frontend/__init__.py new file mode 100644 index 00000000..cfbb3982 --- /dev/null +++ b/backend/src/tests/frontend/__init__.py @@ -0,0 +1 @@ +"""Package containing frontend tests.""" diff --git a/backend/src/tests/frontend/data/manifest.json b/backend/src/tests/frontend/data/manifest.json new file mode 100644 index 00000000..2d070f0a --- /dev/null +++ b/backend/src/tests/frontend/data/manifest.json @@ -0,0 +1,114 @@ +{ + "_vendor-97e41b2b.js": { + "file": "assets/vendor-97e41b2b.js" + }, + "images/hero.jpg": { + "file": "assets/hero-7d6583ab.jpg", + "src": "images/hero.jpg" + }, + "images/hero_club.jpg": { + "file": "assets/hero_club-163a0a1d.jpg", + "src": "images/hero_club.jpg" + }, + "images/hero_judo.jpg": { + "file": "assets/hero_judo-98309ea4.jpg", + "src": "images/hero_judo.jpg" + }, + "images/hero_news.jpg": { + "file": "assets/hero_news-7e409a2c.jpg", + "src": "images/hero_news.jpg" + }, + "images/hero_shop.jpg": { + "file": "assets/hero_shop-b55abed0.jpg", + "src": "images/hero_shop.jpg" + }, + "images/hero_tournaments.jpg": { + "file": "assets/hero_tournaments-59e5271e.jpg", + "src": "images/hero_tournaments.jpg" + }, + "images/hero_trainings.jpg": { + "file": "assets/hero_trainings-47dcea06.jpg", + "src": "images/hero_trainings.jpg" + }, + "src/components/icons/FacebookIcon.vue": { + "file": "assets/FacebookIcon-44b697a2.js", + "imports": [ + "src/index.ts", + "_vendor-97e41b2b.js" + ], + "isDynamicEntry": true, + "src": "src/components/icons/FacebookIcon.vue" + }, + "src/components/icons/InstagramIcon.vue": { + "file": "assets/InstagramIcon-ce6d9dfa.js", + "imports": [ + "src/index.ts", + "_vendor-97e41b2b.js" + ], + "isDynamicEntry": true, + "src": "src/components/icons/InstagramIcon.vue" + }, + "src/components/icons/LoadingIcon.vue": { + "file": "assets/LoadingIcon-3b690cc8.js", + "imports": [ + "src/index.ts", + "_vendor-97e41b2b.js" + ], + "isDynamicEntry": true, + "src": "src/components/icons/LoadingIcon.vue" + }, + "src/components/icons/NextIcon.vue": { + "file": "assets/NextIcon-771d3f7f.js", + "imports": [ + "src/index.ts", + "_vendor-97e41b2b.js" + ], + "isDynamicEntry": true, + "src": "src/components/icons/NextIcon.vue" + }, + "src/components/icons/PrevIcon.vue": { + "file": "assets/PrevIcon-41277b2b.js", + "imports": [ + "src/index.ts", + "_vendor-97e41b2b.js" + ], + "isDynamicEntry": true, + "src": "src/components/icons/PrevIcon.vue" + }, + "src/index.css": { + "file": "assets/index-ace45c09.css", + "src": "src/index.css" + }, + "src/index.ts": { + "assets": [ + "assets/hero-7d6583ab.jpg", + "assets/hero_club-163a0a1d.jpg", + "assets/hero_judo-98309ea4.jpg", + "assets/hero_news-7e409a2c.jpg", + "assets/hero_shop-b55abed0.jpg", + "assets/hero_tournaments-59e5271e.jpg", + "assets/hero_trainings-47dcea06.jpg" + ], + "css": [ + "assets/index-ace45c09.css" + ], + "dynamicImports": [ + "src/components/icons/FacebookIcon.vue", + "src/components/icons/InstagramIcon.vue", + "src/components/icons/LoadingIcon.vue", + "src/components/icons/NextIcon.vue", + "src/components/icons/PrevIcon.vue", + "src/components/icons/FacebookIcon.vue", + "src/components/icons/InstagramIcon.vue", + "src/components/icons/LoadingIcon.vue", + "src/components/icons/NextIcon.vue", + "src/components/icons/PrevIcon.vue" + ], + "file": "assets/index-533fa9ea.js", + "imports": [ + "_vendor-97e41b2b.js" + ], + "isEntry": true, + "src": "src/index.ts" + } +} diff --git a/backend/src/tests/frontend/test_manifest.py b/backend/src/tests/frontend/test_manifest.py new file mode 100644 index 00000000..4aa244f0 --- /dev/null +++ b/backend/src/tests/frontend/test_manifest.py @@ -0,0 +1,57 @@ +"""Module for testing the Manifest class.""" + +from pathlib import Path + +import pytest +from kwai.frontend.manifest import Manifest + + +@pytest.fixture +def manifest() -> Manifest: + """Load a manifest file from the data folder.""" + manifest_file_path = Path(__file__).parent / "data" / "manifest.json" + return Manifest.load_from_file(manifest_file_path) + + +def test_load_manifest_from_string(): + """Test loading the manifest from a string.""" + manifest = Manifest.load_from_string( + """ + { + "src/index.ts": { + "isEntry": true, + "file": "assets/index-8a61960c.js", + "src": "src/index.ts" + } + } + """ + ) + assert len(manifest.chunks) > 0, "There should be a chunk in the manifest." + assert manifest.has_chunk("src/index.ts") is not None, "The chunk should exist." + assert manifest.get_chunk("src/index.ts") is not None, "The chunk should exist." + + +def test_chunks(manifest: Manifest): + """Test the chunks property.""" + chunks = manifest.chunks + assert len(chunks) > 0, "There should be chunks in the manifest." + + +def test_has_chunk(manifest: Manifest): + """Test the has_chunk method.""" + assert manifest.has_chunk("src/index.ts") is True, "The chunk should exist." + assert manifest.has_chunk("images/hero.jpg") is True, "The chunk should exist." + + +def test_chunk(manifest: Manifest): + """Test the get_chunk method.""" + chunk = manifest.get_chunk("src/index.ts") + assert chunk is not None, "The chunk should exist." + assert chunk.src == "src/index.ts", "The src should be 'src/index.ts'" + assert chunk.file == "assets/index-533fa9ea.js" + assert len(chunk.imports) > 0 + assert chunk.entry is True + assert len(chunk.assets) > 0 + assert len(chunk.css) > 0 + assert len(chunk.dynamic_imports) > 0 + assert chunk.dynamic_entry is False From da36fad847e17ad2292cfca49163bee611fc7365 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 23 Aug 2024 15:27:54 +0200 Subject: [PATCH 159/410] refactor: move fixture to conftest.py --- backend/src/tests/frontend/conftest.py | 13 +++++++++++++ backend/src/tests/frontend/test_manifest.py | 10 ---------- 2 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 backend/src/tests/frontend/conftest.py diff --git a/backend/src/tests/frontend/conftest.py b/backend/src/tests/frontend/conftest.py new file mode 100644 index 00000000..3ca673e2 --- /dev/null +++ b/backend/src/tests/frontend/conftest.py @@ -0,0 +1,13 @@ +"""Module for pytest fixtures for testing the frontend module..""" + +from pathlib import Path + +import pytest +from kwai.frontend.manifest import Manifest + + +@pytest.fixture +def manifest() -> Manifest: + """Load a manifest file from the data folder.""" + manifest_file_path = Path(__file__).parent / "data" / "manifest.json" + return Manifest.load_from_file(manifest_file_path) diff --git a/backend/src/tests/frontend/test_manifest.py b/backend/src/tests/frontend/test_manifest.py index 4aa244f0..9bd0e96d 100644 --- a/backend/src/tests/frontend/test_manifest.py +++ b/backend/src/tests/frontend/test_manifest.py @@ -1,18 +1,8 @@ """Module for testing the Manifest class.""" -from pathlib import Path - -import pytest from kwai.frontend.manifest import Manifest -@pytest.fixture -def manifest() -> Manifest: - """Load a manifest file from the data folder.""" - manifest_file_path = Path(__file__).parent / "data" / "manifest.json" - return Manifest.load_from_file(manifest_file_path) - - def test_load_manifest_from_string(): """Test loading the manifest from a string.""" manifest = Manifest.load_from_string( From 38f6efcb80e19dc5ac30fb12bebdbeb4702b20d8 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 23 Aug 2024 15:37:56 +0200 Subject: [PATCH 160/410] refactor: add manifest_path fixture --- backend/src/tests/frontend/conftest.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/backend/src/tests/frontend/conftest.py b/backend/src/tests/frontend/conftest.py index 3ca673e2..d033279b 100644 --- a/backend/src/tests/frontend/conftest.py +++ b/backend/src/tests/frontend/conftest.py @@ -7,7 +7,12 @@ @pytest.fixture -def manifest() -> Manifest: +def manifest_path() -> Path: """Load a manifest file from the data folder.""" - manifest_file_path = Path(__file__).parent / "data" / "manifest.json" - return Manifest.load_from_file(manifest_file_path) + return Path(__file__).parent / "data" / "manifest.json" + + +@pytest.fixture +def manifest(manifest_path) -> Manifest: + """Load a manifest file from the data folder.""" + return Manifest.load_from_file(manifest_path) From 5d49b71cc41bbdba38304e2ebce6f9b82a0a695a Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 23 Aug 2024 16:15:13 +0200 Subject: [PATCH 161/410] feat: Vite in backend --- backend/src/kwai/frontend/vite.py | 124 ++++++++++++++++++ .../tests/frontend/test_development_vite.py | 34 +++++ .../tests/frontend/test_production_vite.py | 44 +++++++ 3 files changed, 202 insertions(+) create mode 100644 backend/src/kwai/frontend/vite.py create mode 100644 backend/src/tests/frontend/test_development_vite.py create mode 100644 backend/src/tests/frontend/test_production_vite.py diff --git a/backend/src/kwai/frontend/vite.py b/backend/src/kwai/frontend/vite.py new file mode 100644 index 00000000..a70253d4 --- /dev/null +++ b/backend/src/kwai/frontend/vite.py @@ -0,0 +1,124 @@ +"""Module for defining a class that handles files and assets created with vite.""" + +from abc import ABC, abstractmethod +from pathlib import Path + +from kwai.frontend.manifest import Chunk, Manifest + + +class Vite(ABC): + """Interface for a Vite runtime.""" + + @abstractmethod + def init(self, *entries: str): + """Initialize the Vite runtime for the given entries.""" + raise NotImplementedError + + @abstractmethod + def generate_scripts(self, *entries: str) -> list[str]: + """Generate the script tags for the given entries.""" + raise NotImplementedError + + @abstractmethod + def generate_css(self, *entries: str) -> list[str]: + """Generate the css tags for the given entries.""" + raise NotImplementedError + + @abstractmethod + def generate_preloads(self, *entries: str) -> list[str]: + """Generate the preload tags for the given entries.""" + raise NotImplementedError + + +class DevelopmentVite(Vite): + """Vite implementation for development.""" + + def __init__(self, base_path: Path): + self._base_path = base_path + self._entries: list[str] = [] + + def init(self, *entries: str): + self._entries = entries + + def generate_scripts(self) -> list[str]: + scripts = [f''] + for entry in self._entries: + scripts.append(f'') + return scripts + + def generate_css(self) -> list[str]: + return [] + + def generate_preloads(self) -> list[str]: + return [] + + +class ProductionVite(Vite): + """Vite implementation for production.""" + + def __init__(self, manifest_filepath: Path, base_path: Path): + self._manifest_filepath: Path = manifest_filepath + self._base_path: Path = base_path + self._manifest: Manifest | None = None + self._imported_chunks: dict[str, Chunk] = {} # chunks imported by the entries + + def init(self, *entries: str): + """Load the manifest file.""" + self._manifest = Manifest.load_from_file(self._manifest_filepath) + self._imported_chunks = self._find_imported_chunks(*entries) + + def generate_scripts(self) -> list[str]: + scripts = [] + + for chunk in self._imported_chunks.values(): + if chunk.entry: + scripts.append( + '' + ) + + return scripts + + def generate_css(self) -> list[str]: + styles = [] + for chunk in self._imported_chunks.values(): + for css in chunk.css: + styles.append(f'') + return styles + + def generate_preloads(self) -> list[str]: + preloads = [] + + for chunk in self._imported_chunks.values(): + if chunk.file.endswith(".js") and not chunk.entry: + preloads.append( + f'' + ) + + return preloads + + def _find_imported_chunks(self, *entries: str) -> dict[str, Chunk]: + chunks = {} + + for entry in entries: + if not self._manifest.has_chunk(entry): + raise ValueError(f"{entry} is not a chunk in {self._manifest_filepath}") + + chunk = self._manifest.get_chunk(entry) + if not chunk.entry: + raise ValueError( + f"{entry} is not an entry point in {self._manifest_filepath}" + ) + + chunks[entry] = chunk + + imports = chunk.imports + while imports: + import_ = imports.pop() + if import_ not in chunks: + import_chunk = self._manifest.get_chunk(import_) + chunks[import_] = import_chunk + imports.extend(import_chunk.imports) + + return chunks diff --git a/backend/src/tests/frontend/test_development_vite.py b/backend/src/tests/frontend/test_development_vite.py new file mode 100644 index 00000000..c71a1a6b --- /dev/null +++ b/backend/src/tests/frontend/test_development_vite.py @@ -0,0 +1,34 @@ +"""Module for testing the development vite class.""" + +from pathlib import Path + +import pytest +from kwai.frontend.vite import DevelopmentVite, Vite + + +@pytest.fixture +def vite() -> Vite: + """A fixture for vite development.""" + vite = DevelopmentVite(Path("/home/kwai/website")) + vite.init("src/index.ts") + return vite + + +def test_development_vite_scripts(vite: Vite): + """Test the development version of the Vite class for script tags.""" + scripts = vite.generate_scripts() + assert len(scripts) == 2, "There should be 2 script tags" + assert scripts[0] == '' + assert scripts[1] == '' + + +def test_development_vite_css(vite: Vite): + """Test the development version of the Vite class for css tags.""" + assert len(vite.generate_css()) == 0, "There should be no css in development" + + +def test_development_vite_preload(vite: Vite): + """Test the development version of the Vite class for preload tags.""" + assert ( + len(vite.generate_preloads()) == 0 + ), "There should be no preload in development" diff --git a/backend/src/tests/frontend/test_production_vite.py b/backend/src/tests/frontend/test_production_vite.py new file mode 100644 index 00000000..afc9b67e --- /dev/null +++ b/backend/src/tests/frontend/test_production_vite.py @@ -0,0 +1,44 @@ +"""Module for testing the production vite class.""" + +from pathlib import Path + +import pytest +from kwai.frontend.vite import ProductionVite, Vite + + +@pytest.fixture +def vite(manifest_path: Path) -> Vite: + """A fixture for vite production.""" + vite = ProductionVite(manifest_path, Path("/home/kwai/website")) + vite.init("src/index.ts") + return vite + + +def test_production_vite_scripts(vite: Vite): + """Test the production version of the Vite class for script tags.""" + scripts = vite.generate_scripts() + assert len(scripts) == 1, "There should be one script tag" + assert ( + scripts[0] == '' + ) + + +def test_production_vite_css(vite: Vite): + """Test the production of the Vite class for css tags.""" + css = vite.generate_css() + assert len(css) == 1, "There should be a css link" + assert ( + css[0] + == '' + ) + + +def test_production_vite_preload(vite: Vite): + """Test the production version of the Vite class for preload tags.""" + preload = vite.generate_preloads() + assert len(preload) == 1, "There should be a preload" + assert ( + preload[0] + == '' + ) From c0404f1e20c106916db5b39c6c3ae31b3b17c9dc Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 23 Aug 2024 17:33:02 +0200 Subject: [PATCH 162/410] fix: script must be a module and base must be a vite url in development --- backend/src/kwai/frontend/vite.py | 8 ++++++-- backend/src/tests/frontend/test_development_vite.py | 12 +++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/backend/src/kwai/frontend/vite.py b/backend/src/kwai/frontend/vite.py index a70253d4..46e71323 100644 --- a/backend/src/kwai/frontend/vite.py +++ b/backend/src/kwai/frontend/vite.py @@ -41,9 +41,13 @@ def init(self, *entries: str): self._entries = entries def generate_scripts(self) -> list[str]: - scripts = [f''] + scripts = [ + f'' + ] for entry in self._entries: - scripts.append(f'') + scripts.append( + f'' + ) return scripts def generate_css(self) -> list[str]: diff --git a/backend/src/tests/frontend/test_development_vite.py b/backend/src/tests/frontend/test_development_vite.py index c71a1a6b..efac3b79 100644 --- a/backend/src/tests/frontend/test_development_vite.py +++ b/backend/src/tests/frontend/test_development_vite.py @@ -9,7 +9,7 @@ @pytest.fixture def vite() -> Vite: """A fixture for vite development.""" - vite = DevelopmentVite(Path("/home/kwai/website")) + vite = DevelopmentVite(Path("http://localhost:5173")) vite.init("src/index.ts") return vite @@ -18,8 +18,14 @@ def test_development_vite_scripts(vite: Vite): """Test the development version of the Vite class for script tags.""" scripts = vite.generate_scripts() assert len(scripts) == 2, "There should be 2 script tags" - assert scripts[0] == '' - assert scripts[1] == '' + assert ( + scripts[0] + == '' + ) + assert ( + scripts[1] + == '' + ) def test_development_vite_css(vite: Vite): From 0a72cdf099c09c0478e76d9c671d9a16b540812b Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 23 Aug 2024 19:36:49 +0200 Subject: [PATCH 163/410] fix: make sure ApplicationPage is refreshed when route is changed --- .../apps/portal/src/pages/ApplicationPage.vue | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/frontend/apps/portal/src/pages/ApplicationPage.vue b/frontend/apps/portal/src/pages/ApplicationPage.vue index 4fd191b4..a532e6c8 100644 --- a/frontend/apps/portal/src/pages/ApplicationPage.vue +++ b/frontend/apps/portal/src/pages/ApplicationPage.vue @@ -2,25 +2,35 @@ import { useRoute, useRouter } from 'vue-router'; import IntroSection from '@root/components/IntroSection.vue'; import { useApplications } from '@root/composables/useApplication'; -import { computed, ref, toRef } from 'vue'; +import { computed, ref, toRef, watch } from 'vue'; import { usePages } from '@root/composables/usePage'; import FullArticle from '@root/components/FullArticle.vue'; const route = useRoute(); -const applicationName = route.meta.application as string; -const heroImageUrl = route.meta.heroImageUrl as string; + +const applicationName = toRef(route.meta.application as string); +const heroImageUrl = toRef(route.meta.heroImageUrl as string); + +watch(route, (nv) => { + if (nv.meta.application) { + applicationName.value = nv.meta.application as string; + } + if (nv.meta.heroImageUrl) { + heroImageUrl.value = nv.meta.heroImageUrl as string; + } +}); // Application const { data: applications } = useApplications(); const application = computed(() => { if (applications.value) { - return applications.value.find(application => application.name === applicationName); + return applications.value.find(application => application.name === applicationName.value); } return null; }); // Pages -const { data: pages } = usePages(toRef(applicationName)); +const { data: pages } = usePages(applicationName); const sortedPages = computed(() => { return [...pages.value || []].sort((a, b) => b.priority - a.priority); }); @@ -41,7 +51,10 @@ const currentPage = computed(() => { if (articleSection.value) articleSection.value.scrollIntoView(true); return sortedPages.value.find(page => page.id === route.query.page); } - return sortedPages.value[0]; + if (sortedPages.value.length > 0) { + return sortedPages.value[0]; + } + return null; }); const router = useRouter(); @@ -55,6 +68,7 @@ const gotoPage = (id: string) => { + {{ applicationName }}
Date: Fri, 23 Aug 2024 19:38:20 +0200 Subject: [PATCH 164/410] fix: remove span with applicationName --- frontend/apps/portal/src/pages/ApplicationPage.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/apps/portal/src/pages/ApplicationPage.vue b/frontend/apps/portal/src/pages/ApplicationPage.vue index a532e6c8..ceb76522 100644 --- a/frontend/apps/portal/src/pages/ApplicationPage.vue +++ b/frontend/apps/portal/src/pages/ApplicationPage.vue @@ -68,7 +68,6 @@ const gotoPage = (id: string) => { - {{ applicationName }}
Date: Fri, 23 Aug 2024 19:39:26 +0200 Subject: [PATCH 165/410] fix: use import.meta.env.BASE_URL for history --- frontend/apps/portal/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/apps/portal/src/index.ts b/frontend/apps/portal/src/index.ts index ea40e77d..a4367108 100644 --- a/frontend/apps/portal/src/index.ts +++ b/frontend/apps/portal/src/index.ts @@ -12,7 +12,7 @@ const app = createApp(App); app.use(VueQueryPlugin); const router = createRouter({ - history: createWebHistory(), + history: createWebHistory(import.meta.env.BASE_URL), routes: [], }); router.beforeEach((to, from, next) => { From 0e848d930450bc23e3f9ed1570b13e807f073500 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 23 Aug 2024 21:28:18 +0200 Subject: [PATCH 166/410] feat: start serving the frontend with FastAPI --- backend/src/kwai/api/app.py | 3 + backend/src/kwai/api/dependencies.py | 9 ++ backend/src/kwai/core/settings.py | 27 ++++++ backend/src/kwai/frontend/__init__.py | 1 + backend/src/kwai/frontend/app.py | 127 ++++++++++++++++++++++++++ frontend/apps/auth/vite.config.ts | 13 +++ frontend/apps/author/vite.config.ts | 13 +++ frontend/apps/club/vite.config.ts | 13 +++ frontend/apps/coach/vite.config.ts | 13 +++ frontend/apps/portal/vite.config.ts | 16 +++- 10 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 backend/src/kwai/frontend/__init__.py create mode 100644 backend/src/kwai/frontend/app.py diff --git a/backend/src/kwai/api/app.py b/backend/src/kwai/api/app.py index f6be12fb..16ea335d 100644 --- a/backend/src/kwai/api/app.py +++ b/backend/src/kwai/api/app.py @@ -18,6 +18,7 @@ from kwai.api.v1.teams.api import router as teams_api_router from kwai.api.v1.trainings.api import api_router as training_api_router from kwai.core.settings import LoggerSettings, Settings, get_settings +from kwai.frontend.app import create_frontend @asynccontextmanager @@ -120,4 +121,6 @@ async def log(request: Request, call_next): app.include_router(training_api_router, prefix="/api/v1") app.include_router(club_api_router, prefix="/api/v1") + app.mount("/", create_frontend()) + return app diff --git a/backend/src/kwai/api/dependencies.py b/backend/src/kwai/api/dependencies.py index 56e523dd..e16f761f 100644 --- a/backend/src/kwai/api/dependencies.py +++ b/backend/src/kwai/api/dependencies.py @@ -1,9 +1,11 @@ """Module that integrates the dependencies in FastAPI.""" + from typing import AsyncGenerator import jwt from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer +from fastapi.templating import Jinja2Templates from jwt import ExpiredSignatureError from redis.asyncio import Redis @@ -34,6 +36,13 @@ async def create_database( await database.close() +async def create_templates(settings=Depends(get_settings)) -> Jinja2Templates: + """Create the template engine dependency.""" + templates = Jinja2Templates(directory=settings.template.path) + templates.env.add_extension("jinja2.ext.do") + return templates + + async def get_current_user( settings=Depends(get_settings), db=Depends(create_database), diff --git a/backend/src/kwai/core/settings.py b/backend/src/kwai/core/settings.py index 4b09d6bc..03254736 100644 --- a/backend/src/kwai/core/settings.py +++ b/backend/src/kwai/core/settings.py @@ -1,4 +1,5 @@ """Module for the settings of this application.""" + import os from functools import lru_cache @@ -12,6 +13,30 @@ class SettingsException(Exception): """Raised when a problem occurred while loading the settings.""" +class FrontendApplicationSettings(BaseModel): + """Settings for a frontend application.""" + + base: str + base_dev: str | None = None + entries: list[str] | str + + +class FrontendApplications(BaseModel): + """All applications.""" + + portal: FrontendApplicationSettings + coach: FrontendApplicationSettings + + +class FrontendSettings(BaseModel): + """Settings for the frontend.""" + + test: bool + path: str + apps: FrontendApplications + root_app: str + + class FilesSettings(BaseModel): """Settings for files (upload).""" @@ -92,6 +117,8 @@ class TemplateSettings(BaseModel): class Settings(BaseModel): """Class with settings.""" + frontend: FrontendSettings + files: FilesSettings security: SecuritySettings diff --git a/backend/src/kwai/frontend/__init__.py b/backend/src/kwai/frontend/__init__.py new file mode 100644 index 00000000..c656fddb --- /dev/null +++ b/backend/src/kwai/frontend/__init__.py @@ -0,0 +1 @@ +"""Package that defines modules for serving the frontend from the Python backend.""" diff --git a/backend/src/kwai/frontend/app.py b/backend/src/kwai/frontend/app.py new file mode 100644 index 00000000..8e6e2bdd --- /dev/null +++ b/backend/src/kwai/frontend/app.py @@ -0,0 +1,127 @@ +"""Module that defines a sub application for handling the frontend.""" + +import uuid +from enum import Enum +from pathlib import Path +from typing import Annotated + +from fastapi import Depends, FastAPI, HTTPException, Request, status +from fastapi.responses import JSONResponse, RedirectResponse +from fastapi.staticfiles import StaticFiles +from fastapi.templating import Jinja2Templates +from loguru import logger + +from kwai.api.dependencies import create_templates +from kwai.core.settings import Settings, get_settings +from kwai.frontend.vite import DevelopmentVite, ProductionVite + + +class FrontendApplicationName(str, Enum): + """Defines all available frontend application names.""" + + portal = "portal" + coach = "coach" + + @classmethod + def list(cls): + """List all available frontend application names.""" + return [c.value for c in cls] + + +def create_frontend_app(frontend_app: FastAPI, settings: Settings, application: str): + """Create a frontend for an application.""" + # Public files + root_path = Path(settings.frontend.path) / "apps" / application / "dist" + frontend_app.mount(f"/apps/{application}/public", StaticFiles(directory=root_path)) + # Assets + frontend_app.mount( + f"/apps/{application}/assets", StaticFiles(directory=root_path / "assets") + ) + + @frontend_app.get("/apps/{app}/{router:path}") + async def get_app( + request: Request, + templates: Annotated[Jinja2Templates, Depends(create_templates)], + app: FrontendApplicationName, + ): + """Get the html page for a given frontend application. + + Remark: the router:path is required for handling a refresh on a vue-router page. + """ + manifest_path = root_path / "manifest.json" + if not manifest_path.exists(): + raise HTTPException( + status_code=status.INTERNAL_SERVER_ERROR, + detail=f"Manifest file {manifest_path} not found", + ) + + if not hasattr(settings.frontend.apps, app): + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Application {app} does not exist.", + ) + + app_setting = getattr(settings.frontend.apps, app) + + if settings.frontend.test: + if app_setting.base_dev is None: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f"Setting base_dev not set for application {app}", + ) + vite = DevelopmentVite(app_setting.base_dev) + else: + vite = ProductionVite(manifest_path, app_setting.base) + + return templates.TemplateResponse( + "index.jinja2", + { + "request": request, + "settings": settings, + "vite": vite, + }, + ) + + +def create_frontend(): + """Create the frontend.""" + frontend_app = FastAPI() + + @frontend_app.get("/") + async def get_root(settings: Annotated[Settings, Depends(get_settings)]): + """Redirect the root path to the portal application.""" + return RedirectResponse(f"/apps/{settings.frontend.root_app}") + + @frontend_app.middleware("http") + async def log(request: Request, call_next): + """Middleware for logging the requests.""" + request_id = str(uuid.uuid4()) + with logger.contextualize(request_id=request_id): + logger.info(f"{request.url} - {request.method} - Request started") + + response = None # Make pylint happy... + try: + response = await call_next(request) + except Exception as ex: + logger.error(f"{request.url} - Request failed: {ex}") + logger.exception(ex) + response = JSONResponse( + content={ + "detail": str(ex), + }, + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + ) + finally: + response.headers["X-Request-ID"] = request_id + logger.info( + f"{request.url} - {request.method} - Request ended: " + f"{response.status_code}" + ) + + return response + + kwai_settings = get_settings() + for application in FrontendApplicationName.list(): + create_frontend_app(frontend_app, kwai_settings, application) + + return frontend_app diff --git a/frontend/apps/auth/vite.config.ts b/frontend/apps/auth/vite.config.ts index aac1990b..0c7a3316 100644 --- a/frontend/apps/auth/vite.config.ts +++ b/frontend/apps/auth/vite.config.ts @@ -23,11 +23,24 @@ const resolveTheme = (path: string) => { export default defineConfig(() => { return { + experimental: { + renderBuiltUrl(filename, { type }) { + if (type === 'public') { + return `public/${filename}`; + } + }, + }, base: '/apps/auth/', server: { host: '0.0.0.0', port: 3002, }, + build: { + manifest: true, + rollupOptions: { + input: 'src/index.ts', + }, + }, plugins: [ vue(), toml(), diff --git a/frontend/apps/author/vite.config.ts b/frontend/apps/author/vite.config.ts index 673d6570..8c20bffc 100644 --- a/frontend/apps/author/vite.config.ts +++ b/frontend/apps/author/vite.config.ts @@ -7,6 +7,13 @@ import { visualizer } from 'rollup-plugin-visualizer'; export default defineConfig(({ mode }) => { return { + experimental: { + renderBuiltUrl(filename, { type }) { + if (type === 'public') { + return `public/${filename}`; + } + }, + }, base: '/apps/author/', esbuild: { pure: mode === 'production' ? ['console.log'] : [], @@ -15,6 +22,12 @@ export default defineConfig(({ mode }) => { host: '0.0.0.0', port: 3001, }, + build: { + manifest: true, + rollupOptions: { + input: 'src/index.ts', + }, + }, plugins: [ vue(), VueI18nPlugin({ diff --git a/frontend/apps/club/vite.config.ts b/frontend/apps/club/vite.config.ts index 8c732f19..46ee1b3d 100644 --- a/frontend/apps/club/vite.config.ts +++ b/frontend/apps/club/vite.config.ts @@ -7,11 +7,24 @@ import { visualizer } from 'rollup-plugin-visualizer'; export default defineConfig(({ mode }) => { return { + experimental: { + renderBuiltUrl(filename, { type }) { + if (type === 'public') { + return `public/${filename}`; + } + }, + }, base: '/apps/club/', server: { host: '0.0.0.0', port: 3004, }, + build: { + manifest: true, + rollupOptions: { + input: 'src/index.ts', + }, + }, esbuild: { pure: mode === 'production' ? ['console.log'] : [], }, diff --git a/frontend/apps/coach/vite.config.ts b/frontend/apps/coach/vite.config.ts index 4667eab7..3dcf2ce2 100644 --- a/frontend/apps/coach/vite.config.ts +++ b/frontend/apps/coach/vite.config.ts @@ -6,6 +6,13 @@ import { visualizer } from 'rollup-plugin-visualizer'; export default defineConfig(({ mode }) => { return { + experimental: { + renderBuiltUrl(filename, { type }) { + if (type === 'public') { + return `public/${filename}`; + } + }, + }, base: '/apps/coach/', esbuild: { pure: mode === 'production' ? ['console.log'] : [], @@ -14,6 +21,12 @@ export default defineConfig(({ mode }) => { host: '0.0.0.0', port: 3003, }, + build: { + manifest: true, + rollupOptions: { + input: 'src/index.ts', + }, + }, plugins: [ vue(), splitVendorChunkPlugin(), diff --git a/frontend/apps/portal/vite.config.ts b/frontend/apps/portal/vite.config.ts index 36692f45..dd61fea0 100644 --- a/frontend/apps/portal/vite.config.ts +++ b/frontend/apps/portal/vite.config.ts @@ -21,11 +21,25 @@ const resolveTheme = (path: string) => { export default defineConfig(() => { return { - base: '/', + experimental: { + renderBuiltUrl(filename, { type }) { + if (type === 'public') { + return `public/${filename}`; + } + }, + }, + base: '/apps/portal', server: { + origin: 'http://localhost:3000', host: '0.0.0.0', port: 3000, }, + build: { + manifest: true, + rollupOptions: { + input: 'src/index.ts', + }, + }, plugins: [ vue(), splitVendorChunkPlugin(), visualizer(), ], From 8c00d9990b3d3c73080d54111703eb7acb3866aa Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 24 Aug 2024 18:50:36 +0200 Subject: [PATCH 167/410] feat: add auth, author, club, and coach application --- backend/src/kwai/frontend/app.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/src/kwai/frontend/app.py b/backend/src/kwai/frontend/app.py index 8e6e2bdd..63fe3a1c 100644 --- a/backend/src/kwai/frontend/app.py +++ b/backend/src/kwai/frontend/app.py @@ -19,8 +19,11 @@ class FrontendApplicationName(str, Enum): """Defines all available frontend application names.""" - portal = "portal" + auth = "auth" + author = "author" + club = "club" coach = "coach" + portal = "portal" @classmethod def list(cls): From d4ab50e752b536124fea9292585813313ea893ab Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 24 Aug 2024 19:06:59 +0200 Subject: [PATCH 168/410] docs: add frontend --- backend/docs/deploy.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/backend/docs/deploy.md b/backend/docs/deploy.md index e1c1cc44..7b4bd327 100644 --- a/backend/docs/deploy.md +++ b/backend/docs/deploy.md @@ -53,9 +53,29 @@ cd backend/migrations dbmate -d . -u "" up ```` -## Step 4: Run +## Step 4: Frontend -To start the application use the following command: +Build the frontend with `npm run build.` This will result in a folder `dist` in all the frontend applications. +FastAPI will be used to render the frontend. Add all applications to the `.kwai.toml` configuration file: + +````toml +[frontend] +path = "/home/kwai/frontend" +root_app = "portal" + +[frontend.apps] + +[frontend.apps.portal] +base="/apps/portal" +entries="/src/index.ts" +```` + +In this example there should be a `/home/kwai/frontend/apps/portal/dist` folder that contains the result of the +build command. + +## Step 5: Run + +To start the backend application use the following command: ````shell cd backend/src From 10c4d9097951d46b1c86213e3cb610be1a879acf Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 24 Aug 2024 19:16:06 +0200 Subject: [PATCH 169/410] docs: add a shell command for building the frontend --- backend/docs/deploy.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/backend/docs/deploy.md b/backend/docs/deploy.md index 7b4bd327..e3e8c245 100644 --- a/backend/docs/deploy.md +++ b/backend/docs/deploy.md @@ -55,7 +55,14 @@ dbmate -d . -u "" up ## Step 4: Frontend -Build the frontend with `npm run build.` This will result in a folder `dist` in all the frontend applications. +Build the frontend : + +````shell +cd frontend +npm run build +```` + +This will result in a folder `dist` in all the frontend applications. FastAPI will be used to render the frontend. Add all applications to the `.kwai.toml` configuration file: ````toml From 4a39431d82da2e40a97455223e423b53130c2bec Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 24 Aug 2024 19:29:42 +0200 Subject: [PATCH 170/410] fix: INTERNAL_SERVER_ERROR must be HTTP_500_INTERNAL_SERVER_ERROR --- backend/src/kwai/frontend/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/kwai/frontend/app.py b/backend/src/kwai/frontend/app.py index 63fe3a1c..42a879fa 100644 --- a/backend/src/kwai/frontend/app.py +++ b/backend/src/kwai/frontend/app.py @@ -54,7 +54,7 @@ async def get_app( manifest_path = root_path / "manifest.json" if not manifest_path.exists(): raise HTTPException( - status_code=status.INTERNAL_SERVER_ERROR, + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Manifest file {manifest_path} not found", ) From c9be23ef127dacee2c80db80873dff0a887ee3cf Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 24 Aug 2024 19:36:02 +0200 Subject: [PATCH 171/410] fix: check for manifest.json only on production --- backend/src/kwai/frontend/app.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/backend/src/kwai/frontend/app.py b/backend/src/kwai/frontend/app.py index 42a879fa..8a8aa123 100644 --- a/backend/src/kwai/frontend/app.py +++ b/backend/src/kwai/frontend/app.py @@ -51,13 +51,6 @@ async def get_app( Remark: the router:path is required for handling a refresh on a vue-router page. """ - manifest_path = root_path / "manifest.json" - if not manifest_path.exists(): - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail=f"Manifest file {manifest_path} not found", - ) - if not hasattr(settings.frontend.apps, app): raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, @@ -74,6 +67,12 @@ async def get_app( ) vite = DevelopmentVite(app_setting.base_dev) else: + manifest_path = root_path / "manifest.json" + if not manifest_path.exists(): + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Manifest file {manifest_path} not found", + ) vite = ProductionVite(manifest_path, app_setting.base) return templates.TemplateResponse( From 9f4c163273c4c6c76f02ddf502b5e55b89582834 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 24 Aug 2024 20:04:23 +0200 Subject: [PATCH 172/410] feat: add filter by uuid --- .../modules/teams/repositories/member_db_repository.py | 4 ++++ .../modules/teams/repositories/member_repository.py | 6 ++++++ .../modules/teams/repositories/test_member_db_query.py | 10 ++++++++++ 3 files changed, 20 insertions(+) diff --git a/backend/src/kwai/modules/teams/repositories/member_db_repository.py b/backend/src/kwai/modules/teams/repositories/member_db_repository.py index 898f2707..1a843040 100644 --- a/backend/src/kwai/modules/teams/repositories/member_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/member_db_repository.py @@ -86,6 +86,10 @@ def filter_by_birthdate( ) return self + def filter_by_uuid(self, uuid: UniqueId) -> Self: + self._query.and_where(MemberRow.field("uuid").eq(str(uuid))) + return self + class MemberDbRepository(MemberRepository): """A member repository for a database.""" diff --git a/backend/src/kwai/modules/teams/repositories/member_repository.py b/backend/src/kwai/modules/teams/repositories/member_repository.py index 05d802ca..d22a51fb 100644 --- a/backend/src/kwai/modules/teams/repositories/member_repository.py +++ b/backend/src/kwai/modules/teams/repositories/member_repository.py @@ -5,6 +5,7 @@ from kwai.core.domain.repository.query import Query from kwai.core.domain.value_objects.date import Date +from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.teams.domain.team_member import MemberEntity, MemberIdentifier @@ -20,6 +21,11 @@ def filter_by_id(self, id_: MemberIdentifier) -> Self: """Find a team member by its id.""" raise NotImplementedError + @abstractmethod + def filter_by_uuid(self, uuid: UniqueId) -> Self: + """Find a team member by its uuid.""" + raise NotImplementedError + @abstractmethod def filter_by_birthdate( self, start_date: Date, end_date: Date | None = None diff --git a/backend/src/tests/modules/teams/repositories/test_member_db_query.py b/backend/src/tests/modules/teams/repositories/test_member_db_query.py index 489172b4..79c82b20 100644 --- a/backend/src/tests/modules/teams/repositories/test_member_db_query.py +++ b/backend/src/tests/modules/teams/repositories/test_member_db_query.py @@ -3,6 +3,7 @@ import pytest from kwai.core.db.database import Database from kwai.core.domain.value_objects.date import Date +from kwai.core.domain.value_objects.unique_id import UniqueId from kwai.modules.teams.domain.team_member import MemberIdentifier from kwai.modules.teams.repositories.member_db_repository import MemberDbQuery from kwai.modules.teams.repositories.member_repository import MemberQuery @@ -25,6 +26,15 @@ async def test_filter_by_id(query: MemberQuery): pytest.fail(f"An exception occurred: {exc}") +async def test_filter_by_uuid(query: MemberQuery): + """Test filtering by uuid.""" + query.filter_by_uuid(UniqueId.generate()) + try: + await query.fetch_one() + except Exception as exc: + pytest.fail(f"An exception occurred: {exc}") + + async def test_filter_by_birthdate_without_end_date(query: MemberQuery): """Test filtering by birthdate.""" query.filter_by_birthdate(Date.create(2015, 1, 1)) From 320baa877d5ef73bcdb381fec444246ab19ed0aa Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 24 Aug 2024 21:23:17 +0200 Subject: [PATCH 173/410] feat: add team member --- backend/src/kwai/api/v1/teams/api.py | 25 ++++++++ backend/src/kwai/api/v1/teams/presenters.py | 10 +++ .../kwai/modules/teams/create_team_member.py | 62 +++++++++++++++++++ .../kwai/modules/teams/domain/team_member.py | 2 +- .../modules/teams/repositories/_tables.py | 11 ++++ .../teams/repositories/team_db_repository.py | 10 ++- .../teams/repositories/team_repository.py | 5 ++ backend/src/tests/api/v1/teams/conftest.py | 4 ++ backend/src/tests/api/v1/teams/test_api.py | 40 ++++++++++++ .../repositories/test_team_db_repository.py | 9 +++ 10 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 backend/src/kwai/modules/teams/create_team_member.py diff --git a/backend/src/kwai/api/v1/teams/api.py b/backend/src/kwai/api/v1/teams/api.py index 8658f119..35454e1f 100644 --- a/backend/src/kwai/api/v1/teams/api.py +++ b/backend/src/kwai/api/v1/teams/api.py @@ -6,6 +6,7 @@ from kwai.api.dependencies import create_database, get_current_user from kwai.api.v1.teams.presenters import ( + JsonApiTeamMemberPresenter, JsonApiTeamMembersPresenter, JsonApiTeamPresenter, JsonApiTeamsPresenter, @@ -15,9 +16,14 @@ from kwai.core.db.uow import UnitOfWork from kwai.modules.identity.users.user import UserEntity from kwai.modules.teams.create_team import CreateTeam, CreateTeamCommand +from kwai.modules.teams.create_team_member import ( + CreateTeamMember, + CreateTeamMemberCommand, +) from kwai.modules.teams.delete_team import DeleteTeam, DeleteTeamCommand from kwai.modules.teams.get_team import GetTeam, GetTeamCommand from kwai.modules.teams.get_teams import GetTeams, GetTeamsCommand +from kwai.modules.teams.repositories.member_db_repository import MemberDbRepository from kwai.modules.teams.repositories.team_db_repository import TeamDbRepository from kwai.modules.teams.update_team import UpdateTeam, UpdateTeamCommand from kwai.modules.training.teams.team_repository import TeamNotFoundException @@ -122,3 +128,22 @@ async def get_team_members( command = GetTeamCommand(id=id) await GetTeam(TeamDbRepository(database), presenter).execute(command) return presenter.get_document() + + +@router.post("/teams/{id}/members", status_code=status.HTTP_201_CREATED) +async def create_team_member( + id: int, + resource: TeamMemberDocument, + database: Annotated[Database, Depends(create_database)], +) -> TeamMemberDocument: + """Add a member to the team with the given id.""" + presenter = JsonApiTeamMemberPresenter() + command = CreateTeamMemberCommand( + team_id=id, + member_id=resource.data.id, + active=resource.data.attributes.active, + ) + await CreateTeamMember( + TeamDbRepository(database), MemberDbRepository(database), presenter + ).execute(command) + return presenter.get_document() diff --git a/backend/src/kwai/api/v1/teams/presenters.py b/backend/src/kwai/api/v1/teams/presenters.py index d936a6a4..dc750c8b 100644 --- a/backend/src/kwai/api/v1/teams/presenters.py +++ b/backend/src/kwai/api/v1/teams/presenters.py @@ -4,6 +4,7 @@ from kwai.core.domain.presenter import AsyncPresenter, IterableResult, Presenter from kwai.core.json_api import JsonApiPresenter, Meta from kwai.modules.teams.domain.team import TeamEntity +from kwai.modules.teams.domain.team_member import TeamMember class JsonApiTeamPresenter(JsonApiPresenter[TeamDocument], Presenter[TeamEntity]): @@ -41,3 +42,12 @@ def present(self, use_case_result: TeamEntity) -> None: for member in use_case_result.members: team_member_document = TeamMemberDocument.create(member) self._document.merge(team_member_document) + + +class JsonApiTeamMemberPresenter( + JsonApiPresenter[TeamMemberDocument], Presenter[TeamMember] +): + """A presenter that transforms a team member into a JSON:API document.""" + + def present(self, use_case_result: TeamMember) -> None: + self._document = TeamMemberDocument.create(use_case_result) diff --git a/backend/src/kwai/modules/teams/create_team_member.py b/backend/src/kwai/modules/teams/create_team_member.py new file mode 100644 index 00000000..dfa38229 --- /dev/null +++ b/backend/src/kwai/modules/teams/create_team_member.py @@ -0,0 +1,62 @@ +"""Module that defines the use case for creating a team member.""" + +from dataclasses import dataclass + +from kwai.core.domain.presenter import Presenter +from kwai.core.domain.value_objects.unique_id import UniqueId +from kwai.modules.teams.domain.team import TeamIdentifier +from kwai.modules.teams.domain.team_member import TeamMember +from kwai.modules.teams.repositories.member_repository import MemberRepository +from kwai.modules.teams.repositories.team_repository import TeamRepository + + +@dataclass(frozen=True, kw_only=True, slots=True) +class CreateTeamMemberCommand: + """Input for the 'Create Team Member' use case.""" + + team_id: int + member_id: str + active: bool = True + + +class CreateTeamMember: + """Implements the 'Create Team Member' use case.""" + + def __init__( + self, + team_repository: TeamRepository, + member_repository: MemberRepository, + presenter: Presenter[TeamMember], + ): + """Initialize the use case. + + Args: + team_repository: A repository for retrieving the team. + member_repository: A repository for retrieving the member. + presenter: A Presenter for processing the result. + """ + self._team_repository = team_repository + self._member_repository = member_repository + self._presenter = presenter + + async def execute(self, command: CreateTeamMemberCommand) -> None: + """Execute the use case. + + Raises: + TeamNotFoundException: If the team does not exist. + MemberNotFoundException: If the member does not exist. + """ + team_query = self._team_repository.create_query().filter_by_id( + TeamIdentifier(command.team_id) + ) + team = await self._team_repository.get(team_query) + + member_query = self._member_repository.create_query().filter_by_uuid( + UniqueId.create_from_string(command.member_id) + ) + member = await self._member_repository.get(member_query) + + team_member = TeamMember(member=member, active=command.active) + await self._team_repository.add_team_member(team, team_member) + + self._presenter.present(team_member) diff --git a/backend/src/kwai/modules/teams/domain/team_member.py b/backend/src/kwai/modules/teams/domain/team_member.py index 8b98ad2d..3f1d07d0 100644 --- a/backend/src/kwai/modules/teams/domain/team_member.py +++ b/backend/src/kwai/modules/teams/domain/team_member.py @@ -84,4 +84,4 @@ class TeamMember: active: bool member: MemberEntity - traceable_time: TraceableTime + traceable_time: TraceableTime = TraceableTime() diff --git a/backend/src/kwai/modules/teams/repositories/_tables.py b/backend/src/kwai/modules/teams/repositories/_tables.py index 1b131430..53e215fb 100644 --- a/backend/src/kwai/modules/teams/repositories/_tables.py +++ b/backend/src/kwai/modules/teams/repositories/_tables.py @@ -97,6 +97,17 @@ def create_team_member(self, member: MemberEntity): ), ) + @classmethod + def persist(cls, team: TeamEntity, team_member: TeamMember) -> Self: + """Persist a team member to the table row.""" + return cls( + team_id=team.id.value, + member_id=team_member.member.id.value, + active=1 if team_member.active else 0, + created_at=team_member.traceable_time.created_at.timestamp, # type: ignore[arg-type] + updated_at=team_member.traceable_time.updated_at.timestamp, + ) + @dataclass(kw_only=True, frozen=True, slots=True) class CountryRow(TableRow): diff --git a/backend/src/kwai/modules/teams/repositories/team_db_repository.py b/backend/src/kwai/modules/teams/repositories/team_db_repository.py index 548523fe..3359402a 100644 --- a/backend/src/kwai/modules/teams/repositories/team_db_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_db_repository.py @@ -15,7 +15,11 @@ from kwai.core.functions import async_groupby from kwai.modules.club.domain.value_objects import Birthdate, Gender, License from kwai.modules.teams.domain.team import TeamEntity, TeamIdentifier -from kwai.modules.teams.domain.team_member import MemberEntity, MemberIdentifier +from kwai.modules.teams.domain.team_member import ( + MemberEntity, + MemberIdentifier, + TeamMember, +) from kwai.modules.teams.repositories._tables import ( CountryRow, MemberPersonRow, @@ -169,3 +173,7 @@ async def update(self, team: TeamEntity) -> TeamEntity: await self._database.update( team.id.value, TeamRow.__table_name__, TeamRow.persist(team) ) + + async def add_team_member(self, team: TeamEntity, member: TeamMember): + team_member_row = TeamMemberRow.persist(team, member) + await self._database.insert(TeamMemberRow.__table_name__, team_member_row) diff --git a/backend/src/kwai/modules/teams/repositories/team_repository.py b/backend/src/kwai/modules/teams/repositories/team_repository.py index b3f34899..003100d9 100644 --- a/backend/src/kwai/modules/teams/repositories/team_repository.py +++ b/backend/src/kwai/modules/teams/repositories/team_repository.py @@ -5,6 +5,7 @@ from kwai.core.domain.repository.query import Query from kwai.modules.teams.domain.team import TeamEntity, TeamIdentifier +from kwai.modules.teams.domain.team_member import TeamMember class TeamNotFoundException(Exception): @@ -71,3 +72,7 @@ async def delete(self, team: TeamEntity) -> None: @abstractmethod async def update(self, team: TeamEntity) -> TeamEntity: """Update a team.""" + + @abstractmethod + async def add_team_member(self, team: TeamEntity, member: TeamMember): + """Add a member to a team.""" diff --git a/backend/src/tests/api/v1/teams/conftest.py b/backend/src/tests/api/v1/teams/conftest.py index d610caeb..32765fb7 100644 --- a/backend/src/tests/api/v1/teams/conftest.py +++ b/backend/src/tests/api/v1/teams/conftest.py @@ -1,3 +1,7 @@ """Module for defining common fixtures for testing the teams endpoints.""" from tests.fixtures.teams.teams import * # noqa +from tests.fixtures.club.countries import * # noqa +from tests.fixtures.club.contacts import * # noqa +from tests.fixtures.club.persons import * # noqa +from tests.fixtures.club.members import * # noqa diff --git a/backend/src/tests/api/v1/teams/test_api.py b/backend/src/tests/api/v1/teams/test_api.py index 2ad13e39..d233e54e 100644 --- a/backend/src/tests/api/v1/teams/test_api.py +++ b/backend/src/tests/api/v1/teams/test_api.py @@ -64,3 +64,43 @@ async def test_update_team(secure_client: TestClient, make_team_in_db): assert ( response.json()["data"]["attributes"]["remark"] == "This is a test" ), "The team should be updated." + + +async def test_get_team_members(secure_client: TestClient, make_team_in_db): + """Test /api/v1/teams//members endpoint for getting a team's members.""" + team = await make_team_in_db() + response = secure_client.get(f"/api/v1/teams/{team.id}/members") + assert response.status_code == status.HTTP_200_OK + + +async def test_create_team_member( + secure_client: TestClient, make_team_in_db, make_member_in_db +): + """Test /api/v1/teams//members endpoint for creating a team's member.""" + team = await make_team_in_db() + member = await make_member_in_db() + payload = { + "data": { + "type": "team_members", + "id": str(member.uuid), + "attributes": { + "active": True, + "first_name": member.person.name.first_name, + "last_name": member.person.name.last_name, + "license_number": member.license.number, + "license_end_date": str(member.license.end_date), + "gender": member.person.gender.value, + "birthdate": str(member.person.birthdate), + }, + "relationships": { + "nationality": { + "data": { + "type": "countries", + "id": str(member.person.nationality.id), + } + } + }, + } + } + response = secure_client.post(f"/api/v1/teams/{team.id}/members", json=payload) + assert response.status_code == status.HTTP_201_CREATED, response.json() diff --git a/backend/src/tests/modules/teams/repositories/test_team_db_repository.py b/backend/src/tests/modules/teams/repositories/test_team_db_repository.py index 24ca8a13..4ca62e9d 100644 --- a/backend/src/tests/modules/teams/repositories/test_team_db_repository.py +++ b/backend/src/tests/modules/teams/repositories/test_team_db_repository.py @@ -52,3 +52,12 @@ async def test_update_team(database: Database, make_team_in_db): team = await team_repo.get(team_repo.create_query().filter_by_id(team.id)) assert team.remark == "This is a test.", "The team should be updated." + + +async def test_add_team_member(database: Database, make_team_in_db, make_team_member): + """Test adding a team member to a team.""" + team_repo = TeamDbRepository(database) + team = await make_team_in_db() + team_member = make_team_member() + + await team_repo.add_team_member(team, team_member) From 67be5536156d8146f249704a8adcdb675da53b69 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 24 Aug 2024 21:23:48 +0200 Subject: [PATCH 174/410] fix: add template for frontend --- backend/templates/index.jinja2 | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 backend/templates/index.jinja2 diff --git a/backend/templates/index.jinja2 b/backend/templates/index.jinja2 new file mode 100644 index 00000000..06c5e27c --- /dev/null +++ b/backend/templates/index.jinja2 @@ -0,0 +1,22 @@ + +{% do vite.init("src/index.ts") %} + + + + + Portal + {% for preload in vite.generate_preloads() %} + {{ preload | safe }} + {% endfor %} + {% for css in vite.generate_css() %} + {{ css | safe }} + {% endfor %} + + +
+
+ {% for js in vite.generate_scripts() %} + {{ js | safe }} + {% endfor %} + + From 1ec2f9a4cd7415c8c5e0af736e21b81d21847a2a Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 24 Aug 2024 22:03:10 +0200 Subject: [PATCH 175/410] fix: add origin to server --- frontend/apps/auth/vite.config.ts | 1 + frontend/apps/author/vite.config.ts | 1 + frontend/apps/club/vite.config.ts | 1 + frontend/apps/coach/vite.config.ts | 1 + 4 files changed, 4 insertions(+) diff --git a/frontend/apps/auth/vite.config.ts b/frontend/apps/auth/vite.config.ts index 0c7a3316..fc046f15 100644 --- a/frontend/apps/auth/vite.config.ts +++ b/frontend/apps/auth/vite.config.ts @@ -32,6 +32,7 @@ export default defineConfig(() => { }, base: '/apps/auth/', server: { + origin: 'http://localhost:3002', host: '0.0.0.0', port: 3002, }, diff --git a/frontend/apps/author/vite.config.ts b/frontend/apps/author/vite.config.ts index 8c20bffc..7abc725a 100644 --- a/frontend/apps/author/vite.config.ts +++ b/frontend/apps/author/vite.config.ts @@ -19,6 +19,7 @@ export default defineConfig(({ mode }) => { pure: mode === 'production' ? ['console.log'] : [], }, server: { + origin: 'http://localhost:3001', host: '0.0.0.0', port: 3001, }, diff --git a/frontend/apps/club/vite.config.ts b/frontend/apps/club/vite.config.ts index 46ee1b3d..db225f9c 100644 --- a/frontend/apps/club/vite.config.ts +++ b/frontend/apps/club/vite.config.ts @@ -16,6 +16,7 @@ export default defineConfig(({ mode }) => { }, base: '/apps/club/', server: { + origin: 'http://localhost:3004', host: '0.0.0.0', port: 3004, }, diff --git a/frontend/apps/coach/vite.config.ts b/frontend/apps/coach/vite.config.ts index 3dcf2ce2..8ac8fa14 100644 --- a/frontend/apps/coach/vite.config.ts +++ b/frontend/apps/coach/vite.config.ts @@ -18,6 +18,7 @@ export default defineConfig(({ mode }) => { pure: mode === 'production' ? ['console.log'] : [], }, server: { + origin: 'http://localhost:3003', host: '0.0.0.0', port: 3003, }, From 5408ea2b8a8c1430f4d591c18cb826c34b95bc9d Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 24 Aug 2024 22:03:44 +0200 Subject: [PATCH 176/410] fix: add auth, author, club frontend applications --- backend/src/kwai/core/settings.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/src/kwai/core/settings.py b/backend/src/kwai/core/settings.py index 03254736..ca586658 100644 --- a/backend/src/kwai/core/settings.py +++ b/backend/src/kwai/core/settings.py @@ -24,8 +24,11 @@ class FrontendApplicationSettings(BaseModel): class FrontendApplications(BaseModel): """All applications.""" - portal: FrontendApplicationSettings + auth: FrontendApplicationSettings + author: FrontendApplicationSettings + club: FrontendApplicationSettings coach: FrontendApplicationSettings + portal: FrontendApplicationSettings class FrontendSettings(BaseModel): From bb0a45f04303ad038990615efb6f44d64b6711fa Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 24 Aug 2024 22:20:08 +0200 Subject: [PATCH 177/410] fix: url must be href --- frontend/apps/club/src/components/ClubToolbar.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/apps/club/src/components/ClubToolbar.vue b/frontend/apps/club/src/components/ClubToolbar.vue index ba2294b7..144b6cc3 100644 --- a/frontend/apps/club/src/components/ClubToolbar.vue +++ b/frontend/apps/club/src/components/ClubToolbar.vue @@ -43,7 +43,7 @@ const logout = () => {
- + Login
From 6fc83dd0ecdf873ba28747ab9b210992b832e162 Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 27 Aug 2024 20:31:48 +0200 Subject: [PATCH 178/410] feat: make it possible to start api+frontend or api only --- backend/src/kwai/__main__.py | 41 +++++++++++++++++++++++++ backend/src/kwai/api/__main__.py | 51 ++++++++++++++++++------------- backend/src/kwai/api/app.py | 19 +++++------- backend/src/kwai/core/args.py | 21 +++++++++++++ backend/src/tests/api/conftest.py | 4 ++- 5 files changed, 102 insertions(+), 34 deletions(-) create mode 100644 backend/src/kwai/__main__.py create mode 100644 backend/src/kwai/core/args.py diff --git a/backend/src/kwai/__main__.py b/backend/src/kwai/__main__.py new file mode 100644 index 00000000..33d71836 --- /dev/null +++ b/backend/src/kwai/__main__.py @@ -0,0 +1,41 @@ +"""Module for starting kwai. + +When this module is used, it will start the api and frontend application. +If only the api is required, use kwai.api. +""" + +from contextlib import asynccontextmanager + +import uvicorn +from fastapi import FastAPI +from loguru import logger + +from kwai.api.app import create_app +from kwai.core.args import create_args +from kwai.frontend.app import create_frontend + +APP_NAME = "kwai" + + +@asynccontextmanager +async def lifespan(app: FastAPI): + """Log the start/stop of the application.""" + logger.info(f"{APP_NAME} is starting") + yield + logger.warning(f"{APP_NAME} has ended!") + + +main_app = FastAPI(title=APP_NAME, lifespan=lifespan) +api_app = create_app() +main_app.mount("/api", api_app) + +frontend_app = create_frontend() +main_app.mount("/", frontend_app) + +args = create_args(APP_NAME) +uvicorn.run( + main_app, + host=args.host, + port=args.port, + reload=args.reload, +) diff --git a/backend/src/kwai/api/__main__.py b/backend/src/kwai/api/__main__.py index 38d3d7ca..bd5fe576 100644 --- a/backend/src/kwai/api/__main__.py +++ b/backend/src/kwai/api/__main__.py @@ -1,31 +1,38 @@ -"""Module for starting the api server.""" -import argparse +"""Module for starting the api server. + +This will only start the api server. Use this when the frontend is not served +by FastAPI or if the api server is running on another server. +""" + +from contextlib import asynccontextmanager import uvicorn +from fastapi import FastAPI +from loguru import logger + +from kwai.core.args import create_args + +APP_NAME = "kwai API" + + +@asynccontextmanager +async def lifespan(app: FastAPI): + """Log the start/stop of the API application. + + Remark: This will only be executed when kwai API is the main application. + """ + logger.info(f"{APP_NAME} is starting") + yield + logger.warning(f"{APP_NAME} has ended!") + + +api_app = FastAPI(title="kwai API", lifespan=lifespan) -def create_args(): - """Parse and create cli arguments.""" - parser = argparse.ArgumentParser(description="kwai backend") - parser.add_argument( - "--reload", - action=argparse.BooleanOptionalAction, - help="Watch for code changes or not", - ) - parser.add_argument( - "--host", type=str, default="0.0.0.0", help="The host of the api server." - ) - parser.add_argument( - "--port", type=int, default=8000, help="The port of the api server." - ) - return parser.parse_args() - - -args = create_args() +args = create_args(APP_NAME) uvicorn.run( - "kwai.api.app:create_app", + api_app, host=args.host, port=args.port, - factory=True, reload=args.reload, ) diff --git a/backend/src/kwai/api/app.py b/backend/src/kwai/api/app.py index 16ea335d..665625af 100644 --- a/backend/src/kwai/api/app.py +++ b/backend/src/kwai/api/app.py @@ -18,7 +18,6 @@ from kwai.api.v1.teams.api import router as teams_api_router from kwai.api.v1.trainings.api import api_router as training_api_router from kwai.core.settings import LoggerSettings, Settings, get_settings -from kwai.frontend.app import create_frontend @asynccontextmanager @@ -66,7 +65,7 @@ def create_app(settings: Settings | None = None) -> FastAPI: Args: settings: Settings to use in this application. """ - app = FastAPI(title="kwai", lifespan=lifespan, separate_input_output_schemas=False) + app = FastAPI(lifespan=lifespan, separate_input_output_schemas=False) if settings is None: settings = get_settings() @@ -113,14 +112,12 @@ async def log(request: Request, call_next): if settings.logger: configure_logger(settings.logger) - app.include_router(auth_api_router, prefix="/api/v1") - app.include_router(portal_api_router, prefix="/api/v1") - app.include_router(pages_api_router, prefix="/api/v1") - app.include_router(news_api_router, prefix="/api/v1") - app.include_router(teams_api_router, prefix="/api/v1") - app.include_router(training_api_router, prefix="/api/v1") - app.include_router(club_api_router, prefix="/api/v1") - - app.mount("/", create_frontend()) + app.include_router(auth_api_router, prefix="/v1") + app.include_router(portal_api_router, prefix="/v1") + app.include_router(pages_api_router, prefix="/v1") + app.include_router(news_api_router, prefix="/v1") + app.include_router(teams_api_router, prefix="/v1") + app.include_router(training_api_router, prefix="/v1") + app.include_router(club_api_router, prefix="/v1") return app diff --git a/backend/src/kwai/core/args.py b/backend/src/kwai/core/args.py new file mode 100644 index 00000000..3d403857 --- /dev/null +++ b/backend/src/kwai/core/args.py @@ -0,0 +1,21 @@ +"""Module for handling arguments for starting a uvicorn application.""" + +import argparse +from argparse import Namespace + + +def create_args(prog: str, default_port: int = 8000) -> Namespace: + """Parse and create cli arguments.""" + parser = argparse.ArgumentParser(prog=prog) + parser.add_argument( + "--reload", + action=argparse.BooleanOptionalAction, + help="Watch for code changes or not", + ) + parser.add_argument( + "--host", type=str, default="0.0.0.0", help="The host of the server." + ) + parser.add_argument( + "--port", type=int, default=default_port, help="The port of the server." + ) + return parser.parse_args() diff --git a/backend/src/tests/api/conftest.py b/backend/src/tests/api/conftest.py index ff7a7eb6..a33427d4 100644 --- a/backend/src/tests/api/conftest.py +++ b/backend/src/tests/api/conftest.py @@ -1,6 +1,7 @@ """Module that defines fixtures for the api tests.""" import pytest +from fastapi import FastAPI from fastapi.testclient import TestClient from kwai.api.app import create_app from kwai.core.settings import get_settings @@ -10,7 +11,8 @@ @pytest.fixture(scope="module") def client() -> TestClient: """Get an HTTP client.""" - app = create_app(get_settings()) + app = FastAPI(title="kwai API -- TEST") + app.mount("/api", create_app(get_settings())) return TestClient(app) From cf78d11af81e04146ac934d1a551e7fbf43916a9 Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 27 Aug 2024 21:20:10 +0200 Subject: [PATCH 179/410] fix: use create methods for the applications --- backend/src/kwai/__main__.py | 28 +++------------------------- backend/src/kwai/api/__main__.py | 25 +++---------------------- backend/src/kwai/api/app.py | 8 +++++--- backend/src/kwai/app.py | 31 +++++++++++++++++++++++++++++++ backend/src/kwai/frontend/app.py | 11 ++++++----- 5 files changed, 48 insertions(+), 55 deletions(-) create mode 100644 backend/src/kwai/app.py diff --git a/backend/src/kwai/__main__.py b/backend/src/kwai/__main__.py index 33d71836..041a4aa7 100644 --- a/backend/src/kwai/__main__.py +++ b/backend/src/kwai/__main__.py @@ -4,38 +4,16 @@ If only the api is required, use kwai.api. """ -from contextlib import asynccontextmanager - import uvicorn -from fastapi import FastAPI -from loguru import logger -from kwai.api.app import create_app +from kwai.app import APP_NAME from kwai.core.args import create_args -from kwai.frontend.app import create_frontend - -APP_NAME = "kwai" - - -@asynccontextmanager -async def lifespan(app: FastAPI): - """Log the start/stop of the application.""" - logger.info(f"{APP_NAME} is starting") - yield - logger.warning(f"{APP_NAME} has ended!") - - -main_app = FastAPI(title=APP_NAME, lifespan=lifespan) -api_app = create_app() -main_app.mount("/api", api_app) - -frontend_app = create_frontend() -main_app.mount("/", frontend_app) args = create_args(APP_NAME) uvicorn.run( - main_app, + "kwai.app:create_app", host=args.host, port=args.port, + factory=True, reload=args.reload, ) diff --git a/backend/src/kwai/api/__main__.py b/backend/src/kwai/api/__main__.py index bd5fe576..4141c5e9 100644 --- a/backend/src/kwai/api/__main__.py +++ b/backend/src/kwai/api/__main__.py @@ -4,35 +4,16 @@ by FastAPI or if the api server is running on another server. """ -from contextlib import asynccontextmanager - import uvicorn -from fastapi import FastAPI -from loguru import logger +from kwai.api.app import APP_NAME from kwai.core.args import create_args -APP_NAME = "kwai API" - - -@asynccontextmanager -async def lifespan(app: FastAPI): - """Log the start/stop of the API application. - - Remark: This will only be executed when kwai API is the main application. - """ - logger.info(f"{APP_NAME} is starting") - yield - logger.warning(f"{APP_NAME} has ended!") - - -api_app = FastAPI(title="kwai API", lifespan=lifespan) - - args = create_args(APP_NAME) uvicorn.run( - api_app, + "kwai.api.app.create_api", host=args.host, port=args.port, + factory=True, reload=args.reload, ) diff --git a/backend/src/kwai/api/app.py b/backend/src/kwai/api/app.py index 665625af..cc1dcb01 100644 --- a/backend/src/kwai/api/app.py +++ b/backend/src/kwai/api/app.py @@ -19,13 +19,15 @@ from kwai.api.v1.trainings.api import api_router as training_api_router from kwai.core.settings import LoggerSettings, Settings, get_settings +APP_NAME = "kwai API" + @asynccontextmanager async def lifespan(app: FastAPI): """Log the start/stop of the application.""" - logger.info("kwai is starting") + logger.info(f"{APP_NAME} is starting") yield - logger.warning("kwai has ended!") + logger.warning(f"{APP_NAME} has ended!") def configure_logger(settings: LoggerSettings): @@ -59,7 +61,7 @@ def log_format(record): ) -def create_app(settings: Settings | None = None) -> FastAPI: +def create_api(settings: Settings | None = None) -> FastAPI: """Create the FastAPI application. Args: diff --git a/backend/src/kwai/app.py b/backend/src/kwai/app.py new file mode 100644 index 00000000..aa21078e --- /dev/null +++ b/backend/src/kwai/app.py @@ -0,0 +1,31 @@ +"""Module that creates a FastAPI application for the API and Frontend.""" + +from contextlib import asynccontextmanager + +from fastapi import FastAPI +from loguru import logger + +from kwai.api.app import create_api +from kwai.frontend.app import create_frontend + +APP_NAME = "kwai" + + +@asynccontextmanager +async def lifespan(app: FastAPI): + """Log the start/stop of the application.""" + logger.info(f"{APP_NAME} is starting") + yield + logger.warning(f"{APP_NAME} has ended!") + + +def create_app() -> FastAPI: + """Create the FastAPI application for API and frontend.""" + main_app = FastAPI(title=APP_NAME, lifespan=lifespan) + api_app = create_api() + main_app.mount("/api", api_app) + + frontend_app = create_frontend() + main_app.mount("/", frontend_app) + + return main_app diff --git a/backend/src/kwai/frontend/app.py b/backend/src/kwai/frontend/app.py index 8a8aa123..43ed6365 100644 --- a/backend/src/kwai/frontend/app.py +++ b/backend/src/kwai/frontend/app.py @@ -89,15 +89,11 @@ def create_frontend(): """Create the frontend.""" frontend_app = FastAPI() - @frontend_app.get("/") - async def get_root(settings: Annotated[Settings, Depends(get_settings)]): - """Redirect the root path to the portal application.""" - return RedirectResponse(f"/apps/{settings.frontend.root_app}") - @frontend_app.middleware("http") async def log(request: Request, call_next): """Middleware for logging the requests.""" request_id = str(uuid.uuid4()) + print("LOGGING!!!") with logger.contextualize(request_id=request_id): logger.info(f"{request.url} - {request.method} - Request started") @@ -122,6 +118,11 @@ async def log(request: Request, call_next): return response + @frontend_app.get("/") + async def get_root(settings: Annotated[Settings, Depends(get_settings)]): + """Redirect the root path to the portal application.""" + return RedirectResponse(f"/apps/{settings.frontend.root_app}") + kwai_settings = get_settings() for application in FrontendApplicationName.list(): create_frontend_app(frontend_app, kwai_settings, application) From c73f56468f42fa712a9a26cde73a290fa83a0429 Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 27 Aug 2024 21:33:23 +0200 Subject: [PATCH 180/410] fix: remove print --- backend/src/kwai/frontend/app.py | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/kwai/frontend/app.py b/backend/src/kwai/frontend/app.py index 43ed6365..b894e2c0 100644 --- a/backend/src/kwai/frontend/app.py +++ b/backend/src/kwai/frontend/app.py @@ -93,7 +93,6 @@ def create_frontend(): async def log(request: Request, call_next): """Middleware for logging the requests.""" request_id = str(uuid.uuid4()) - print("LOGGING!!!") with logger.contextualize(request_id=request_id): logger.info(f"{request.url} - {request.method} - Request started") From b6ded9c692caee8f99d6208e291a8683742c7773 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 30 Aug 2024 20:57:26 +0200 Subject: [PATCH 181/410] refactor: use routers and dependencies for the frontend --- backend/src/kwai/app.py | 1 + backend/src/kwai/frontend/app.py | 92 ++-------------------- backend/src/kwai/frontend/apps/__init__.py | 19 +++++ backend/src/kwai/frontend/apps/_auth.py | 44 +++++++++++ backend/src/kwai/frontend/apps/_author.py | 44 +++++++++++ backend/src/kwai/frontend/apps/_club.py | 44 +++++++++++ backend/src/kwai/frontend/apps/_coach.py | 44 +++++++++++ backend/src/kwai/frontend/apps/_portal.py | 44 +++++++++++ backend/src/kwai/frontend/dependencies.py | 61 ++++++++++++++ 9 files changed, 306 insertions(+), 87 deletions(-) create mode 100644 backend/src/kwai/frontend/apps/__init__.py create mode 100644 backend/src/kwai/frontend/apps/_auth.py create mode 100644 backend/src/kwai/frontend/apps/_author.py create mode 100644 backend/src/kwai/frontend/apps/_club.py create mode 100644 backend/src/kwai/frontend/apps/_coach.py create mode 100644 backend/src/kwai/frontend/apps/_portal.py create mode 100644 backend/src/kwai/frontend/dependencies.py diff --git a/backend/src/kwai/app.py b/backend/src/kwai/app.py index aa21078e..c2f10e0a 100644 --- a/backend/src/kwai/app.py +++ b/backend/src/kwai/app.py @@ -22,6 +22,7 @@ async def lifespan(app: FastAPI): def create_app() -> FastAPI: """Create the FastAPI application for API and frontend.""" main_app = FastAPI(title=APP_NAME, lifespan=lifespan) + api_app = create_api() main_app.mount("/api", api_app) diff --git a/backend/src/kwai/frontend/app.py b/backend/src/kwai/frontend/app.py index b894e2c0..e88434e6 100644 --- a/backend/src/kwai/frontend/app.py +++ b/backend/src/kwai/frontend/app.py @@ -1,88 +1,12 @@ """Module that defines a sub application for handling the frontend.""" import uuid -from enum import Enum -from pathlib import Path -from typing import Annotated -from fastapi import Depends, FastAPI, HTTPException, Request, status -from fastapi.responses import JSONResponse, RedirectResponse -from fastapi.staticfiles import StaticFiles -from fastapi.templating import Jinja2Templates +from fastapi import FastAPI, Request, status +from fastapi.responses import JSONResponse from loguru import logger -from kwai.api.dependencies import create_templates -from kwai.core.settings import Settings, get_settings -from kwai.frontend.vite import DevelopmentVite, ProductionVite - - -class FrontendApplicationName(str, Enum): - """Defines all available frontend application names.""" - - auth = "auth" - author = "author" - club = "club" - coach = "coach" - portal = "portal" - - @classmethod - def list(cls): - """List all available frontend application names.""" - return [c.value for c in cls] - - -def create_frontend_app(frontend_app: FastAPI, settings: Settings, application: str): - """Create a frontend for an application.""" - # Public files - root_path = Path(settings.frontend.path) / "apps" / application / "dist" - frontend_app.mount(f"/apps/{application}/public", StaticFiles(directory=root_path)) - # Assets - frontend_app.mount( - f"/apps/{application}/assets", StaticFiles(directory=root_path / "assets") - ) - - @frontend_app.get("/apps/{app}/{router:path}") - async def get_app( - request: Request, - templates: Annotated[Jinja2Templates, Depends(create_templates)], - app: FrontendApplicationName, - ): - """Get the html page for a given frontend application. - - Remark: the router:path is required for handling a refresh on a vue-router page. - """ - if not hasattr(settings.frontend.apps, app): - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail=f"Application {app} does not exist.", - ) - - app_setting = getattr(settings.frontend.apps, app) - - if settings.frontend.test: - if app_setting.base_dev is None: - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail=f"Setting base_dev not set for application {app}", - ) - vite = DevelopmentVite(app_setting.base_dev) - else: - manifest_path = root_path / "manifest.json" - if not manifest_path.exists(): - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail=f"Manifest file {manifest_path} not found", - ) - vite = ProductionVite(manifest_path, app_setting.base) - - return templates.TemplateResponse( - "index.jinja2", - { - "request": request, - "settings": settings, - "vite": vite, - }, - ) +from kwai.frontend.apps import apps_router, portal_router def create_frontend(): @@ -117,13 +41,7 @@ async def log(request: Request, call_next): return response - @frontend_app.get("/") - async def get_root(settings: Annotated[Settings, Depends(get_settings)]): - """Redirect the root path to the portal application.""" - return RedirectResponse(f"/apps/{settings.frontend.root_app}") - - kwai_settings = get_settings() - for application in FrontendApplicationName.list(): - create_frontend_app(frontend_app, kwai_settings, application) + frontend_app.include_router(apps_router, prefix="/apps") + frontend_app.include_router(portal_router) return frontend_app diff --git a/backend/src/kwai/frontend/apps/__init__.py b/backend/src/kwai/frontend/apps/__init__.py new file mode 100644 index 00000000..247a1f2c --- /dev/null +++ b/backend/src/kwai/frontend/apps/__init__.py @@ -0,0 +1,19 @@ +"""Package for defining the routes for all frontend applications.""" + +from fastapi import APIRouter + +from kwai.frontend.apps._auth import router as auth_router +from kwai.frontend.apps._author import router as author_router +from kwai.frontend.apps._club import router as club_router +from kwai.frontend.apps._coach import router as coach_router +from kwai.frontend.apps._portal import router as portal_router + +# All routers, except for the portal, because that will be added as root by the frontend +# application. +apps_router = APIRouter() +apps_router.include_router(auth_router) +apps_router.include_router(author_router) +apps_router.include_router(club_router) +apps_router.include_router(coach_router) + +__all__ = ["apps_router", "portal_router"] diff --git a/backend/src/kwai/frontend/apps/_auth.py b/backend/src/kwai/frontend/apps/_auth.py new file mode 100644 index 00000000..6f8267bc --- /dev/null +++ b/backend/src/kwai/frontend/apps/_auth.py @@ -0,0 +1,44 @@ +"""Module that defines the routes for the authentication frontend application.""" + +from pathlib import Path +from typing import Annotated + +from fastapi import APIRouter, Depends, Request +from fastapi.staticfiles import StaticFiles +from fastapi.templating import Jinja2Templates + +from kwai.api.dependencies import create_templates +from kwai.core.settings import FrontendApplicationSettings, get_settings +from kwai.frontend.dependencies import FrontendApplicationDependency, ViteDependency +from kwai.frontend.vite import Vite + +APP_NAME = "auth" + +router = APIRouter(prefix=f"/{APP_NAME}") + +_auth_dependency = FrontendApplicationDependency(APP_NAME) +_auth_vite_dependency = ViteDependency(APP_NAME) + +settings = get_settings() +if not settings.frontend.test: + root_path = Path(settings.frontend.path) / "apps" / APP_NAME / "dist" + # Public files + router.mount("/public", StaticFiles(directory=root_path)) + # Assets + router.mount("/assets", StaticFiles(directory=root_path / "assets")) + + +@router.get("/{router:path}") +async def get_app( + request: Request, + templates: Annotated[Jinja2Templates, Depends(create_templates)], + app_settings: Annotated[FrontendApplicationSettings, Depends(_auth_dependency)], + vite: Annotated[Vite, Depends(_auth_vite_dependency)], +): + return templates.TemplateResponse( + "index.jinja2", + { + "request": request, + "vite": vite, + }, + ) diff --git a/backend/src/kwai/frontend/apps/_author.py b/backend/src/kwai/frontend/apps/_author.py new file mode 100644 index 00000000..0d264b2b --- /dev/null +++ b/backend/src/kwai/frontend/apps/_author.py @@ -0,0 +1,44 @@ +"""Module that defines the routes for the author frontend application.""" + +from pathlib import Path +from typing import Annotated + +from fastapi import APIRouter, Depends, Request +from fastapi.staticfiles import StaticFiles +from fastapi.templating import Jinja2Templates + +from kwai.api.dependencies import create_templates +from kwai.core.settings import FrontendApplicationSettings, get_settings +from kwai.frontend.dependencies import FrontendApplicationDependency, ViteDependency +from kwai.frontend.vite import Vite + +APP_NAME = "author" + +router = APIRouter(prefix=f"/{APP_NAME}") + +_auth_dependency = FrontendApplicationDependency(APP_NAME) +_auth_vite_dependency = ViteDependency(APP_NAME) + +settings = get_settings() +if not settings.frontend.test: + root_path = Path(settings.frontend.path) / "apps" / APP_NAME / "dist" + # Public files + router.mount("/public", StaticFiles(directory=root_path)) + # Assets + router.mount("/assets", StaticFiles(directory=root_path / "assets")) + + +@router.get("/{router:path}") +async def get_app( + request: Request, + templates: Annotated[Jinja2Templates, Depends(create_templates)], + app_settings: Annotated[FrontendApplicationSettings, Depends(_auth_dependency)], + vite: Annotated[Vite, Depends(_auth_vite_dependency)], +): + return templates.TemplateResponse( + "index.jinja2", + { + "request": request, + "vite": vite, + }, + ) diff --git a/backend/src/kwai/frontend/apps/_club.py b/backend/src/kwai/frontend/apps/_club.py new file mode 100644 index 00000000..a76a1848 --- /dev/null +++ b/backend/src/kwai/frontend/apps/_club.py @@ -0,0 +1,44 @@ +"""Module that defines the routes for the club frontend application.""" + +from pathlib import Path +from typing import Annotated + +from fastapi import APIRouter, Depends, Request +from fastapi.staticfiles import StaticFiles +from fastapi.templating import Jinja2Templates + +from kwai.api.dependencies import create_templates +from kwai.core.settings import FrontendApplicationSettings, get_settings +from kwai.frontend.dependencies import FrontendApplicationDependency, ViteDependency +from kwai.frontend.vite import Vite + +APP_NAME = "club" + +router = APIRouter(prefix=f"/{APP_NAME}") + +_club_dependency = FrontendApplicationDependency(APP_NAME) +_club_vite_dependency = ViteDependency(APP_NAME) + +settings = get_settings() +if not settings.frontend.test: + root_path = Path(settings.frontend.path) / "apps" / APP_NAME / "dist" + # Public files + router.mount("/public", StaticFiles(directory=root_path)) + # Assets + router.mount("/assets", StaticFiles(directory=root_path / "assets")) + + +@router.get("/{router:path}") +async def get_app( + request: Request, + templates: Annotated[Jinja2Templates, Depends(create_templates)], + app_settings: Annotated[FrontendApplicationSettings, Depends(_club_dependency)], + vite: Annotated[Vite, Depends(_club_vite_dependency)], +): + return templates.TemplateResponse( + "index.jinja2", + { + "request": request, + "vite": vite, + }, + ) diff --git a/backend/src/kwai/frontend/apps/_coach.py b/backend/src/kwai/frontend/apps/_coach.py new file mode 100644 index 00000000..f7b4d64b --- /dev/null +++ b/backend/src/kwai/frontend/apps/_coach.py @@ -0,0 +1,44 @@ +"""Module that defines the routes for the coach frontend application.""" + +from pathlib import Path +from typing import Annotated + +from fastapi import APIRouter, Depends, Request +from fastapi.staticfiles import StaticFiles +from fastapi.templating import Jinja2Templates + +from kwai.api.dependencies import create_templates +from kwai.core.settings import FrontendApplicationSettings, get_settings +from kwai.frontend.dependencies import FrontendApplicationDependency, ViteDependency +from kwai.frontend.vite import Vite + +APP_NAME = "coach" + +router = APIRouter(prefix=f"/{APP_NAME}") + +_club_dependency = FrontendApplicationDependency(APP_NAME) +_club_vite_dependency = ViteDependency(APP_NAME) + +settings = get_settings() +if not settings.frontend.test: + root_path = Path(settings.frontend.path) / "apps" / APP_NAME / "dist" + # Public files + router.mount("/public", StaticFiles(directory=root_path)) + # Assets + router.mount("/assets", StaticFiles(directory=root_path / "assets")) + + +@router.get("/{router:path}") +async def get_app( + request: Request, + templates: Annotated[Jinja2Templates, Depends(create_templates)], + app_settings: Annotated[FrontendApplicationSettings, Depends(_club_dependency)], + vite: Annotated[Vite, Depends(_club_vite_dependency)], +): + return templates.TemplateResponse( + "index.jinja2", + { + "request": request, + "vite": vite, + }, + ) diff --git a/backend/src/kwai/frontend/apps/_portal.py b/backend/src/kwai/frontend/apps/_portal.py new file mode 100644 index 00000000..59fc2699 --- /dev/null +++ b/backend/src/kwai/frontend/apps/_portal.py @@ -0,0 +1,44 @@ +"""Module that defines the routes for the portal frontend application.""" + +from pathlib import Path +from typing import Annotated + +from fastapi import APIRouter, Depends, Request +from fastapi.staticfiles import StaticFiles +from fastapi.templating import Jinja2Templates + +from kwai.api.dependencies import create_templates +from kwai.core.settings import FrontendApplicationSettings, get_settings +from kwai.frontend.dependencies import FrontendApplicationDependency, ViteDependency +from kwai.frontend.vite import Vite + +APP_NAME = "portal" + +router = APIRouter() + +_portal_dependency = FrontendApplicationDependency(APP_NAME) +_portal_vite_dependency = ViteDependency(APP_NAME) + +settings = get_settings() +if not settings.frontend.test: + root_path = Path(settings.frontend.path) / "apps" / APP_NAME / "dist" + # Public files + router.mount("/public", StaticFiles(directory=root_path)) + # Assets + router.mount("/assets", StaticFiles(directory=root_path / "assets")) + + +@router.get("/{router:path}") +async def get_app( + request: Request, + templates: Annotated[Jinja2Templates, Depends(create_templates)], + app_settings: Annotated[FrontendApplicationSettings, Depends(_portal_dependency)], + vite: Annotated[Vite, Depends(_portal_vite_dependency)], +): + return templates.TemplateResponse( + "index.jinja2", + { + "request": request, + "vite": vite, + }, + ) diff --git a/backend/src/kwai/frontend/dependencies.py b/backend/src/kwai/frontend/dependencies.py new file mode 100644 index 00000000..f3d27f33 --- /dev/null +++ b/backend/src/kwai/frontend/dependencies.py @@ -0,0 +1,61 @@ +"""Module for defining dependencies for the frontend applications.""" + +from pathlib import Path +from typing import Annotated + +from fastapi import Depends, HTTPException, status + +from kwai.core.settings import FrontendApplicationSettings, Settings, get_settings +from kwai.frontend.vite import DevelopmentVite, ProductionVite, Vite + + +class FrontendApplicationDependency: + """A dependency that gets the applications settings.""" + + def __init__(self, application_name: str): + self._application_name = application_name + + def __call__( + self, settings: Annotated[Settings, Depends(get_settings)] + ) -> FrontendApplicationSettings: + """Get the settings for the application.""" + if not hasattr(settings.frontend.apps, self._application_name): + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Application {self._application_name} does not exist.", + ) + + return getattr(settings.frontend.apps, self._application_name) + + +class ViteDependency: + """Vite is a dependency.""" + + def __init__(self, application_name: str): + self._application_name = application_name + + def __call__(self, settings: Annotated[Settings, Depends(get_settings)]) -> Vite: + """Create a Vite environment for this application.""" + app_setting = getattr(settings.frontend.apps, self._application_name) + if settings.frontend.test: + if app_setting.base_dev is None: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f"Setting base_dev not set for application {self._application_name}", + ) + return DevelopmentVite(app_setting.base_dev) + + manifest_path = ( + Path(settings.frontend.path) + / "apps" + / self._application_name + / "dist" + / "manifest.json" + ) + if not manifest_path.exists(): + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Manifest file {manifest_path} not found", + ) + + return ProductionVite(manifest_path, app_setting.base) From 2af38417fad7e4f3bc842485b0734310a35dafb2 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 31 Aug 2024 20:29:46 +0200 Subject: [PATCH 182/410] fix: /apps/portal doesn't work on root / --- backend/src/kwai/frontend/app.py | 13 +++++++++---- backend/src/kwai/frontend/apps/__init__.py | 3 +-- backend/src/kwai/frontend/apps/_portal.py | 3 ++- frontend/apps/portal/vite.config.ts | 2 +- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/backend/src/kwai/frontend/app.py b/backend/src/kwai/frontend/app.py index e88434e6..86340989 100644 --- a/backend/src/kwai/frontend/app.py +++ b/backend/src/kwai/frontend/app.py @@ -1,12 +1,14 @@ """Module that defines a sub application for handling the frontend.""" import uuid +from typing import Annotated -from fastapi import FastAPI, Request, status -from fastapi.responses import JSONResponse +from fastapi import Depends, FastAPI, Request, status +from fastapi.responses import JSONResponse, RedirectResponse from loguru import logger -from kwai.frontend.apps import apps_router, portal_router +from kwai.core.settings import Settings, get_settings +from kwai.frontend.apps import apps_router def create_frontend(): @@ -42,6 +44,9 @@ async def log(request: Request, call_next): return response frontend_app.include_router(apps_router, prefix="/apps") - frontend_app.include_router(portal_router) + + @frontend_app.get("/") + def root(settings: Annotated[Settings, Depends(get_settings)]): + return RedirectResponse(f"/apps/{settings.frontend.root_app}") return frontend_app diff --git a/backend/src/kwai/frontend/apps/__init__.py b/backend/src/kwai/frontend/apps/__init__.py index 247a1f2c..9f7ac60f 100644 --- a/backend/src/kwai/frontend/apps/__init__.py +++ b/backend/src/kwai/frontend/apps/__init__.py @@ -15,5 +15,4 @@ apps_router.include_router(author_router) apps_router.include_router(club_router) apps_router.include_router(coach_router) - -__all__ = ["apps_router", "portal_router"] +apps_router.include_router(portal_router) diff --git a/backend/src/kwai/frontend/apps/_portal.py b/backend/src/kwai/frontend/apps/_portal.py index 59fc2699..5140a83d 100644 --- a/backend/src/kwai/frontend/apps/_portal.py +++ b/backend/src/kwai/frontend/apps/_portal.py @@ -14,7 +14,7 @@ APP_NAME = "portal" -router = APIRouter() +router = APIRouter(prefix=f"/{APP_NAME}") _portal_dependency = FrontendApplicationDependency(APP_NAME) _portal_vite_dependency = ViteDependency(APP_NAME) @@ -35,6 +35,7 @@ async def get_app( app_settings: Annotated[FrontendApplicationSettings, Depends(_portal_dependency)], vite: Annotated[Vite, Depends(_portal_vite_dependency)], ): + print("Portal???") return templates.TemplateResponse( "index.jinja2", { diff --git a/frontend/apps/portal/vite.config.ts b/frontend/apps/portal/vite.config.ts index dd61fea0..2f20a282 100644 --- a/frontend/apps/portal/vite.config.ts +++ b/frontend/apps/portal/vite.config.ts @@ -28,7 +28,7 @@ export default defineConfig(() => { } }, }, - base: '/apps/portal', + base: '/apps/portal/', server: { origin: 'http://localhost:3000', host: '0.0.0.0', From 49ddc93c5eceb48186969808a5c59172ebbc03f4 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 2 Sep 2024 20:16:12 +0200 Subject: [PATCH 183/410] fix: redirect /news and /pages --- backend/src/kwai/frontend/app.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/backend/src/kwai/frontend/app.py b/backend/src/kwai/frontend/app.py index 86340989..a06f6b28 100644 --- a/backend/src/kwai/frontend/app.py +++ b/backend/src/kwai/frontend/app.py @@ -1,6 +1,7 @@ """Module that defines a sub application for handling the frontend.""" import uuid +from pathlib import Path from typing import Annotated from fastapi import Depends, FastAPI, Request, status @@ -45,8 +46,27 @@ async def log(request: Request, call_next): frontend_app.include_router(apps_router, prefix="/apps") + @frontend_app.get("/news/{path:path}") + def news(path: Path, settings: Annotated[Settings, Depends(get_settings)]): + """Redirect the news path to the portal application. + + When FastAPI serves the frontend, the root path can't be used for the portal. + So redirect this url to the root application. + """ + return RedirectResponse(f"/apps/{settings.frontend.root_app}/news/{path}") + + @frontend_app.get("/pages/{path:path}") + def pages(path: Path, settings: Annotated[Settings, Depends(get_settings)]): + """Redirect the pages path to the portal application. + + When FastAPI serves the frontend, the root path can't be used for the portal. + So redirect this url to the root application. + """ + return RedirectResponse(f"/apps/{settings.frontend.root_app}/pages/{path}") + @frontend_app.get("/") def root(settings: Annotated[Settings, Depends(get_settings)]): + """Redirect index to the portal application.""" return RedirectResponse(f"/apps/{settings.frontend.root_app}") return frontend_app From a497c64bed2adea19aa525e18f1caedf46b14088 Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 2 Sep 2024 20:31:17 +0200 Subject: [PATCH 184/410] fix: remove print --- backend/src/kwai/frontend/apps/_portal.py | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/kwai/frontend/apps/_portal.py b/backend/src/kwai/frontend/apps/_portal.py index 5140a83d..b79d0b36 100644 --- a/backend/src/kwai/frontend/apps/_portal.py +++ b/backend/src/kwai/frontend/apps/_portal.py @@ -35,7 +35,6 @@ async def get_app( app_settings: Annotated[FrontendApplicationSettings, Depends(_portal_dependency)], vite: Annotated[Vite, Depends(_portal_vite_dependency)], ): - print("Portal???") return templates.TemplateResponse( "index.jinja2", { From a9ed8821fbcbaa36845a14ff0f6f31c51407723c Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 3 Sep 2024 19:26:27 +0200 Subject: [PATCH 185/410] docs: remove obsolete comment --- backend/src/kwai/frontend/apps/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/backend/src/kwai/frontend/apps/__init__.py b/backend/src/kwai/frontend/apps/__init__.py index 9f7ac60f..9149d679 100644 --- a/backend/src/kwai/frontend/apps/__init__.py +++ b/backend/src/kwai/frontend/apps/__init__.py @@ -8,8 +8,6 @@ from kwai.frontend.apps._coach import router as coach_router from kwai.frontend.apps._portal import router as portal_router -# All routers, except for the portal, because that will be added as root by the frontend -# application. apps_router = APIRouter() apps_router.include_router(auth_router) apps_router.include_router(author_router) From 04c58d3b7f5291129e0400902aa64745c8139912 Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 4 Sep 2024 21:26:12 +0200 Subject: [PATCH 186/410] feat: list teams --- frontend/apps/club/src/composables/useTeam.ts | 90 +++++++++++++++++++ frontend/apps/club/src/locales/nl.yaml | 5 ++ .../apps/club/src/pages/teams/TeamsPage.vue | 86 ++++++++++++++++++ frontend/apps/club/src/types/team.ts | 6 ++ 4 files changed, 187 insertions(+) create mode 100644 frontend/apps/club/src/composables/useTeam.ts create mode 100644 frontend/apps/club/src/pages/teams/TeamsPage.vue create mode 100644 frontend/apps/club/src/types/team.ts diff --git a/frontend/apps/club/src/composables/useTeam.ts b/frontend/apps/club/src/composables/useTeam.ts new file mode 100644 index 00000000..8ba14468 --- /dev/null +++ b/frontend/apps/club/src/composables/useTeam.ts @@ -0,0 +1,90 @@ +import type { Team } from '@root/types/team'; +import { JsonApiData, JsonApiDocument, useHttpApi } from '@kwai/api'; +import { z } from 'zod'; +import { type Ref, ref, toValue } from 'vue'; +import { useQuery } from '@tanstack/vue-query'; + +export interface Teams { + meta: { + count: number, + offset: number, + limit: number + }, + items: Team[] +} + +const TeamResourceSchema = JsonApiData.extend({ + type: z.literal('teams'), + attributes: z.object({ + name: z.string(), + active: z.boolean(), + remark: z.string(), + }), +}); + +type TeamResource = z.infer; + +export const TeamDocumentSchema = JsonApiDocument.extend({ + data: z.union([ + TeamResourceSchema, + z.array(TeamResourceSchema).default([]), + ]), +}); +type TeamDocument = z.infer; + +const transform = (doc: TeamDocument) : Team | Teams => { + const mapModel = (data: TeamResource): Team => { + return { + id: data.id, + name: data.attributes.name, + active: data.attributes.active, + remark: data.attributes.remark, + }; + }; + if (Array.isArray(doc.data)) { + return { + meta: { + count: doc.meta?.count || 0, + offset: doc.meta?.offset || 0, + limit: doc.meta?.limit || 0, + }, + items: doc.data.map(mapModel), + }; + } + return mapModel(doc.data); +}; + +const getTeams = async({ + offset = null, + limit = null, +} : { + offset?: number | null, + limit?: number | null, +}) => { + let api = useHttpApi().url('/v1/teams'); + if (offset) { + api = api.query({ 'page[offset]': offset }); + } + if (limit) { + api = api.query({ 'page[limit]': limit }); + } + return api.get().json().then(json => { + const result = TeamDocumentSchema.safeParse(json); + if (result.success) { + return transform(result.data) as Teams; + } + console.log(result.error); + throw result.error; + }); +}; + +export const useTeams = ({ offset = ref(0), limit = ref(0) } : { offset?: Ref, limit?: Ref}) => { + const queryKey : { offset: Ref, limit: Ref } = { offset, limit }; + return useQuery({ + queryKey: ['club/teams', queryKey], + queryFn: () => getTeams({ + offset: toValue(offset), + limit: toValue(limit), + }), + }); +}; diff --git a/frontend/apps/club/src/locales/nl.yaml b/frontend/apps/club/src/locales/nl.yaml index 7bb49244..15b31e90 100644 --- a/frontend/apps/club/src/locales/nl.yaml +++ b/frontend/apps/club/src/locales/nl.yaml @@ -20,3 +20,8 @@ members_upload: Opgelet er zijn fouten gevonden in het opgeladen bestand! row: Rij description: Omschrijving +teams: + title: Teams + error: Er is een fout gebeurd tijdens het ophalen van de teams. + name: Naam + remark: Opmerking diff --git a/frontend/apps/club/src/pages/teams/TeamsPage.vue b/frontend/apps/club/src/pages/teams/TeamsPage.vue new file mode 100644 index 00000000..2b8b9917 --- /dev/null +++ b/frontend/apps/club/src/pages/teams/TeamsPage.vue @@ -0,0 +1,86 @@ + + + + + diff --git a/frontend/apps/club/src/types/team.ts b/frontend/apps/club/src/types/team.ts new file mode 100644 index 00000000..b7c9e487 --- /dev/null +++ b/frontend/apps/club/src/types/team.ts @@ -0,0 +1,6 @@ +export interface Team { + id?: string, + name: string, + active: boolean, + remark: string +} From e52f3bb2173e42ba9d16b32096dc63b5147768a0 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 6 Sep 2024 16:40:54 +0200 Subject: [PATCH 187/410] refactor: eslint --- frontend/.eslintrc.cjs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/frontend/.eslintrc.cjs b/frontend/.eslintrc.cjs index fe6deb67..727bcd01 100644 --- a/frontend/.eslintrc.cjs +++ b/frontend/.eslintrc.cjs @@ -1,13 +1,13 @@ module.exports = { - root: true, - // This tells ESLint to load the config from the package `eslint-config-kwai` - extends: ['kwai'], - settings: { - next: { - rootDir: [ - 'apps/*/', - 'packages/*/' - ], - }, + root: true, + // This tells ESLint to load the config from the package `eslint-config-kwai` + extends: ['kwai'], + settings: { + next: { + rootDir: [ + 'apps/*/', + 'packages/*/', + ], }, -}; \ No newline at end of file + }, +}; From 698a5d6ffa289cbb96d05116485289e7c77aca38 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 7 Sep 2024 20:50:16 +0200 Subject: [PATCH 188/410] feat: add transformResourceArrayToObject --- frontend/packages/kwai-api/src/index.ts | 47 +++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/frontend/packages/kwai-api/src/index.ts b/frontend/packages/kwai-api/src/index.ts index 5bdb2ea8..c9eb4cee 100644 --- a/frontend/packages/kwai-api/src/index.ts +++ b/frontend/packages/kwai-api/src/index.ts @@ -51,6 +51,53 @@ export const JsonApiDocument = z.object({ }); export type JsonApiDocumentType = z.infer; +/** + * Transforms an array of resources in a nested object. + * + * This object makes it easier to lookup included resources. When, for example, a team resource + * has team members, the included array will contain resources for the team members but also + * country resources for the nationality of these team members. In this example, the returned + * object will have two properties: team_members and countries. The value of these properties will + * be another object with all the resources. The property for each resource will be the id of the resource. + * + * { + * team_members: { + * '1': { + * type: 'team_members', + * id: '1', + * attributes: { + * name: 'Jigoro Kano', + * }, + * relationships: { + * nationality: { + * data: { type: 'countries', 'id': '1' } + * } + * } + * } + * }, + * countries: { + * '1': { + * type: 'countries', + * id: '1', + * attributes: { + * name: 'Japan' + * } + * } + * } + * } + * + * @param resources + */ +export const transformResourceArrayToObject = (resources: JsonApiDataType[]): Record> => { + return resources.reduce((acc: Record>, current) => { + if (!acc[current.type]) { + acc[current.type] = {}; + } + acc[current.type][current.id as string] = current; + return acc; + }, {}); +}; + export interface LocalStorage { loginRedirect: Ref, accessToken: Ref, From b3270478485ca31d231809920708e6a352efeb10 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 7 Sep 2024 20:50:49 +0200 Subject: [PATCH 189/410] ci: vitest --- frontend/package-lock.json | 1097 ++++++++++++++++++++++++++++++++++-- 1 file changed, 1064 insertions(+), 33 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index c5c836e1..6c5203a9 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -126,6 +126,7 @@ "@tanstack/vue-query": "^5.32.0", "@vueuse/core": "^10.9.0", "vee-validate": "^4.12.6", + "vitest": "^2.0.5", "vue": "^3.4.25", "vue-i18n": "^9.13.1", "vue-router": "^4.3.2", @@ -140,6 +141,336 @@ "vue-tsc": "^1.8.27" } }, + "apps/club/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "apps/club/node_modules/@intlify/unplugin-vue-i18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@intlify/unplugin-vue-i18n/-/unplugin-vue-i18n-4.0.0.tgz", @@ -170,10 +501,366 @@ "petite-vue-i18n": { "optional": true }, - "vue-i18n": { + "vue-i18n": { + "optional": true + }, + "vue-i18n-bridge": { + "optional": true + } + } + }, + "apps/club/node_modules/@vitest/expect": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz", + "integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==", + "dependencies": { + "@vitest/spy": "2.0.5", + "@vitest/utils": "2.0.5", + "chai": "^5.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "apps/club/node_modules/@vitest/runner": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.5.tgz", + "integrity": "sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==", + "dependencies": { + "@vitest/utils": "2.0.5", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "apps/club/node_modules/@vitest/snapshot": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.5.tgz", + "integrity": "sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==", + "dependencies": { + "@vitest/pretty-format": "2.0.5", + "magic-string": "^0.30.10", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "apps/club/node_modules/@vitest/spy": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz", + "integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==", + "dependencies": { + "tinyspy": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "apps/club/node_modules/@vitest/utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz", + "integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==", + "dependencies": { + "@vitest/pretty-format": "2.0.5", + "estree-walker": "^3.0.3", + "loupe": "^3.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "apps/club/node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/chai": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", + "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "apps/club/node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "engines": { + "node": ">= 16" + } + }, + "apps/club/node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "engines": { + "node": ">=6" + } + }, + "apps/club/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "apps/club/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "apps/club/node_modules/loupe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", + "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "apps/club/node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "engines": { + "node": ">= 14.16" + } + }, + "apps/club/node_modules/rollup": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz", + "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==", + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.21.2", + "@rollup/rollup-android-arm64": "4.21.2", + "@rollup/rollup-darwin-arm64": "4.21.2", + "@rollup/rollup-darwin-x64": "4.21.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.21.2", + "@rollup/rollup-linux-arm-musleabihf": "4.21.2", + "@rollup/rollup-linux-arm64-gnu": "4.21.2", + "@rollup/rollup-linux-arm64-musl": "4.21.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.21.2", + "@rollup/rollup-linux-riscv64-gnu": "4.21.2", + "@rollup/rollup-linux-s390x-gnu": "4.21.2", + "@rollup/rollup-linux-x64-gnu": "4.21.2", + "@rollup/rollup-linux-x64-musl": "4.21.2", + "@rollup/rollup-win32-arm64-msvc": "4.21.2", + "@rollup/rollup-win32-ia32-msvc": "4.21.2", + "@rollup/rollup-win32-x64-msvc": "4.21.2", + "fsevents": "~2.3.2" + } + }, + "apps/club/node_modules/tinypool": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz", + "integrity": "sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "apps/club/node_modules/tinyspy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz", + "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==", + "engines": { + "node": ">=14.0.0" + } + }, + "apps/club/node_modules/vite": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.3.tgz", + "integrity": "sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "apps/club/node_modules/vite-node": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.5.tgz", + "integrity": "sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.5", + "pathe": "^1.1.2", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "apps/club/node_modules/vitest": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.5.tgz", + "integrity": "sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@vitest/expect": "2.0.5", + "@vitest/pretty-format": "^2.0.5", + "@vitest/runner": "2.0.5", + "@vitest/snapshot": "2.0.5", + "@vitest/spy": "2.0.5", + "@vitest/utils": "2.0.5", + "chai": "^5.1.1", + "debug": "^4.3.5", + "execa": "^8.0.1", + "magic-string": "^0.30.10", + "pathe": "^1.1.2", + "std-env": "^3.7.0", + "tinybench": "^2.8.0", + "tinypool": "^1.0.0", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.0.5", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.0.5", + "@vitest/ui": "2.0.5", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { "optional": true }, - "vue-i18n-bridge": { + "jsdom": { "optional": true } } @@ -288,6 +975,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.24.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", @@ -426,6 +1125,21 @@ "fast-check": "^3.13.2" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/android-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", @@ -1208,7 +1922,6 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -1222,7 +1935,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -1231,7 +1943,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -1245,7 +1956,6 @@ "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -1556,6 +2266,198 @@ } } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz", + "integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz", + "integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz", + "integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz", + "integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz", + "integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz", + "integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz", + "integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz", + "integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz", + "integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz", + "integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz", + "integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz", + "integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz", + "integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz", + "integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz", + "integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz", + "integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@rushstack/node-core-library": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", @@ -1828,7 +2730,7 @@ "version": "20.12.7", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", - "dev": true, + "devOptional": true, "dependencies": { "undici-types": "~5.26.4" } @@ -2110,6 +3012,17 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@vitest/pretty-format": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz", + "integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/@vitest/runner": { "version": "0.34.6", "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.6.tgz", @@ -2952,7 +3865,6 @@ "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, "engines": { "node": ">=8" } @@ -3403,9 +4315,9 @@ "dev": true }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "dependencies": { "ms": "2.1.2" }, @@ -4382,6 +5294,53 @@ "node": ">=0.10.0" } }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/fast-check": { "version": "3.17.2", "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.17.2.tgz", @@ -4632,7 +5591,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, "engines": { "node": "*" } @@ -4656,6 +5614,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", @@ -4916,6 +5885,14 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "engines": { + "node": ">=16.17.0" + } + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -5254,6 +6231,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -5648,6 +6636,11 @@ "@jridgewell/sourcemap-codec": "^1.4.15" } }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -5879,6 +6872,31 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -6254,9 +7272,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -6357,9 +7375,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.45", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz", + "integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==", "funding": [ { "type": "opencollective", @@ -6376,7 +7394,7 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "source-map-js": "^1.2.0" }, "engines": { @@ -7026,14 +8044,12 @@ "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==" }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, "engines": { "node": ">=14" }, @@ -7085,8 +8101,7 @@ "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==" }, "node_modules/statuses": { "version": "2.0.1", @@ -7100,8 +8115,7 @@ "node_modules/std-env": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", - "dev": true + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==" }, "node_modules/stdin-discarder": { "version": "0.2.2", @@ -7284,6 +8298,17 @@ "node": ">=8" } }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -7538,8 +8563,7 @@ "node_modules/tinybench": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", - "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", - "dev": true + "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==" }, "node_modules/tinypool": { "version": "0.7.0", @@ -7550,6 +8574,14 @@ "node": ">=14.0.0" } }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/tinyspy": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", @@ -7866,7 +8898,7 @@ "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "devOptional": true }, "node_modules/unicorn-magic": { "version": "0.1.0", @@ -8333,10 +9365,9 @@ } }, "node_modules/why-is-node-running": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", - "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", - "dev": true, + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" From 27331b36b3dd192cc56337e00b57c8544be5673a Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 7 Sep 2024 21:37:54 +0200 Subject: [PATCH 190/410] feat: add TeamMember interface --- frontend/apps/club/src/types/team.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/frontend/apps/club/src/types/team.ts b/frontend/apps/club/src/types/team.ts index b7c9e487..25dd1942 100644 --- a/frontend/apps/club/src/types/team.ts +++ b/frontend/apps/club/src/types/team.ts @@ -1,6 +1,20 @@ +import type { License } from '@root/types/member'; +import type { Country } from '@root/types/country'; +import type { DateType } from '@kwai/date'; + +export interface TeamMember { + id: string, + name: string, + license: License, + gender: number, + birthdate: DateType, + nationality: Country, +} + export interface Team { id?: string, name: string, active: boolean, - remark: string + remark: string, + members: TeamMember[], } From 332258f305d5f0b1585562e1941bfe40e026e4b0 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 7 Sep 2024 21:38:10 +0200 Subject: [PATCH 191/410] ci: exclude test files --- frontend/apps/club/tsconfig.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/apps/club/tsconfig.json b/frontend/apps/club/tsconfig.json index 3c8bf4a2..893df2b1 100644 --- a/frontend/apps/club/tsconfig.json +++ b/frontend/apps/club/tsconfig.json @@ -18,6 +18,9 @@ "src/**/*.ts", "src/**/*.vue" ], + "exclude": [ + "src/**/*.test.ts" + ], "references": [ { "path": "./tsconfig.node.json" From 54fa183508077e16fe461ff674a3ae36fa1154ef Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 7 Sep 2024 21:38:49 +0200 Subject: [PATCH 192/410] refactor: move Country code to useCountry --- frontend/apps/club/src/composables/useCountry.ts | 12 ++++++++++++ frontend/apps/club/src/composables/useMember.ts | 11 +---------- 2 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 frontend/apps/club/src/composables/useCountry.ts diff --git a/frontend/apps/club/src/composables/useCountry.ts b/frontend/apps/club/src/composables/useCountry.ts new file mode 100644 index 00000000..9bc6cfa9 --- /dev/null +++ b/frontend/apps/club/src/composables/useCountry.ts @@ -0,0 +1,12 @@ +import { JsonApiData } from '@kwai/api'; +import { z } from 'zod'; + +export const CountryResourceSchema = JsonApiData.extend({ + type: z.literal('countries'), + attributes: z.object({ + iso_2: z.string(), + iso_3: z.string(), + name: z.string(), + }), +}); +export type CountryResource = z.infer; diff --git a/frontend/apps/club/src/composables/useMember.ts b/frontend/apps/club/src/composables/useMember.ts index 5c27d28d..5666c381 100644 --- a/frontend/apps/club/src/composables/useMember.ts +++ b/frontend/apps/club/src/composables/useMember.ts @@ -4,6 +4,7 @@ import { type Ref, ref, toValue } from 'vue'; import { useQuery } from '@tanstack/vue-query'; import { z } from 'zod'; import type { Member } from '@root/types/member'; +import { CountryResourceSchema } from '@root/composables/useCountry'; export interface Members { meta: { count: number, offset: number, limit: number }, @@ -67,16 +68,6 @@ const ContactResourceSchema = JsonApiData.extend({ }); type ContactResource = z.infer; -const CountryResourceSchema = JsonApiData.extend({ - type: z.literal('countries'), - attributes: z.object({ - iso_2: z.string(), - iso_3: z.string(), - name: z.string(), - }), -}); -type CountryResource = z.infer; - export const MemberDocumentSchema = JsonApiDocument.extend({ data: z.union([ MemberResourceSchema, From 17f6b5e529919ab56db1ae222622f8169d732a0a Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 7 Sep 2024 21:39:12 +0200 Subject: [PATCH 193/410] feat: add team members --- frontend/apps/club/src/composables/useTeam.ts | 65 ++++++++++++++++--- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/frontend/apps/club/src/composables/useTeam.ts b/frontend/apps/club/src/composables/useTeam.ts index 8ba14468..ce435420 100644 --- a/frontend/apps/club/src/composables/useTeam.ts +++ b/frontend/apps/club/src/composables/useTeam.ts @@ -1,8 +1,22 @@ -import type { Team } from '@root/types/team'; -import { JsonApiData, JsonApiDocument, useHttpApi } from '@kwai/api'; +import type { Team, TeamMember } from '@root/types/team'; +import { + JsonApiData, + JsonApiDocument, + JsonResourceIdentifier, + transformResourceArrayToObject, + useHttpApi, +} from '@kwai/api'; import { z } from 'zod'; import { type Ref, ref, toValue } from 'vue'; import { useQuery } from '@tanstack/vue-query'; +import { CountryResourceSchema } from '@root/composables/useCountry'; + +const TeamMemberSchema = JsonApiData.extend({ + type: z.literal('team_members'), + attributes: z.object({ + name: z.string(), + }), +}); export interface Teams { meta: { @@ -20,6 +34,11 @@ const TeamResourceSchema = JsonApiData.extend({ active: z.boolean(), remark: z.string(), }), + relationships: z.object({ + team_members: z.object({ + data: z.array(JsonResourceIdentifier).default([]), + }), + }), }); type TeamResource = z.infer; @@ -27,18 +46,44 @@ type TeamResource = z.infer; export const TeamDocumentSchema = JsonApiDocument.extend({ data: z.union([ TeamResourceSchema, - z.array(TeamResourceSchema).default([]), + z.array(TeamResourceSchema), ]), + included: z.array(z.union([TeamMemberSchema, CountryResourceSchema])).default([]), }); -type TeamDocument = z.infer; +export type TeamDocument = z.infer; + +export const transform = (doc: TeamDocument) : Team | Teams => { + const included = transformResourceArrayToObject(doc.included); + const mapModel = (teamResource: TeamResource): Team => { + const teamMembers: TeamMember[] = []; + for (const teamMemberIdentifier of teamResource.relationships.team_members.data) { + const teamMember = included[teamMemberIdentifier.type][teamMemberIdentifier.id]; + const nationality = included[teamMember.relationships.nationality.data.type][teamMember.relationships.nationality.data.id]; + teamMembers.push( + { + id: teamMemberIdentifier.id, + name: teamMember.attributes.name, + license: { + number: teamMember.attributes.license_number, + end_date: teamMember.attributes.license_end_date, + }, + gender: teamMember.attributes.gender, + birthdate: teamMember.attributes.birthdate, + nationality: { + iso_2: nationality.attributes.iso_2, + iso_3: nationality.attributes.iso_3, + name: nationality.attributes.name, + }, + } + ); + } -const transform = (doc: TeamDocument) : Team | Teams => { - const mapModel = (data: TeamResource): Team => { return { - id: data.id, - name: data.attributes.name, - active: data.attributes.active, - remark: data.attributes.remark, + id: teamResource.id, + name: teamResource.attributes.name, + active: teamResource.attributes.active, + remark: teamResource.attributes.remark, + members: teamMembers, }; }; if (Array.isArray(doc.data)) { From 3e1577d239254d197cbf28a5900f5a85cb346fd3 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 7 Sep 2024 21:39:29 +0200 Subject: [PATCH 194/410] fix: export License interface --- frontend/apps/club/src/types/member.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/apps/club/src/types/member.ts b/frontend/apps/club/src/types/member.ts index 4f5271bc..908142dc 100644 --- a/frontend/apps/club/src/types/member.ts +++ b/frontend/apps/club/src/types/member.ts @@ -1,7 +1,7 @@ import type { DateType } from '@kwai/date'; import type { Person } from './person'; -interface License { +export interface License { number: string, end_date: DateType } From 19420853e1038067412ba21fc310c182a7b4e183 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 7 Sep 2024 21:39:44 +0200 Subject: [PATCH 195/410] test: add tests for useTeam --- frontend/apps/club/package.json | 1 + .../apps/club/src/composables/useTeam.test.ts | 93 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 frontend/apps/club/src/composables/useTeam.test.ts diff --git a/frontend/apps/club/package.json b/frontend/apps/club/package.json index f89320d8..e48f23d8 100644 --- a/frontend/apps/club/package.json +++ b/frontend/apps/club/package.json @@ -23,6 +23,7 @@ "autoprefixer": "^10.4.16", "postcss": "^8.4.31", "tailwindcss": "^3.4.3", + "vitest": "^2.0.5", "vue-tsc": "^1.8.27" }, "private": true, diff --git a/frontend/apps/club/src/composables/useTeam.test.ts b/frontend/apps/club/src/composables/useTeam.test.ts new file mode 100644 index 00000000..fc88c8f3 --- /dev/null +++ b/frontend/apps/club/src/composables/useTeam.test.ts @@ -0,0 +1,93 @@ +import { describe, expect, it } from 'vitest'; +import { TeamDocumentSchema, transform } from '@root/composables/useTeam'; + +const teamWithoutMembersJson = { + data: { + type: 'teams', + id: '1', + attributes: { name: 'U11', active: true, remark: '' }, + relationships: { team_members: { data: [] } }, + }, +}; + +const teamWithMembersJson = { + data: { + type: 'teams', + id: '1', + attributes: { name: 'U11', active: true, remark: '' }, + relationships: { + team_members: { + data: [ + { type: 'team_members', id: '1' }, + ], + }, + }, + }, + included: [{ + type: 'team_members', + id: '1', + attributes: { name: 'Jigoro Kano' }, + relationships: { + nationality: { + data: { type: 'countries', id: '1' }, + }, + }, + }, { + type: 'countries', + id: '1', + attributes: { iso_2: 'JP', iso_3: 'JPN', name: 'Japan' }, + }, + ], +}; + +const parse = (json) => { + const result = TeamDocumentSchema.safeParse(json); + if (!result.success) { + console.log(result.error); + } + return result; +}; + +describe('useTeam tests', () => { + it('can handle a team document', () => { + const { data: document, success } = parse(teamWithoutMembersJson); + + expect(success).toBeTruthy(); + expect(document.data.type).toEqual('teams'); + expect(document.data.id).toEqual('1'); + expect(document.data.attributes.name).toEqual('U11'); + }); + + it('can handle a team document with team members', () => { + const { data: document, success } = parse(teamWithMembersJson); + + expect(success).toBeTruthy(); + expect(document.data.type).toEqual('teams'); + expect(document).toHaveProperty('data.id', '1'); + expect(document.data.relationships.team_members.data).toHaveLength(1); + expect(document.included).toHaveLength(2); + expect(document).toHaveProperty('included.0.type', 'team_members'); + expect(document).toHaveProperty('included.0.id', '1'); + expect(document).toHaveProperty('included.0.attributes.name', 'Jigoro Kano'); + }); + + it('can transform a document with a team', () => { + const { data: document } = parse(teamWithoutMembersJson); + + const team = transform(document); + expect(team).not.toBeNull(); + expect(team).toHaveProperty('id', '1'); + expect(team).toHaveProperty('name', 'U11'); + expect(team.members).toHaveLength(0); + }); + + it('can transform a document with a team and members', () => { + const { data: document } = parse(teamWithMembersJson); + const team = transform(document); + expect(team).not.toBeNull(); + expect(team).toHaveProperty('id', '1'); + expect(team).toHaveProperty('name', 'U11'); + expect(team).toHaveProperty('members.0.name', 'Jigoro Kano'); + expect(team).toHaveProperty('members.0.nationality.name', 'Japan'); + }); +}); From 293593e05c03538cf4b9f4ada06cce9229b3cf57 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 7 Sep 2024 21:40:05 +0200 Subject: [PATCH 196/410] feat: add team members --- frontend/apps/club/src/locales/nl.yaml | 1 + .../apps/club/src/pages/teams/TeamsPage.vue | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/frontend/apps/club/src/locales/nl.yaml b/frontend/apps/club/src/locales/nl.yaml index 15b31e90..9f0a3fe8 100644 --- a/frontend/apps/club/src/locales/nl.yaml +++ b/frontend/apps/club/src/locales/nl.yaml @@ -25,3 +25,4 @@ teams: error: Er is een fout gebeurd tijdens het ophalen van de teams. name: Naam remark: Opmerking + members: Leden diff --git a/frontend/apps/club/src/pages/teams/TeamsPage.vue b/frontend/apps/club/src/pages/teams/TeamsPage.vue index 2b8b9917..6ed0d7b4 100644 --- a/frontend/apps/club/src/pages/teams/TeamsPage.vue +++ b/frontend/apps/club/src/pages/teams/TeamsPage.vue @@ -33,7 +33,7 @@ const { data: teams, isPending, isError } = useTeams({}); v-else-if="teams" class="w-full text-sm text-left" > - + {{ t('teams.name') }} + + {{ t('teams.members') }} + {{ t('teams.remark') }} + - + {{ team.name }} + + {{ team.members.length }} + {{ team.remark }} + + Edit + From f81da4d372f51a467db798575bd683eaa6920a21 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sun, 8 Sep 2024 17:06:41 +0200 Subject: [PATCH 197/410] feat: add JsonResourceIdentifierType --- frontend/packages/kwai-api/src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/packages/kwai-api/src/index.ts b/frontend/packages/kwai-api/src/index.ts index c9eb4cee..face551c 100644 --- a/frontend/packages/kwai-api/src/index.ts +++ b/frontend/packages/kwai-api/src/index.ts @@ -11,6 +11,7 @@ export const JsonResourceIdentifier = z.object({ id: z.optional(z.string()), type: z.string(), }); +export type JsonResourceIdentifierType = z.infer; export const JsonApiRelationship = z.object({ data: z.union([JsonResourceIdentifier, z.array(JsonResourceIdentifier)]), From 686da526f0d3acfb0b2f1990f953d124ca7ee128 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sun, 8 Sep 2024 17:07:19 +0200 Subject: [PATCH 198/410] fix: typescript type errors --- .../apps/club/src/composables/useTeam.test.ts | 24 +++++++++++-------- frontend/apps/club/src/composables/useTeam.ts | 15 ++++++------ frontend/apps/club/tsconfig.json | 3 --- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/frontend/apps/club/src/composables/useTeam.test.ts b/frontend/apps/club/src/composables/useTeam.test.ts index fc88c8f3..07c4fb2c 100644 --- a/frontend/apps/club/src/composables/useTeam.test.ts +++ b/frontend/apps/club/src/composables/useTeam.test.ts @@ -1,5 +1,7 @@ import { describe, expect, it } from 'vitest'; -import { TeamDocumentSchema, transform } from '@root/composables/useTeam'; +import { type TeamDocument, TeamDocumentSchema, transform } from '@root/composables/useTeam'; +import type { TeamResource } from '@kwai/coach/src/composables/useTeam'; +import type { Team } from '@root/types/team'; const teamWithoutMembersJson = { data: { @@ -40,7 +42,7 @@ const teamWithMembersJson = { ], }; -const parse = (json) => { +const parse = (json: unknown) => { const result = TeamDocumentSchema.safeParse(json); if (!result.success) { console.log(result.error); @@ -53,19 +55,21 @@ describe('useTeam tests', () => { const { data: document, success } = parse(teamWithoutMembersJson); expect(success).toBeTruthy(); - expect(document.data.type).toEqual('teams'); - expect(document.data.id).toEqual('1'); - expect(document.data.attributes.name).toEqual('U11'); + expect(document).toHaveProperty('data.type', 'teams'); + expect(document).toHaveProperty('data.id', '1'); + expect(document).toHaveProperty('data.attributes.name', 'U11'); }); it('can handle a team document with team members', () => { const { data: document, success } = parse(teamWithMembersJson); expect(success).toBeTruthy(); - expect(document.data.type).toEqual('teams'); + expect(document).toHaveProperty('data.type', 'teams'); expect(document).toHaveProperty('data.id', '1'); - expect(document.data.relationships.team_members.data).toHaveLength(1); - expect(document.included).toHaveLength(2); + expect(document).toHaveProperty('data.relationships.team_members.data'); + const teamData = document!.data as TeamResource; + expect(teamData.relationships!.team_members.data).toHaveLength(1); + expect(document!.included).toHaveLength(2); expect(document).toHaveProperty('included.0.type', 'team_members'); expect(document).toHaveProperty('included.0.id', '1'); expect(document).toHaveProperty('included.0.attributes.name', 'Jigoro Kano'); @@ -74,7 +78,7 @@ describe('useTeam tests', () => { it('can transform a document with a team', () => { const { data: document } = parse(teamWithoutMembersJson); - const team = transform(document); + const team = transform(document as TeamDocument) as Team; expect(team).not.toBeNull(); expect(team).toHaveProperty('id', '1'); expect(team).toHaveProperty('name', 'U11'); @@ -83,7 +87,7 @@ describe('useTeam tests', () => { it('can transform a document with a team and members', () => { const { data: document } = parse(teamWithMembersJson); - const team = transform(document); + const team = transform(document as TeamDocument) as Team; expect(team).not.toBeNull(); expect(team).toHaveProperty('id', '1'); expect(team).toHaveProperty('name', 'U11'); diff --git a/frontend/apps/club/src/composables/useTeam.ts b/frontend/apps/club/src/composables/useTeam.ts index ce435420..51281e29 100644 --- a/frontend/apps/club/src/composables/useTeam.ts +++ b/frontend/apps/club/src/composables/useTeam.ts @@ -1,8 +1,8 @@ import type { Team, TeamMember } from '@root/types/team'; import { JsonApiData, - JsonApiDocument, - JsonResourceIdentifier, + JsonApiDocument, JsonResourceIdentifier, + type JsonResourceIdentifierType, transformResourceArrayToObject, useHttpApi, } from '@kwai/api'; @@ -57,11 +57,12 @@ export const transform = (doc: TeamDocument) : Team | Teams => { const mapModel = (teamResource: TeamResource): Team => { const teamMembers: TeamMember[] = []; for (const teamMemberIdentifier of teamResource.relationships.team_members.data) { - const teamMember = included[teamMemberIdentifier.type][teamMemberIdentifier.id]; - const nationality = included[teamMember.relationships.nationality.data.type][teamMember.relationships.nationality.data.id]; + const teamMember = included[teamMemberIdentifier.type][teamMemberIdentifier.id as string]; + const countryResourceId = teamMember.relationships!.nationality.data as JsonResourceIdentifierType; + const nationality = included[countryResourceId.type][countryResourceId.id as string]; teamMembers.push( { - id: teamMemberIdentifier.id, + id: teamMemberIdentifier.id as string, name: teamMember.attributes.name, license: { number: teamMember.attributes.license_number, @@ -70,8 +71,8 @@ export const transform = (doc: TeamDocument) : Team | Teams => { gender: teamMember.attributes.gender, birthdate: teamMember.attributes.birthdate, nationality: { - iso_2: nationality.attributes.iso_2, - iso_3: nationality.attributes.iso_3, + iso2: nationality.attributes.iso_2, + iso3: nationality.attributes.iso_3, name: nationality.attributes.name, }, } diff --git a/frontend/apps/club/tsconfig.json b/frontend/apps/club/tsconfig.json index 893df2b1..3c8bf4a2 100644 --- a/frontend/apps/club/tsconfig.json +++ b/frontend/apps/club/tsconfig.json @@ -18,9 +18,6 @@ "src/**/*.ts", "src/**/*.vue" ], - "exclude": [ - "src/**/*.test.ts" - ], "references": [ { "path": "./tsconfig.node.json" From e06d34b5f803df95de3d5afd6a0e4e77789f8787 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sun, 8 Sep 2024 21:51:23 +0200 Subject: [PATCH 199/410] fix: import CountryResource --- frontend/apps/club/src/composables/useMember.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/apps/club/src/composables/useMember.ts b/frontend/apps/club/src/composables/useMember.ts index 5666c381..a2bf6c74 100644 --- a/frontend/apps/club/src/composables/useMember.ts +++ b/frontend/apps/club/src/composables/useMember.ts @@ -4,7 +4,7 @@ import { type Ref, ref, toValue } from 'vue'; import { useQuery } from '@tanstack/vue-query'; import { z } from 'zod'; import type { Member } from '@root/types/member'; -import { CountryResourceSchema } from '@root/composables/useCountry'; +import { type CountryResource, CountryResourceSchema } from '@root/composables/useCountry'; export interface Members { meta: { count: number, offset: number, limit: number }, From 13e1d7b66816ae868775779381b576c7118114d8 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sun, 8 Sep 2024 21:51:44 +0200 Subject: [PATCH 200/410] ci: sync dependencies --- frontend/apps/auth/package.json | 2 +- frontend/apps/club/package.json | 1 - frontend/apps/coach/package.json | 2 +- frontend/apps/portal/package.json | 2 +- frontend/package-lock.json | 14686 ++++++++++++----------- frontend/package.json | 5 +- frontend/packages/kwai-ui/package.json | 2 +- 7 files changed, 7804 insertions(+), 6896 deletions(-) diff --git a/frontend/apps/auth/package.json b/frontend/apps/auth/package.json index 91920f85..4d4c7c4c 100644 --- a/frontend/apps/auth/package.json +++ b/frontend/apps/auth/package.json @@ -6,7 +6,7 @@ "@kwai/api": "*", "@kwai/config": "*", "@kwai/ui": "*", - "@vueuse/core": "^10.9.0", + "@vueuse/core": "11.0.3", "pinia": "^2.1.7", "vee-validate": "^4.12.6", "vue": "^3.4.25", diff --git a/frontend/apps/club/package.json b/frontend/apps/club/package.json index e48f23d8..f89320d8 100644 --- a/frontend/apps/club/package.json +++ b/frontend/apps/club/package.json @@ -23,7 +23,6 @@ "autoprefixer": "^10.4.16", "postcss": "^8.4.31", "tailwindcss": "^3.4.3", - "vitest": "^2.0.5", "vue-tsc": "^1.8.27" }, "private": true, diff --git a/frontend/apps/coach/package.json b/frontend/apps/coach/package.json index b10c35af..aceb0dd8 100644 --- a/frontend/apps/coach/package.json +++ b/frontend/apps/coach/package.json @@ -10,7 +10,7 @@ "@kwai/types": "*", "@kwai/ui": "*", "@tanstack/vue-query": "^5.32.0", - "@vuepic/vue-datepicker": "8.4.0", + "@vuepic/vue-datepicker": "9.0.3", "@vueuse/core": "^10.9.0", "vee-validate": "^4.12.6", "vue": "^3.4.25", diff --git a/frontend/apps/portal/package.json b/frontend/apps/portal/package.json index 0dfddd36..bbd9d352 100644 --- a/frontend/apps/portal/package.json +++ b/frontend/apps/portal/package.json @@ -10,7 +10,7 @@ "@kwai/ui": "*", "@tanstack/vue-query": "^5.32.0", "@vueuse/core": "^10.9.0", - "@vueuse/router": "^10.6.1", + "@vueuse/router": "11.0.3", "vue": "^3.4.25", "vue-router": "^4.3.2" }, diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 6c5203a9..2cc3fe43 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -11,6 +11,9 @@ "apps/*", "packages/*" ], + "dependencies": { + "vitest": "^2.0.5" + }, "devDependencies": { "@vue/test-utils": "^2.4.3", "eslint-config-kwai": "*", @@ -32,7 +35,7 @@ "@kwai/api": "*", "@kwai/config": "*", "@kwai/ui": "*", - "@vueuse/core": "^10.9.0", + "@vueuse/core": "11.0.3", "pinia": "^2.1.7", "vee-validate": "^4.12.6", "vue": "^3.4.25", @@ -49,6 +52,89 @@ "vue-tsc": "^1.8.24" } }, + "apps/auth/node_modules/@vueuse/core": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-11.0.3.tgz", + "integrity": "sha512-RENlh64+SYA9XMExmmH1a3TPqeIuJBNNB/63GT35MZI+zpru3oMRUA6cEFr9HmGqEgUisurwGwnIieF6qu3aXw==", + "dependencies": { + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "11.0.3", + "@vueuse/shared": "11.0.3", + "vue-demi": ">=0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "apps/auth/node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "apps/auth/node_modules/@vueuse/metadata": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.0.3.tgz", + "integrity": "sha512-+FtbO4SD5WpsOcQTcC0hAhNlOid6QNLzqedtquTtQ+CRNBoAt9GuV07c6KNHK1wCmlq8DFPwgiLF2rXwgSHX5Q==", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "apps/auth/node_modules/@vueuse/shared": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-11.0.3.tgz", + "integrity": "sha512-0rY2m6HS5t27n/Vp5cTDsKTlNnimCqsbh/fmT2LgE+aaU42EMfXo8+bNX91W9I7DDmxfuACXMmrd7d79JxkqWA==", + "dependencies": { + "vue-demi": ">=0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "apps/auth/node_modules/@vueuse/shared/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "apps/author": { "name": "@kwai/author", "version": "1.0.0", @@ -126,7 +212,6 @@ "@tanstack/vue-query": "^5.32.0", "@vueuse/core": "^10.9.0", "vee-validate": "^4.12.6", - "vitest": "^2.0.5", "vue": "^3.4.25", "vue-i18n": "^9.13.1", "vue-router": "^4.3.2", @@ -141,223 +226,565 @@ "vue-tsc": "^1.8.27" } }, - "apps/club/node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], + "apps/club/node_modules/@intlify/unplugin-vue-i18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@intlify/unplugin-vue-i18n/-/unplugin-vue-i18n-4.0.0.tgz", + "integrity": "sha512-q2Mhqa/mLi0tulfLFO4fMXXvEbkSZpI5yGhNNsLTNJJ41icEGUuyDe+j5zRZIKSkOJRgX6YbCyibTDJdRsukmw==", + "dependencies": { + "@intlify/bundle-utils": "^8.0.0", + "@intlify/shared": "^9.4.0", + "@rollup/pluginutils": "^5.1.0", + "@vue/compiler-sfc": "^3.2.47", + "debug": "^4.3.3", + "fast-glob": "^3.2.12", + "js-yaml": "^4.1.0", + "json5": "^2.2.3", + "pathe": "^1.0.0", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2", + "unplugin": "^1.1.0" + }, "engines": { - "node": ">=12" + "node": ">= 14.16" + }, + "peerDependencies": { + "petite-vue-i18n": "*", + "vue-i18n": "*", + "vue-i18n-bridge": "*" + }, + "peerDependenciesMeta": { + "petite-vue-i18n": { + "optional": true + }, + "vue-i18n": { + "optional": true + }, + "vue-i18n-bridge": { + "optional": true + } } }, - "apps/club/node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" + "apps/coach": { + "name": "@kwai/coach", + "version": "1.0.0", + "dependencies": { + "@intlify/unplugin-vue-i18n": "4.0.0", + "@kwai/api": "*", + "@kwai/config": "*", + "@kwai/date": "*", + "@kwai/types": "*", + "@kwai/ui": "*", + "@tanstack/vue-query": "^5.32.0", + "@vuepic/vue-datepicker": "9.0.3", + "@vueuse/core": "^10.9.0", + "vee-validate": "^4.12.6", + "vue": "^3.4.25", + "vue-i18n": "^9.13.1", + "vue-router": "^4.3.2", + "zod": "^3.23.4" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^4.5.0", + "@vue/tsconfig": "^0.4.0", + "autoprefixer": "^10.4.16", + "postcss": "^8.4.31", + "tailwindcss": "^3.4.3", + "vue-tsc": "^1.8.24" } }, - "apps/club/node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "android" - ], + "apps/coach/node_modules/@intlify/unplugin-vue-i18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@intlify/unplugin-vue-i18n/-/unplugin-vue-i18n-4.0.0.tgz", + "integrity": "sha512-q2Mhqa/mLi0tulfLFO4fMXXvEbkSZpI5yGhNNsLTNJJ41icEGUuyDe+j5zRZIKSkOJRgX6YbCyibTDJdRsukmw==", + "dependencies": { + "@intlify/bundle-utils": "^8.0.0", + "@intlify/shared": "^9.4.0", + "@rollup/pluginutils": "^5.1.0", + "@vue/compiler-sfc": "^3.2.47", + "debug": "^4.3.3", + "fast-glob": "^3.2.12", + "js-yaml": "^4.1.0", + "json5": "^2.2.3", + "pathe": "^1.0.0", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2", + "unplugin": "^1.1.0" + }, "engines": { - "node": ">=12" + "node": ">= 14.16" + }, + "peerDependencies": { + "petite-vue-i18n": "*", + "vue-i18n": "*", + "vue-i18n-bridge": "*" + }, + "peerDependenciesMeta": { + "petite-vue-i18n": { + "optional": true + }, + "vue-i18n": { + "optional": true + }, + "vue-i18n-bridge": { + "optional": true + } } }, - "apps/club/node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], + "apps/coach/node_modules/@vuepic/vue-datepicker": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@vuepic/vue-datepicker/-/vue-datepicker-9.0.3.tgz", + "integrity": "sha512-OtCAKG+CkVBpCwnPx7/BGRF+/z+jDzNl2cMBpcr8j2NkAN+13xkUt7sctbOVKbG/jhuXtKoUSedI69e0cDXPXw==", + "dependencies": { + "date-fns": "^3.6.0" + }, "engines": { - "node": ">=12" + "node": ">=18.12.0" + }, + "peerDependencies": { + "vue": ">=3.2.0" } }, - "apps/club/node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" + "apps/portal": { + "name": "@kwai/portal", + "version": "1.0.0", + "dependencies": { + "@kwai/api": "*", + "@kwai/config": "*", + "@kwai/date": "*", + "@kwai/types": "*", + "@kwai/ui": "*", + "@tanstack/vue-query": "^5.32.0", + "@vueuse/core": "^10.9.0", + "@vueuse/router": "11.0.3", + "vue": "^3.4.25", + "vue-router": "^4.3.2" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^4.5.0", + "@vue/tsconfig": "^0.4.0", + "autoprefixer": "^10.4.16", + "postcss": "^8.4.31", + "tailwindcss": "^3.4.3", + "vue-tsc": "^1.8.24" } }, - "apps/club/node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "freebsd" - ], + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "engines": { - "node": ">=12" + "node": ">=0.10.0" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", + "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@bundled-es-modules/cookie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz", + "integrity": "sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==", + "dev": true, + "dependencies": { + "cookie": "^0.5.0" + } + }, + "node_modules/@bundled-es-modules/statuses": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz", + "integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==", + "dev": true, + "dependencies": { + "statuses": "^2.0.1" + } + }, + "node_modules/@effect/schema": { + "version": "0.66.5", + "resolved": "https://registry.npmjs.org/@effect/schema/-/schema-0.66.5.tgz", + "integrity": "sha512-xfu5161JyrfAS1Ruwv0RXd4QFiCALbm3iu9nlW9N9K+52wbS0WdO6XUekPZ9V/O7LN+XmlIh5Y9xhJaIWCZ/gw==", + "dev": true, + "peerDependencies": { + "effect": "^3.0.3", + "fast-check": "^3.13.2" } }, - "apps/club/node_modules/@esbuild/freebsd-x64": { + "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "cpu": [ - "x64" + "ppc64" ], "optional": true, "os": [ - "freebsd" + "aix" ], "engines": { "node": ">=12" } }, - "apps/club/node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ - "linux" + "android" ], "engines": { "node": ">=12" } }, - "apps/club/node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ - "linux" + "android" ], "engines": { "node": ">=12" } }, - "apps/club/node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", "cpu": [ - "ia32" + "x64" ], + "dev": true, "optional": true, "os": [ - "linux" + "android" ], "engines": { "node": ">=12" } }, - "apps/club/node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", "cpu": [ - "loong64" + "arm64" ], + "dev": true, "optional": true, "os": [ - "linux" + "darwin" ], "engines": { "node": ">=12" } }, - "apps/club/node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", "cpu": [ - "mips64el" + "x64" ], + "dev": true, "optional": true, "os": [ - "linux" + "darwin" ], "engines": { "node": ">=12" } }, - "apps/club/node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", "cpu": [ - "ppc64" + "arm64" ], + "dev": true, "optional": true, "os": [ - "linux" + "freebsd" ], "engines": { "node": ">=12" } }, - "apps/club/node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", "cpu": [ - "riscv64" + "x64" ], + "dev": true, "optional": true, "os": [ - "linux" + "freebsd" ], "engines": { "node": ">=12" } }, - "apps/club/node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", "cpu": [ "s390x" ], + "dev": true, "optional": true, "os": [ "linux" @@ -366,13 +793,14 @@ "node": ">=12" } }, - "apps/club/node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -381,13 +809,14 @@ "node": ">=12" } }, - "apps/club/node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "netbsd" @@ -396,13 +825,14 @@ "node": ">=12" } }, - "apps/club/node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "openbsd" @@ -411,13 +841,14 @@ "node": ">=12" } }, - "apps/club/node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "sunos" @@ -426,13 +857,14 @@ "node": ">=12" } }, - "apps/club/node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -441,13 +873,14 @@ "node": ">=12" } }, - "apps/club/node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "win32" @@ -456,13 +889,14 @@ "node": ">=12" } }, - "apps/club/node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -471,436 +905,344 @@ "node": ">=12" } }, - "apps/club/node_modules/@intlify/unplugin-vue-i18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@intlify/unplugin-vue-i18n/-/unplugin-vue-i18n-4.0.0.tgz", - "integrity": "sha512-q2Mhqa/mLi0tulfLFO4fMXXvEbkSZpI5yGhNNsLTNJJ41icEGUuyDe+j5zRZIKSkOJRgX6YbCyibTDJdRsukmw==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dependencies": { - "@intlify/bundle-utils": "^8.0.0", - "@intlify/shared": "^9.4.0", - "@rollup/pluginutils": "^5.1.0", - "@vue/compiler-sfc": "^3.2.47", - "debug": "^4.3.3", - "fast-glob": "^3.2.12", - "js-yaml": "^4.1.0", - "json5": "^2.2.3", - "pathe": "^1.0.0", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2", - "unplugin": "^1.1.0" + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">= 14.16" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "peerDependencies": { - "petite-vue-i18n": "*", - "vue-i18n": "*", - "vue-i18n-bridge": "*" - }, - "peerDependenciesMeta": { - "petite-vue-i18n": { - "optional": true - }, - "vue-i18n": { - "optional": true - }, - "vue-i18n-bridge": { - "optional": true - } + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "apps/club/node_modules/@vitest/expect": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz", - "integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==", - "dependencies": { - "@vitest/spy": "2.0.5", - "@vitest/utils": "2.0.5", - "chai": "^5.1.1", - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "apps/club/node_modules/@vitest/runner": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.5.tgz", - "integrity": "sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==", + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dependencies": { - "@vitest/utils": "2.0.5", - "pathe": "^1.1.2" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://opencollective.com/eslint" } }, - "apps/club/node_modules/@vitest/snapshot": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.5.tgz", - "integrity": "sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==", - "dependencies": { - "@vitest/pretty-format": "2.0.5", - "magic-string": "^0.30.10", - "pathe": "^1.1.2" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "apps/club/node_modules/@vitest/spy": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz", - "integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==", + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dependencies": { - "tinyspy": "^3.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "apps/club/node_modules/@vitest/utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz", - "integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==", + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dependencies": { - "@vitest/pretty-format": "2.0.5", - "estree-walker": "^3.0.3", - "loupe": "^3.1.1", - "tinyrainbow": "^1.2.0" + "brace-expansion": "^1.1.7" }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "apps/club/node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "engines": { - "node": ">=12" + "node": "*" } }, - "apps/club/node_modules/chai": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", - "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "engines": { - "node": ">=12" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "apps/club/node_modules/check-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", - "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", - "engines": { - "node": ">= 16" + "node_modules/@fbraem/rollup-plugin-toml": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@fbraem/rollup-plugin-toml/-/rollup-plugin-toml-0.0.4.tgz", + "integrity": "sha512-pk/zSCpsNq/SbzE+1JFrsiH4f2iGkeTGfi8YbBZdo+l7XeLtk130XostppcrIKDVGzONk8IhfBnqr6FoDo/pIw==", + "dev": true, + "dependencies": { + "@iarna/toml": "^3.0.0", + "@rollup/pluginutils": "^4.1.0" } }, - "apps/club/node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "node_modules/@fbraem/rollup-plugin-toml/node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, "engines": { - "node": ">=6" + "node": ">= 8.0.0" } }, - "apps/club/node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "node": ">=10.10.0" } }, - "apps/club/node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dependencies": { - "@types/estree": "^1.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "apps/club/node_modules/loupe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", - "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dependencies": { - "get-func-name": "^2.0.1" + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "apps/club/node_modules/pathval": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", - "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "engines": { - "node": ">= 14.16" + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "apps/club/node_modules/rollup": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz", - "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==", + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==" + }, + "node_modules/@iarna/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-td6ZUkz2oS3VeleBcN+m//Q6HlCFCPrnI0FZhrt/h4XqLEdOyYp2u21nd8MdsR+WJy5r9PTDaHTDDfhf4H4l6Q==", + "dev": true + }, + "node_modules/@inquirer/confirm": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.1.5.tgz", + "integrity": "sha512-6+dwZrpko5vr5EFEQmUbfBVhtu6IsnB8lQNsLHgO9S9fbfS5J6MuUj+NY0h98pPpYZXEazLR7qzypEDqVzf6aQ==", + "dev": true, "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" + "@inquirer/core": "^8.0.1", + "@inquirer/type": "^1.3.0" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.21.2", - "@rollup/rollup-android-arm64": "4.21.2", - "@rollup/rollup-darwin-arm64": "4.21.2", - "@rollup/rollup-darwin-x64": "4.21.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.21.2", - "@rollup/rollup-linux-arm-musleabihf": "4.21.2", - "@rollup/rollup-linux-arm64-gnu": "4.21.2", - "@rollup/rollup-linux-arm64-musl": "4.21.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.21.2", - "@rollup/rollup-linux-riscv64-gnu": "4.21.2", - "@rollup/rollup-linux-s390x-gnu": "4.21.2", - "@rollup/rollup-linux-x64-gnu": "4.21.2", - "@rollup/rollup-linux-x64-musl": "4.21.2", - "@rollup/rollup-win32-arm64-msvc": "4.21.2", - "@rollup/rollup-win32-ia32-msvc": "4.21.2", - "@rollup/rollup-win32-x64-msvc": "4.21.2", - "fsevents": "~2.3.2" + "node": ">=18" } }, - "apps/club/node_modules/tinypool": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz", - "integrity": "sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==", + "node_modules/@inquirer/core": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-8.0.1.tgz", + "integrity": "sha512-qJRk1y51Os2ARc11Bg2N6uIwiQ9qBSrmZeuMonaQ/ntFpb4+VlcQ8Gl1TFH67mJLz3HA2nvuave0nbv6Lu8pbg==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.1", + "@inquirer/type": "^1.3.0", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.12.7", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0" + }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": ">=18" } }, - "apps/club/node_modules/tinyspy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz", - "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==", + "node_modules/@inquirer/core/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==", + "dev": true, "engines": { - "node": ">=14.0.0" + "node": ">=8" } }, - "apps/club/node_modules/vite": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.3.tgz", - "integrity": "sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==", + "node_modules/@inquirer/core/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==", + "dev": true + }, + "node_modules/@inquirer/core/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==", + "dev": true, "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": ">=8" + } + }, + "node_modules/@inquirer/core/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/core/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, - "optionalDependencies": { - "fsevents": "~2.3.3" + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.1.tgz", + "integrity": "sha512-mtup3wVKia3ZwULPHcbs4Mor8Voi+iIXEWD7wCNbIO6lYR62oPCTQyrddi5OMYVXHzeCSoneZwJuS8sBvlEwDw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.3.0.tgz", + "integrity": "sha512-RW4Zf6RCTnInRaOZuRHTqAUl+v6VJuQGglir7nW2BkT3OXOphMhkIFhvFRjorBx2l0VwtC/M4No8vYR65TdN9Q==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@intlify/bundle-utils": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@intlify/bundle-utils/-/bundle-utils-8.0.0.tgz", + "integrity": "sha512-1B++zykRnMwQ+20SpsZI1JCnV/YJt9Oq7AGlEurzkWJOFtFAVqaGc/oV36PBRYeiKnTbY9VYfjBimr2Vt42wLQ==", + "dependencies": { + "@intlify/message-compiler": "^9.4.0", + "@intlify/shared": "^9.4.0", + "acorn": "^8.8.2", + "escodegen": "^2.1.0", + "estree-walker": "^2.0.2", + "jsonc-eslint-parser": "^2.3.0", + "mlly": "^1.2.0", + "source-map-js": "^1.0.1", + "yaml-eslint-parser": "^1.2.2" }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" + "engines": { + "node": ">= 14.16" }, "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { + "petite-vue-i18n": { "optional": true }, - "terser": { + "vue-i18n": { "optional": true } } }, - "apps/club/node_modules/vite-node": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.5.tgz", - "integrity": "sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==", + "node_modules/@intlify/core-base": { + "version": "9.13.1", + "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.13.1.tgz", + "integrity": "sha512-+bcQRkJO9pcX8d0gel9ZNfrzU22sZFSA0WVhfXrf5jdJOS24a+Bp8pozuS9sBI9Hk/tGz83pgKfmqcn/Ci7/8w==", "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.5", - "pathe": "^1.1.2", - "tinyrainbow": "^1.2.0", - "vite": "^5.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" + "@intlify/message-compiler": "9.13.1", + "@intlify/shared": "9.13.1" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": ">= 16" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://github.com/sponsors/kazupon" } }, - "apps/club/node_modules/vitest": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.5.tgz", - "integrity": "sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==", + "node_modules/@intlify/message-compiler": { + "version": "9.13.1", + "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.13.1.tgz", + "integrity": "sha512-SKsVa4ajYGBVm7sHMXd5qX70O2XXjm55zdZB3VeMFCvQyvLew/dLvq3MqnaIsTMF1VkkOb9Ttr6tHcMlyPDL9w==", "dependencies": { - "@ampproject/remapping": "^2.3.0", - "@vitest/expect": "2.0.5", - "@vitest/pretty-format": "^2.0.5", - "@vitest/runner": "2.0.5", - "@vitest/snapshot": "2.0.5", - "@vitest/spy": "2.0.5", - "@vitest/utils": "2.0.5", - "chai": "^5.1.1", - "debug": "^4.3.5", - "execa": "^8.0.1", - "magic-string": "^0.30.10", - "pathe": "^1.1.2", - "std-env": "^3.7.0", - "tinybench": "^2.8.0", - "tinypool": "^1.0.0", - "tinyrainbow": "^1.2.0", - "vite": "^5.0.0", - "vite-node": "2.0.5", - "why-is-node-running": "^2.3.0" - }, - "bin": { - "vitest": "vitest.mjs" + "@intlify/shared": "9.13.1", + "source-map-js": "^1.0.2" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": ">= 16" }, "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.0.5", - "@vitest/ui": "2.0.5", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } + "url": "https://github.com/sponsors/kazupon" } }, - "apps/coach": { - "name": "@kwai/coach", - "version": "1.0.0", - "dependencies": { - "@intlify/unplugin-vue-i18n": "4.0.0", - "@kwai/api": "*", - "@kwai/config": "*", - "@kwai/date": "*", - "@kwai/types": "*", - "@kwai/ui": "*", - "@tanstack/vue-query": "^5.32.0", - "@vuepic/vue-datepicker": "8.4.0", - "@vueuse/core": "^10.9.0", - "vee-validate": "^4.12.6", - "vue": "^3.4.25", - "vue-i18n": "^9.13.1", - "vue-router": "^4.3.2", - "zod": "^3.23.4" + "node_modules/@intlify/shared": { + "version": "9.13.1", + "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.13.1.tgz", + "integrity": "sha512-u3b6BKGhE6j/JeRU6C/RL2FgyJfy6LakbtfeVF8fJXURpZZTzfh3e05J0bu0XPw447Q6/WUp3C4ajv4TMS4YsQ==", + "engines": { + "node": ">= 16" }, - "devDependencies": { - "@vitejs/plugin-vue": "^4.5.0", - "@vue/tsconfig": "^0.4.0", - "autoprefixer": "^10.4.16", - "postcss": "^8.4.31", - "tailwindcss": "^3.4.3", - "vue-tsc": "^1.8.24" + "funding": { + "url": "https://github.com/sponsors/kazupon" } }, - "apps/coach/node_modules/@intlify/unplugin-vue-i18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@intlify/unplugin-vue-i18n/-/unplugin-vue-i18n-4.0.0.tgz", - "integrity": "sha512-q2Mhqa/mLi0tulfLFO4fMXXvEbkSZpI5yGhNNsLTNJJ41icEGUuyDe+j5zRZIKSkOJRgX6YbCyibTDJdRsukmw==", + "node_modules/@intlify/unplugin-vue-i18n": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@intlify/unplugin-vue-i18n/-/unplugin-vue-i18n-1.6.0.tgz", + "integrity": "sha512-IGeFNWxdEvB12E/3Y/+nmIsGeTg5okPsK1XEtUUD/DdkHbVqUbJucMpHKeHF8Px55Qca551pQCs/g+VjNUt6KA==", + "dev": true, "dependencies": { - "@intlify/bundle-utils": "^8.0.0", + "@intlify/bundle-utils": "^7.4.0", "@intlify/shared": "^9.4.0", - "@rollup/pluginutils": "^5.1.0", + "@rollup/pluginutils": "^5.0.2", "@vue/compiler-sfc": "^3.2.47", "debug": "^4.3.3", "fast-glob": "^3.2.12", @@ -931,1717 +1273,1580 @@ } } }, - "apps/portal": { - "name": "@kwai/portal", - "version": "1.0.0", + "node_modules/@intlify/unplugin-vue-i18n/node_modules/@intlify/bundle-utils": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@intlify/bundle-utils/-/bundle-utils-7.5.1.tgz", + "integrity": "sha512-UovJl10oBIlmYEcWw+VIHdKY5Uv5sdPG0b/b6bOYxGLln3UwB75+2dlc0F3Fsa0RhoznQ5Rp589/BZpABpE4Xw==", + "dev": true, "dependencies": { - "@kwai/api": "*", - "@kwai/config": "*", - "@kwai/date": "*", - "@kwai/types": "*", - "@kwai/ui": "*", - "@tanstack/vue-query": "^5.32.0", - "@vueuse/core": "^10.9.0", - "@vueuse/router": "^10.6.1", - "vue": "^3.4.25", - "vue-router": "^4.3.2" - }, - "devDependencies": { - "@vitejs/plugin-vue": "^4.5.0", - "@vue/tsconfig": "^0.4.0", - "autoprefixer": "^10.4.16", - "postcss": "^8.4.31", - "tailwindcss": "^3.4.3", - "vue-tsc": "^1.8.24" + "@intlify/message-compiler": "^9.4.0", + "@intlify/shared": "^9.4.0", + "acorn": "^8.8.2", + "escodegen": "^2.1.0", + "estree-walker": "^2.0.2", + "jsonc-eslint-parser": "^2.3.0", + "magic-string": "^0.30.0", + "mlly": "^1.2.0", + "source-map-js": "^1.0.1", + "yaml-eslint-parser": "^1.2.2" + }, + "engines": { + "node": ">= 14.16" + }, + "peerDependenciesMeta": { + "petite-vue-i18n": { + "optional": true + }, + "vue-i18n": { + "optional": true + } } }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, - "engines": { - "node": ">=10" + "dependencies": { + "@sinclair/typebox": "^0.27.8" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.24.2", - "picocolors": "^1.0.0" - }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "engines": { - "node": ">=6.9.0" + "node": ">=6.0.0" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "engines": { - "node": ">=6.9.0" + "node": ">=6.0.0" } }, - "node_modules/@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", - "dev": true, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/@kwai/api": { + "resolved": "packages/kwai-api", + "link": true + }, + "node_modules/@kwai/auth": { + "resolved": "apps/auth", + "link": true + }, + "node_modules/@kwai/author": { + "resolved": "apps/author", + "link": true + }, + "node_modules/@kwai/club": { + "resolved": "apps/club", + "link": true + }, + "node_modules/@kwai/coach": { + "resolved": "apps/coach", + "link": true + }, + "node_modules/@kwai/config": { + "resolved": "packages/kwai-config", + "link": true + }, + "node_modules/@kwai/date": { + "resolved": "packages/kwai-date", + "link": true + }, + "node_modules/@kwai/portal": { + "resolved": "apps/portal", + "link": true + }, + "node_modules/@kwai/types": { + "resolved": "packages/kwai-types", + "link": true + }, + "node_modules/@kwai/ui": { + "resolved": "packages/kwai-ui", + "link": true + }, + "node_modules/@microsoft/api-extractor": { + "version": "7.43.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.0.tgz", + "integrity": "sha512-GFhTcJpB+MI6FhvXEI9b2K0snulNLWHqC/BbcJtyNYcKUiw7l3Lgis5ApsYncJ0leALX7/of4XfmXk+maT111w==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "@microsoft/api-extractor-model": "7.28.13", + "@microsoft/tsdoc": "0.14.2", + "@microsoft/tsdoc-config": "~0.16.1", + "@rushstack/node-core-library": "4.0.2", + "@rushstack/rig-package": "0.5.2", + "@rushstack/terminal": "0.10.0", + "@rushstack/ts-command-line": "4.19.1", + "lodash": "~4.17.15", + "minimatch": "~3.0.3", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "source-map": "~0.6.1", + "typescript": "5.4.2" }, - "engines": { - "node": ">=4" + "bin": { + "api-extractor": "bin/api-extractor" } }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/@microsoft/api-extractor-model": { + "version": "7.28.13", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.13.tgz", + "integrity": "sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" + "@microsoft/tsdoc": "0.14.2", + "@microsoft/tsdoc-config": "~0.16.1", + "@rushstack/node-core-library": "4.0.2" } }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/@microsoft/api-extractor/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { - "color-name": "1.1.3" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/@microsoft/api-extractor/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, "engines": { - "node": ">=4" + "node": ">=10" } }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/@microsoft/api-extractor/node_modules/minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=4" + "node": "*" } }, - "node_modules/@babel/parser": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", - "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@bundled-es-modules/cookie": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz", - "integrity": "sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==", + "node_modules/@microsoft/api-extractor/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { - "cookie": "^0.5.0" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/@bundled-es-modules/statuses": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz", - "integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==", + "node_modules/@microsoft/api-extractor/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "dependencies": { - "statuses": "^2.0.1" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@effect/schema": { - "version": "0.66.5", - "resolved": "https://registry.npmjs.org/@effect/schema/-/schema-0.66.5.tgz", - "integrity": "sha512-xfu5161JyrfAS1Ruwv0RXd4QFiCALbm3iu9nlW9N9K+52wbS0WdO6XUekPZ9V/O7LN+XmlIh5Y9xhJaIWCZ/gw==", + "node_modules/@microsoft/api-extractor/node_modules/typescript": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", "dev": true, - "peerDependencies": { - "effect": "^3.0.3", - "fast-check": "^3.13.2" + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" + "node_modules/@microsoft/tsdoc": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", + "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", + "dev": true + }, + "node_modules/@microsoft/tsdoc-config": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz", + "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==", + "dev": true, + "dependencies": { + "@microsoft/tsdoc": "0.14.2", + "ajv": "~6.12.6", + "jju": "~1.4.0", + "resolve": "~1.19.0" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], + "node_modules/@microsoft/tsdoc-config/node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" + "dependencies": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], + "node_modules/@mswjs/cookies": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@mswjs/cookies/-/cookies-1.1.0.tgz", + "integrity": "sha512-0ZcCVQxifZmhwNBoQIrystCb+2sWBY2Zw8lpfJBPCHGCA/HWqehITeCRVIv4VMy8MPlaHo2w2pTHFV2pFfqKPw==", "dev": true, - "optional": true, - "os": [ - "android" - ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], + "node_modules/@mswjs/interceptors": { + "version": "0.26.15", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.26.15.tgz", + "integrity": "sha512-HM47Lu1YFmnYHKMBynFfjCp0U/yRskHj/8QEJW0CBEPOlw8Gkmjfll+S9b8M7V5CNDw2/ciRxjjnWeaCiblSIQ==", "dev": true, - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.2.1", + "strict-event-emitter": "^0.5.1" + }, "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, "engines": { - "node": ">=12" + "node": ">= 8" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "engines": { - "node": ">=12" + "node": ">= 8" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, "engines": { - "node": ">=12" + "node": ">= 8" } }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], + "node_modules/@one-ini/wasm": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", + "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", + "dev": true + }, + "node_modules/@open-draft/deferred-promise": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", + "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==", + "dev": true + }, + "node_modules/@open-draft/logger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", + "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" + "dependencies": { + "is-node-process": "^1.2.0", + "outvariant": "^1.4.0" } }, - "node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], + "node_modules/@open-draft/until": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", + "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", + "dev": true + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=12" + "node": ">=14" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@primeuix/styled": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@primeuix/styled/-/styled-0.0.5.tgz", + "integrity": "sha512-pVoGn/uPkVm/DyF3TR3EmH/pL/dP4nR42FcYbVduFq9VfO3KVeOEqvcCULHXos66RZO9MCbCFUoLy6ctf9GUGQ==", + "dependencies": { + "@primeuix/utils": "^0.0.5" + }, + "engines": { + "node": ">=12.11.0" + } + }, + "node_modules/@primeuix/utils": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@primeuix/utils/-/utils-0.0.5.tgz", + "integrity": "sha512-ntUiUgtRtkF8KuaxHffzhYxQxoXk6LAPHm7CVlFjdqS8Rx8xRkLkZVyo84E+pO2hcNFkOGVP/GxHhQ2s94O8zA==", + "engines": { + "node": ">=12.11.0" + } + }, + "node_modules/@primevue/core": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@primevue/core/-/core-4.0.5.tgz", + "integrity": "sha512-DUCslDA93eUOVW0A1I3yoZgRLI4zmI2++loZQXbUF5jaXCwKiAza14+iyUU+cWH27VSq+jQnCEP9QJtPZiJJ0w==", + "dependencies": { + "@primeuix/styled": "^0.0.5", + "@primeuix/utils": "^0.0.5" + }, + "engines": { + "node": ">=12.11.0" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/@primevue/icons": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@primevue/icons/-/icons-4.0.5.tgz", + "integrity": "sha512-ZxR9W1wlAE2fTtUhrHyeMx5t0jNyAgxDcHPm0cNXpX8q1XF95rSM/qb48QKXIBDBrJ/xs57BcyCNADP/VDPY4g==", + "dependencies": { + "@primeuix/utils": "^0.0.5", + "@primevue/core": "4.0.5" + }, + "engines": { + "node": ">=12.11.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz", + "integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==", "cpu": [ - "arm64" + "arm" ], - "dev": true, "optional": true, "os": [ - "linux" + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz", + "integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==", + "cpu": [ + "arm64" ], - "engines": { - "node": ">=12" - } + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz", + "integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==", "cpu": [ - "ia32" + "arm64" ], - "dev": true, "optional": true, "os": [ - "linux" + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz", + "integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==", + "cpu": [ + "x64" ], - "engines": { - "node": ">=12" - } + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz", + "integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==", "cpu": [ - "loong64" + "arm" ], - "dev": true, "optional": true, "os": [ "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz", + "integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==", + "cpu": [ + "arm" ], - "engines": { - "node": ">=12" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz", + "integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==", "cpu": [ - "mips64el" + "arm64" ], - "dev": true, "optional": true, "os": [ "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz", + "integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==", + "cpu": [ + "arm64" ], - "engines": { - "node": ">=12" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz", + "integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==", "cpu": [ "ppc64" ], - "dev": true, "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">=12" - } + ] }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz", + "integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==", "cpu": [ "riscv64" ], - "dev": true, "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">=12" - } + ] }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz", + "integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==", "cpu": [ "s390x" ], - "dev": true, "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">=12" - } + ] }, - "node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz", + "integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==", "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">=12" - } + ] }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz", + "integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==", "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } + "linux" + ] }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz", + "integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==", "cpu": [ - "x64" + "arm64" ], - "dev": true, "optional": true, "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } + "win32" + ] }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz", + "integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==", "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" - ], - "engines": { - "node": ">=12" - } + ] }, - "node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz", + "integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==", "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" - ], - "engines": { - "node": ">=12" - } + ] }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "node_modules/@rushstack/node-core-library": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", + "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", + "dev": true, "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "z-schema": "~5.0.2" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "node_modules/@rushstack/node-core-library/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" + "yallist": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node": ">=10" } }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@rushstack/node-core-library/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": "*" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=10" } }, - "node_modules/@fbraem/rollup-plugin-toml": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/@fbraem/rollup-plugin-toml/-/rollup-plugin-toml-0.0.4.tgz", - "integrity": "sha512-pk/zSCpsNq/SbzE+1JFrsiH4f2iGkeTGfi8YbBZdo+l7XeLtk130XostppcrIKDVGzONk8IhfBnqr6FoDo/pIw==", + "node_modules/@rushstack/rig-package": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.2.tgz", + "integrity": "sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==", "dev": true, "dependencies": { - "@iarna/toml": "^3.0.0", - "@rollup/pluginutils": "^4.1.0" + "resolve": "~1.22.1", + "strip-json-comments": "~3.1.1" } }, - "node_modules/@fbraem/rollup-plugin-toml/node_modules/@rollup/pluginutils": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", - "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "node_modules/@rushstack/terminal": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.0.tgz", + "integrity": "sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==", "dev": true, "dependencies": { - "estree-walker": "^2.0.1", - "picomatch": "^2.2.2" + "@rushstack/node-core-library": "4.0.2", + "supports-color": "~8.1.1" }, - "engines": { - "node": ">= 8.0.0" + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "node_modules/@rushstack/terminal/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=10.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@rushstack/ts-command-line": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.1.tgz", + "integrity": "sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==", + "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@rushstack/terminal": "0.10.0", + "@types/argparse": "1.0.38", + "argparse": "~1.0.9", + "string-argv": "~0.3.1" } }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@rushstack/ts-command-line/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "sprintf-js": "~1.0.2" } }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, "engines": { - "node": ">=12.22" + "node": ">=18" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==" - }, - "node_modules/@iarna/toml": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-3.0.0.tgz", - "integrity": "sha512-td6ZUkz2oS3VeleBcN+m//Q6HlCFCPrnI0FZhrt/h4XqLEdOyYp2u21nd8MdsR+WJy5r9PTDaHTDDfhf4H4l6Q==", - "dev": true - }, - "node_modules/@inquirer/confirm": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.1.5.tgz", - "integrity": "sha512-6+dwZrpko5vr5EFEQmUbfBVhtu6IsnB8lQNsLHgO9S9fbfS5J6MuUj+NY0h98pPpYZXEazLR7qzypEDqVzf6aQ==", + "node_modules/@tailwindcss/forms": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz", + "integrity": "sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==", "dev": true, "dependencies": { - "@inquirer/core": "^8.0.1", - "@inquirer/type": "^1.3.0" + "mini-svg-data-uri": "^1.2.3" }, - "engines": { - "node": ">=18" + "peerDependencies": { + "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1" } }, - "node_modules/@inquirer/core": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-8.0.1.tgz", - "integrity": "sha512-qJRk1y51Os2ARc11Bg2N6uIwiQ9qBSrmZeuMonaQ/ntFpb4+VlcQ8Gl1TFH67mJLz3HA2nvuave0nbv6Lu8pbg==", - "dev": true, + "node_modules/@tanstack/match-sorter-utils": { + "version": "8.15.1", + "resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.15.1.tgz", + "integrity": "sha512-PnVV3d2poenUM31ZbZi/yXkBu3J7kd5k2u51CGwwNojag451AjTH9N6n41yjXz2fpLeewleyLBmNS6+HcGDlXw==", "dependencies": { - "@inquirer/figures": "^1.0.1", - "@inquirer/type": "^1.3.0", - "@types/mute-stream": "^0.0.4", - "@types/node": "^20.12.7", - "@types/wrap-ansi": "^3.0.0", - "ansi-escapes": "^4.3.2", - "chalk": "^4.1.2", - "cli-spinners": "^2.9.2", - "cli-width": "^4.1.0", - "mute-stream": "^1.0.0", - "signal-exit": "^4.1.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^6.2.0" + "remove-accents": "0.5.0" }, "engines": { - "node": ">=18" - } - }, - "node_modules/@inquirer/core/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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@inquirer/core/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==", - "dev": true - }, - "node_modules/@inquirer/core/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==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "node": ">=12" }, - "engines": { - "node": ">=8" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" } }, - "node_modules/@inquirer/core/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==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" + "node_modules/@tanstack/query-core": { + "version": "5.32.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.32.0.tgz", + "integrity": "sha512-Z3flEgCat55DRXU5UMwYU1U+DgFZKA3iufyOKs+II7iRAo0uXkeU7PH5e6sOH1CGEag0IpKmZxlUFpCg6roSKw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" } }, - "node_modules/@inquirer/core/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, + "node_modules/@tanstack/vue-query": { + "version": "5.32.0", + "resolved": "https://registry.npmjs.org/@tanstack/vue-query/-/vue-query-5.32.0.tgz", + "integrity": "sha512-lmTw3NZud+iT6EqbF1fYNE/7mA2lk3iD8KexF3scV2uWfeTE9diboNjNbZGyBHQSQOzmZJYh7Stnv+ARa8Femw==", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "@tanstack/match-sorter-utils": "^8.11.8", + "@tanstack/query-core": "5.32.0", + "@vue/devtools-api": "^6.5.1", + "vue-demi": "^0.14.6" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@inquirer/figures": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.1.tgz", - "integrity": "sha512-mtup3wVKia3ZwULPHcbs4Mor8Voi+iIXEWD7wCNbIO6lYR62oPCTQyrddi5OMYVXHzeCSoneZwJuS8sBvlEwDw==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@inquirer/type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.3.0.tgz", - "integrity": "sha512-RW4Zf6RCTnInRaOZuRHTqAUl+v6VJuQGglir7nW2BkT3OXOphMhkIFhvFRjorBx2l0VwtC/M4No8vYR65TdN9Q==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@intlify/bundle-utils": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@intlify/bundle-utils/-/bundle-utils-8.0.0.tgz", - "integrity": "sha512-1B++zykRnMwQ+20SpsZI1JCnV/YJt9Oq7AGlEurzkWJOFtFAVqaGc/oV36PBRYeiKnTbY9VYfjBimr2Vt42wLQ==", - "dependencies": { - "@intlify/message-compiler": "^9.4.0", - "@intlify/shared": "^9.4.0", - "acorn": "^8.8.2", - "escodegen": "^2.1.0", - "estree-walker": "^2.0.2", - "jsonc-eslint-parser": "^2.3.0", - "mlly": "^1.2.0", - "source-map-js": "^1.0.1", - "yaml-eslint-parser": "^1.2.2" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" }, - "engines": { - "node": ">= 14.16" + "peerDependencies": { + "@vue/composition-api": "^1.1.2", + "vue": "^2.6.0 || ^3.3.0" }, "peerDependenciesMeta": { - "petite-vue-i18n": { - "optional": true - }, - "vue-i18n": { + "@vue/composition-api": { "optional": true } } }, - "node_modules/@intlify/core-base": { - "version": "9.13.1", - "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.13.1.tgz", - "integrity": "sha512-+bcQRkJO9pcX8d0gel9ZNfrzU22sZFSA0WVhfXrf5jdJOS24a+Bp8pozuS9sBI9Hk/tGz83pgKfmqcn/Ci7/8w==", - "dependencies": { - "@intlify/message-compiler": "9.13.1", - "@intlify/shared": "9.13.1" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@intlify/message-compiler": { - "version": "9.13.1", - "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.13.1.tgz", - "integrity": "sha512-SKsVa4ajYGBVm7sHMXd5qX70O2XXjm55zdZB3VeMFCvQyvLew/dLvq3MqnaIsTMF1VkkOb9Ttr6tHcMlyPDL9w==", - "dependencies": { - "@intlify/shared": "9.13.1", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": ">= 16" + "node_modules/@tanstack/vue-query/node_modules/vue-demi": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@intlify/shared": { - "version": "9.13.1", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.13.1.tgz", - "integrity": "sha512-u3b6BKGhE6j/JeRU6C/RL2FgyJfy6LakbtfeVF8fJXURpZZTzfh3e05J0bu0XPw447Q6/WUp3C4ajv4TMS4YsQ==", "engines": { - "node": ">= 16" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@intlify/unplugin-vue-i18n": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@intlify/unplugin-vue-i18n/-/unplugin-vue-i18n-1.6.0.tgz", - "integrity": "sha512-IGeFNWxdEvB12E/3Y/+nmIsGeTg5okPsK1XEtUUD/DdkHbVqUbJucMpHKeHF8Px55Qca551pQCs/g+VjNUt6KA==", - "dev": true, - "dependencies": { - "@intlify/bundle-utils": "^7.4.0", - "@intlify/shared": "^9.4.0", - "@rollup/pluginutils": "^5.0.2", - "@vue/compiler-sfc": "^3.2.47", - "debug": "^4.3.3", - "fast-glob": "^3.2.12", - "js-yaml": "^4.1.0", - "json5": "^2.2.3", - "pathe": "^1.0.0", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2", - "unplugin": "^1.1.0" - }, - "engines": { - "node": ">= 14.16" + "url": "https://github.com/sponsors/antfu" }, "peerDependencies": { - "petite-vue-i18n": "*", - "vue-i18n": "*", - "vue-i18n-bridge": "*" + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" }, "peerDependenciesMeta": { - "petite-vue-i18n": { - "optional": true - }, - "vue-i18n": { - "optional": true - }, - "vue-i18n-bridge": { + "@vue/composition-api": { "optional": true } } }, - "node_modules/@intlify/unplugin-vue-i18n/node_modules/@intlify/bundle-utils": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/@intlify/bundle-utils/-/bundle-utils-7.5.1.tgz", - "integrity": "sha512-UovJl10oBIlmYEcWw+VIHdKY5Uv5sdPG0b/b6bOYxGLln3UwB75+2dlc0F3Fsa0RhoznQ5Rp589/BZpABpE4Xw==", + "node_modules/@types/argparse": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", + "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", + "dev": true + }, + "node_modules/@types/chai": { + "version": "4.3.19", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.19.tgz", + "integrity": "sha512-2hHHvQBVE2FiSK4eN0Br6snX9MtolHaTo/batnLjlGRhoQzlCL61iVpxoqO7SfFyOw+P/pwv+0zNHzKoGWz9Cw==", + "dev": true + }, + "node_modules/@types/chai-subset": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.5.tgz", + "integrity": "sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==", "dev": true, "dependencies": { - "@intlify/message-compiler": "^9.4.0", - "@intlify/shared": "^9.4.0", - "acorn": "^8.8.2", - "escodegen": "^2.1.0", - "estree-walker": "^2.0.2", - "jsonc-eslint-parser": "^2.3.0", - "magic-string": "^0.30.0", - "mlly": "^1.2.0", - "source-map-js": "^1.0.1", - "yaml-eslint-parser": "^1.2.2" + "@types/chai": "*" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "peer": true + }, + "node_modules/@types/mute-stream": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz", + "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "20.12.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", + "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", + "devOptional": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==" + }, + "node_modules/@types/statuses": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.5.tgz", + "integrity": "sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==", + "dev": true + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", + "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==" + }, + "node_modules/@types/wrap-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", + "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.1.tgz", + "integrity": "sha512-KwfdWXJBOviaBVhxO3p5TJiLpNuh2iyXyjmWN0f1nU87pwyvfS0EmjC6ukQVYVFJd/K1+0NWGPDXiyEyQorn0Q==", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/type-utils": "7.7.1", + "@typescript-eslint/utils": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": ">= 14.16" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" }, "peerDependenciesMeta": { - "petite-vue-i18n": { - "optional": true - }, - "vue-i18n": { + "typescript": { "optional": true } } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, + "node_modules/@typescript-eslint/parser": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.1.tgz", + "integrity": "sha512-vmPzBOOtz48F6JAGVS/kZYk4EkXao6iGrD838sp1w3NQQC0W8ry/q641KU4PrG7AKNAf56NOcR8GOpH8l9FPCw==", "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/typescript-estree": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", + "debug": "^4.3.4" }, "engines": { - "node": ">=12" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.1.tgz", + "integrity": "sha512-PytBif2SF+9SpEUKynYn5g1RHFddJUcyynGpztX3l/ik7KmZEv19WCMhUBkHXPU9es/VWGD3/zg3wg90+Dh2rA==", "dependencies": { - "@sinclair/typebox": "^0.27.8" + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "node_modules/@typescript-eslint/type-utils": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.1.tgz", + "integrity": "sha512-ZksJLW3WF7o75zaBPScdW1Gbkwhd/lyeXGf1kQCxJaOeITscoSl0MjynVvCzuV5boUz/3fOI06Lz8La55mu29Q==", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" + "@typescript-eslint/typescript-estree": "7.7.1", + "@typescript-eslint/utils": "7.7.1", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": ">=6.0.0" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "node_modules/@typescript-eslint/types": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.1.tgz", + "integrity": "sha512-AmPmnGW1ZLTpWa+/2omPrPfR7BcbUU4oha5VIbSbS1a1Tv966bklvLNXxp3mrbc+P2j4MNOTfDffNsk4o0c6/w==", "engines": { - "node": ">=6.0.0" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.1.tgz", + "integrity": "sha512-CXe0JHCXru8Fa36dteXqmH2YxngKJjkQLjxzoj6LYwzZ7qZvgsLSc+eqItCrqIop8Vl2UKoAi0StVWu97FQZIQ==", + "dependencies": { + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, "engines": { - "node": ">=6.0.0" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@kwai/api": { - "resolved": "packages/kwai-api", - "link": true - }, - "node_modules/@kwai/auth": { - "resolved": "apps/auth", - "link": true - }, - "node_modules/@kwai/author": { - "resolved": "apps/author", - "link": true - }, - "node_modules/@kwai/club": { - "resolved": "apps/club", - "link": true - }, - "node_modules/@kwai/coach": { - "resolved": "apps/coach", - "link": true - }, - "node_modules/@kwai/config": { - "resolved": "packages/kwai-config", - "link": true - }, - "node_modules/@kwai/date": { - "resolved": "packages/kwai-date", - "link": true - }, - "node_modules/@kwai/portal": { - "resolved": "apps/portal", - "link": true - }, - "node_modules/@kwai/types": { - "resolved": "packages/kwai-types", - "link": true - }, - "node_modules/@kwai/ui": { - "resolved": "packages/kwai-ui", - "link": true - }, - "node_modules/@microsoft/api-extractor": { - "version": "7.43.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.0.tgz", - "integrity": "sha512-GFhTcJpB+MI6FhvXEI9b2K0snulNLWHqC/BbcJtyNYcKUiw7l3Lgis5ApsYncJ0leALX7/of4XfmXk+maT111w==", - "dev": true, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dependencies": { - "@microsoft/api-extractor-model": "7.28.13", - "@microsoft/tsdoc": "0.14.2", - "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "4.0.2", - "@rushstack/rig-package": "0.5.2", - "@rushstack/terminal": "0.10.0", - "@rushstack/ts-command-line": "4.19.1", - "lodash": "~4.17.15", - "minimatch": "~3.0.3", - "resolve": "~1.22.1", - "semver": "~7.5.4", - "source-map": "~0.6.1", - "typescript": "5.4.2" + "brace-expansion": "^2.0.1" }, - "bin": { - "api-extractor": "bin/api-extractor" - } - }, - "node_modules/@microsoft/api-extractor-model": { - "version": "7.28.13", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.13.tgz", - "integrity": "sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==", - "dev": true, - "dependencies": { - "@microsoft/tsdoc": "0.14.2", - "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "4.0.2" - } - }, - "node_modules/@microsoft/api-extractor/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@microsoft/api-extractor/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/@microsoft/api-extractor/node_modules/minimatch": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", - "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", - "dev": true, + "node_modules/@typescript-eslint/utils": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.1.tgz", + "integrity": "sha512-QUvBxPEaBXf41ZBbaidKICgVL8Hin0p6prQDu6bbetWo39BKbWJxRsErOzMNT1rXvTll+J7ChrbmMCXM9rsvOQ==", "dependencies": { - "brace-expansion": "^1.1.7" + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.15", + "@types/semver": "^7.5.8", + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/typescript-estree": "7.7.1", + "semver": "^7.6.0" }, "engines": { - "node": "*" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" } }, - "node_modules/@microsoft/api-extractor/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.1.tgz", + "integrity": "sha512-gBL3Eq25uADw1LQ9kVpf3hRM+DWzs0uZknHYK3hq4jcTPqVCClHGDnB6UUUV2SFeBeA4KWHWbbLqmbGcZ4FYbw==", "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "@typescript-eslint/types": "7.7.1", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": ">=10" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@microsoft/api-extractor/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.6.2.tgz", + "integrity": "sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.0.0 || ^5.0.0", + "vue": "^3.2.25" } }, - "node_modules/@microsoft/api-extractor/node_modules/typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "node_modules/@vitest/expect": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz", + "integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==", + "dependencies": { + "@vitest/spy": "2.0.5", + "@vitest/utils": "2.0.5", + "chai": "^5.1.1", + "tinyrainbow": "^1.2.0" }, - "engines": { - "node": ">=14.17" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@microsoft/tsdoc": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", - "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", - "dev": true - }, - "node_modules/@microsoft/tsdoc-config": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz", - "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==", - "dev": true, + "node_modules/@vitest/pretty-format": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz", + "integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==", "dependencies": { - "@microsoft/tsdoc": "0.14.2", - "ajv": "~6.12.6", - "jju": "~1.4.0", - "resolve": "~1.19.0" + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@microsoft/tsdoc-config/node_modules/resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", - "dev": true, + "node_modules/@vitest/runner": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.5.tgz", + "integrity": "sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==", "dependencies": { - "is-core-module": "^2.1.0", - "path-parse": "^1.0.6" + "@vitest/utils": "2.0.5", + "pathe": "^1.1.2" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/vitest" } }, - "node_modules/@mswjs/cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@mswjs/cookies/-/cookies-1.1.0.tgz", - "integrity": "sha512-0ZcCVQxifZmhwNBoQIrystCb+2sWBY2Zw8lpfJBPCHGCA/HWqehITeCRVIv4VMy8MPlaHo2w2pTHFV2pFfqKPw==", - "dev": true, - "engines": { - "node": ">=18" + "node_modules/@vitest/snapshot": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.5.tgz", + "integrity": "sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==", + "dependencies": { + "@vitest/pretty-format": "2.0.5", + "magic-string": "^0.30.10", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@mswjs/interceptors": { - "version": "0.26.15", - "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.26.15.tgz", - "integrity": "sha512-HM47Lu1YFmnYHKMBynFfjCp0U/yRskHj/8QEJW0CBEPOlw8Gkmjfll+S9b8M7V5CNDw2/ciRxjjnWeaCiblSIQ==", - "dev": true, + "node_modules/@vitest/spy": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz", + "integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==", "dependencies": { - "@open-draft/deferred-promise": "^2.2.0", - "@open-draft/logger": "^0.3.0", - "@open-draft/until": "^2.0.0", - "is-node-process": "^1.2.0", - "outvariant": "^1.2.1", - "strict-event-emitter": "^0.5.1" + "tinyspy": "^3.0.0" }, - "engines": { - "node": ">=18" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@vitest/utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz", + "integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==", "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@vitest/pretty-format": "2.0.5", + "estree-walker": "^3.0.3", + "loupe": "^3.1.1", + "tinyrainbow": "^1.2.0" }, - "engines": { - "node": ">= 8" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "engines": { - "node": ">= 8" + "node_modules/@vitest/utils/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/@volar/language-core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.11.1.tgz", + "integrity": "sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==", + "dev": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" + "@volar/source-map": "1.11.1" } }, - "node_modules/@one-ini/wasm": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", - "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", - "dev": true - }, - "node_modules/@open-draft/deferred-promise": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", - "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==", - "dev": true - }, - "node_modules/@open-draft/logger": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", - "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", + "node_modules/@volar/source-map": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.11.1.tgz", + "integrity": "sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==", "dev": true, "dependencies": { - "is-node-process": "^1.2.0", - "outvariant": "^1.4.0" + "muggle-string": "^0.3.1" } }, - "node_modules/@open-draft/until": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", - "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", - "dev": true - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "node_modules/@volar/typescript": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.11.1.tgz", + "integrity": "sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==", "dev": true, - "optional": true, - "engines": { - "node": ">=14" + "dependencies": { + "@volar/language-core": "1.11.1", + "path-browserify": "^1.0.1" } }, - "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" + "node_modules/@vue/compiler-core": { + "version": "3.4.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.25.tgz", + "integrity": "sha512-Y2pLLopaElgWnMNolgG8w3C5nNUVev80L7hdQ5iIKPtMJvhVpG0zhnBG/g3UajJmZdvW0fktyZTotEHD1Srhbg==", + "dependencies": { + "@babel/parser": "^7.24.4", + "@vue/shared": "3.4.25", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.0" } }, - "node_modules/@rollup/pluginutils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", - "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "node_modules/@vue/compiler-dom": { + "version": "3.4.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.25.tgz", + "integrity": "sha512-Ugz5DusW57+HjllAugLci19NsDK+VyjGvmbB2TXaTcSlQxwL++2PETHx/+Qv6qFwNLzSt7HKepPe4DcTE3pBWg==", "dependencies": { - "@types/estree": "^1.0.0", + "@vue/compiler-core": "3.4.25", + "@vue/shared": "3.4.25" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.4.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.25.tgz", + "integrity": "sha512-m7rryuqzIoQpOBZ18wKyq05IwL6qEpZxFZfRxlNYuIPDqywrXQxgUwLXIvoU72gs6cRdY6wHD0WVZIFE4OEaAQ==", + "dependencies": { + "@babel/parser": "^7.24.4", + "@vue/compiler-core": "3.4.25", + "@vue/compiler-dom": "3.4.25", + "@vue/compiler-ssr": "3.4.25", + "@vue/shared": "3.4.25", "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" + "magic-string": "^0.30.10", + "postcss": "^8.4.38", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.4.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.25.tgz", + "integrity": "sha512-H2ohvM/Pf6LelGxDBnfbbXFPyM4NE3hrw0e/EpwuSiYu8c819wx+SVGdJ65p/sFrYDd6OnSDxN1MB2mN07hRSQ==", + "dependencies": { + "@vue/compiler-dom": "3.4.25", + "@vue/shared": "3.4.25" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.1.tgz", + "integrity": "sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==" + }, + "node_modules/@vue/eslint-config-typescript": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-13.0.0.tgz", + "integrity": "sha512-MHh9SncG/sfqjVqjcuFLOLD6Ed4dRAis4HNt0dXASeAuLqIAx4YMB1/m2o4pUKK1vCt8fUvYG8KKX2Ot3BVZTg==", + "dependencies": { + "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typescript-eslint/parser": "^7.1.1", + "vue-eslint-parser": "^9.3.1" }, "engines": { - "node": ">=14.0.0" + "node": "^18.18.0 || >=20.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + "eslint": "^8.56.0", + "eslint-plugin-vue": "^9.0.0", + "typescript": ">=4.7.4" }, "peerDependenciesMeta": { - "rollup": { + "typescript": { "optional": true } } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz", - "integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ] + "node_modules/@vue/language-core": { + "version": "1.8.27", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.27.tgz", + "integrity": "sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==", + "dev": true, + "dependencies": { + "@volar/language-core": "~1.11.1", + "@volar/source-map": "~1.11.1", + "@vue/compiler-dom": "^3.3.0", + "@vue/shared": "^3.3.0", + "computeds": "^0.0.1", + "minimatch": "^9.0.3", + "muggle-string": "^0.3.1", + "path-browserify": "^1.0.1", + "vue-template-compiler": "^2.7.14" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz", - "integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ] + "node_modules/@vue/language-core/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz", - "integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ] + "node_modules/@vue/reactivity": { + "version": "3.4.25", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.25.tgz", + "integrity": "sha512-mKbEtKr1iTxZkAG3vm3BtKHAOhuI4zzsVcN0epDldU/THsrvfXRKzq+lZnjczZGnTdh3ojd86/WrP+u9M51pWQ==", + "dependencies": { + "@vue/shared": "3.4.25" + } }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz", - "integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz", - "integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz", - "integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz", - "integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz", - "integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz", - "integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz", - "integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz", - "integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz", - "integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz", - "integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz", - "integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz", - "integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz", - "integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rushstack/node-core-library": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", - "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", - "dev": true, + "node_modules/@vue/runtime-core": { + "version": "3.4.25", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.25.tgz", + "integrity": "sha512-3qhsTqbEh8BMH3pXf009epCI5E7bKu28fJLi9O6W+ZGt/6xgSfMuGPqa5HRbUxLoehTNp5uWvzCr60KuiRIL0Q==", "dependencies": { - "fs-extra": "~7.0.1", - "import-lazy": "~4.0.0", - "jju": "~1.4.0", - "resolve": "~1.22.1", - "semver": "~7.5.4", - "z-schema": "~5.0.2" - }, - "peerDependencies": { - "@types/node": "*" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "@vue/reactivity": "3.4.25", + "@vue/shared": "3.4.25" } }, - "node_modules/@rushstack/node-core-library/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, + "node_modules/@vue/runtime-dom": { + "version": "3.4.25", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.25.tgz", + "integrity": "sha512-ode0sj77kuwXwSc+2Yhk8JMHZh1sZp9F/51wdBiz3KGaWltbKtdihlJFhQG4H6AY+A06zzeMLkq6qu8uDSsaoA==", "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "@vue/runtime-core": "3.4.25", + "@vue/shared": "3.4.25", + "csstype": "^3.1.3" } }, - "node_modules/@rushstack/node-core-library/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, + "node_modules/@vue/server-renderer": { + "version": "3.4.25", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.25.tgz", + "integrity": "sha512-8VTwq0Zcu3K4dWV0jOwIVINESE/gha3ifYCOKEhxOj6MEl5K5y8J8clQncTcDhKF+9U765nRw4UdUEXvrGhyVQ==", "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "@vue/compiler-ssr": "3.4.25", + "@vue/shared": "3.4.25" }, - "engines": { - "node": ">=10" + "peerDependencies": { + "vue": "3.4.25" } }, - "node_modules/@rushstack/rig-package": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.2.tgz", - "integrity": "sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==", - "dev": true, - "dependencies": { - "resolve": "~1.22.1", - "strip-json-comments": "~3.1.1" - } + "node_modules/@vue/shared": { + "version": "3.4.25", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.25.tgz", + "integrity": "sha512-k0yappJ77g2+KNrIaF0FFnzwLvUBLUYr8VOwz+/6vLsmItFp51AcxLL7Ey3iPd7BIRyWPOcqUjMnm7OkahXllA==" }, - "node_modules/@rushstack/terminal": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.0.tgz", - "integrity": "sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==", + "node_modules/@vue/test-utils": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-2.4.5.tgz", + "integrity": "sha512-oo2u7vktOyKUked36R93NB7mg2B+N7Plr8lxp2JBGwr18ch6EggFjixSCdIVVLkT6Qr0z359Xvnafc9dcKyDUg==", "dev": true, "dependencies": { - "@rushstack/node-core-library": "4.0.2", - "supports-color": "~8.1.1" - }, - "peerDependencies": { - "@types/node": "*" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "js-beautify": "^1.14.9", + "vue-component-type-helpers": "^2.0.0" } }, - "node_modules/@rushstack/terminal/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, + "node_modules/@vue/tsconfig": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@vue/tsconfig/-/tsconfig-0.4.0.tgz", + "integrity": "sha512-CPuIReonid9+zOG/CGTT05FXrPYATEqoDGNrEaqS4hwcw5BUNM2FguC0mOwJD4Jr16UpRVl9N0pY3P+srIbqmg==", + "dev": true + }, + "node_modules/@vuepic/vue-datepicker": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@vuepic/vue-datepicker/-/vue-datepicker-8.4.0.tgz", + "integrity": "sha512-Twgvqwd5GrQf3JT2DvAQ/Ku0+sM51zsH1OkQKoRwYqJyF+EugItS8I0CveYmcI3Gbu92RZ9C3DMutvkaiuDzAQ==", "dependencies": { - "has-flag": "^4.0.0" + "date-fns": "^3.6.0" }, "engines": { - "node": ">=10" + "node": ">=18.12.0" }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/@rushstack/ts-command-line": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.1.tgz", - "integrity": "sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==", - "dev": true, - "dependencies": { - "@rushstack/terminal": "0.10.0", - "@types/argparse": "1.0.38", - "argparse": "~1.0.9", - "string-argv": "~0.3.1" + "peerDependencies": { + "vue": ">=3.2.0" } }, - "node_modules/@rushstack/ts-command-line/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, + "node_modules/@vueuse/core": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.9.0.tgz", + "integrity": "sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==", "dependencies": { - "sprintf-js": "~1.0.2" + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "10.9.0", + "@vueuse/shared": "10.9.0", + "vue-demi": ">=0.14.7" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true - }, - "node_modules/@sindresorhus/merge-streams": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", - "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", - "dev": true, + "node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, "engines": { - "node": ">=18" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@tailwindcss/forms": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz", - "integrity": "sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==", - "dev": true, - "dependencies": { - "mini-svg-data-uri": "^1.2.3" + "url": "https://github.com/sponsors/antfu" }, "peerDependencies": { - "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1" + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/metadata": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.9.0.tgz", + "integrity": "sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==", + "funding": { + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/@tanstack/match-sorter-utils": { - "version": "8.15.1", - "resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.15.1.tgz", - "integrity": "sha512-PnVV3d2poenUM31ZbZi/yXkBu3J7kd5k2u51CGwwNojag451AjTH9N6n41yjXz2fpLeewleyLBmNS6+HcGDlXw==", + "node_modules/@vueuse/router": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@vueuse/router/-/router-11.0.3.tgz", + "integrity": "sha512-Sa8wNATd4DoAWkO5NgV+sfTU9dOtC8pi+GEbtzOdC7/99fWK8k5/dfbfkt+OWcpwXoToNidBqnAZafknlYb2ig==", "dependencies": { - "remove-accents": "0.5.0" - }, - "engines": { - "node": ">=12" + "@vueuse/shared": "11.0.3", + "vue-demi": ">=0.14.10" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vue-router": ">=4.0.0-rc.1" } }, - "node_modules/@tanstack/query-core": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.32.0.tgz", - "integrity": "sha512-Z3flEgCat55DRXU5UMwYU1U+DgFZKA3iufyOKs+II7iRAo0uXkeU7PH5e6sOH1CGEag0IpKmZxlUFpCg6roSKw==", + "node_modules/@vueuse/router/node_modules/@vueuse/shared": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-11.0.3.tgz", + "integrity": "sha512-0rY2m6HS5t27n/Vp5cTDsKTlNnimCqsbh/fmT2LgE+aaU42EMfXo8+bNX91W9I7DDmxfuACXMmrd7d79JxkqWA==", + "dependencies": { + "vue-demi": ">=0.14.10" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/@tanstack/vue-query": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@tanstack/vue-query/-/vue-query-5.32.0.tgz", - "integrity": "sha512-lmTw3NZud+iT6EqbF1fYNE/7mA2lk3iD8KexF3scV2uWfeTE9diboNjNbZGyBHQSQOzmZJYh7Stnv+ARa8Femw==", - "dependencies": { - "@tanstack/match-sorter-utils": "^8.11.8", - "@tanstack/query-core": "5.32.0", - "@vue/devtools-api": "^6.5.1", - "vue-demi": "^0.14.6" + "node_modules/@vueuse/router/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" + "url": "https://github.com/sponsors/antfu" }, "peerDependencies": { - "@vue/composition-api": "^1.1.2", - "vue": "^2.6.0 || ^3.3.0" + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" }, "peerDependenciesMeta": { "@vue/composition-api": { @@ -2649,7 +2854,18 @@ } } }, - "node_modules/@tanstack/vue-query/node_modules/vue-demi": { + "node_modules/@vueuse/shared": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.9.0.tgz", + "integrity": "sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==", + "dependencies": { + "vue-demi": ">=0.14.7" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared/node_modules/vue-demi": { "version": "0.14.7", "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", @@ -2674,376 +2890,585 @@ } } }, - "node_modules/@types/argparse": { - "version": "1.0.38", - "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", - "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", - "dev": true + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "node_modules/@types/chai": { - "version": "4.3.14", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz", - "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==", - "dev": true + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } }, - "node_modules/@types/chai-subset": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.5.tgz", - "integrity": "sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", "dev": true, "dependencies": { - "@types/chai": "*" + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" } }, - "node_modules/@types/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "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==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", "dev": true }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "peer": true + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/@types/mute-stream": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz", - "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", - "dev": true, - "dependencies": { - "@types/node": "*" + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" } }, - "node_modules/@types/node": { - "version": "20.12.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", - "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", - "devOptional": true, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "peer": true, "dependencies": { - "undici-types": "~5.26.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==" - }, - "node_modules/@types/statuses": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.5.tgz", - "integrity": "sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==", - "dev": true - }, - "node_modules/@types/web-bluetooth": { - "version": "0.0.20", - "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", - "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==" - }, - "node_modules/@types/wrap-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", - "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.1.tgz", - "integrity": "sha512-KwfdWXJBOviaBVhxO3p5TJiLpNuh2iyXyjmWN0f1nU87pwyvfS0EmjC6ukQVYVFJd/K1+0NWGPDXiyEyQorn0Q==", + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "peer": true, "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.7.1", - "@typescript-eslint/type-utils": "7.7.1", - "@typescript-eslint/utils": "7.7.1", - "@typescript-eslint/visitor-keys": "7.7.1", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" + "engines": { + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@typescript-eslint/parser": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.1.tgz", - "integrity": "sha512-vmPzBOOtz48F6JAGVS/kZYk4EkXao6iGrD838sp1w3NQQC0W8ry/q641KU4PrG7AKNAf56NOcR8GOpH8l9FPCw==", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.7.1", - "@typescript-eslint/types": "7.7.1", - "@typescript-eslint/typescript-estree": "7.7.1", - "@typescript-eslint/visitor-keys": "7.7.1", - "debug": "^4.3.4" + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", + "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001599", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" }, - "peerDependencies": { - "eslint": "^8.56.0" + "bin": { + "autoprefixer": "bin/autoprefixer" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.1.tgz", - "integrity": "sha512-PytBif2SF+9SpEUKynYn5g1RHFddJUcyynGpztX3l/ik7KmZEv19WCMhUBkHXPU9es/VWGD3/zg3wg90+Dh2rA==", + "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==", + "peer": true, "dependencies": { - "@typescript-eslint/types": "7.7.1", - "@typescript-eslint/visitor-keys": "7.7.1" + "possible-typed-array-names": "^1.0.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.1.tgz", - "integrity": "sha512-ZksJLW3WF7o75zaBPScdW1Gbkwhd/lyeXGf1kQCxJaOeITscoSl0MjynVvCzuV5boUz/3fOI06Lz8La55mu29Q==", + "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==" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "@typescript-eslint/typescript-estree": "7.7.1", - "@typescript-eslint/utils": "7.7.1", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" }, - "peerDependencies": { - "eslint": "^8.56.0" + "bin": { + "browserslist": "cli.js" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/@typescript-eslint/types": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.1.tgz", - "integrity": "sha512-AmPmnGW1ZLTpWa+/2omPrPfR7BcbUU4oha5VIbSbS1a1Tv966bklvLNXxp3mrbc+P2j4MNOTfDffNsk4o0c6/w==", + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "peer": true, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": ">=6" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.1.tgz", - "integrity": "sha512-CXe0JHCXru8Fa36dteXqmH2YxngKJjkQLjxzoj6LYwzZ7qZvgsLSc+eqItCrqIop8Vl2UKoAi0StVWu97FQZIQ==", + "node_modules/builtins": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", + "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==", "dependencies": { - "@typescript-eslint/types": "7.7.1", - "@typescript-eslint/visitor-keys": "7.7.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, + "semver": "^7.0.0" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=8" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "peer": true, "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=6" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, "engines": { - "node": ">=8" + "node": ">= 6" } }, - "node_modules/@typescript-eslint/utils": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.1.tgz", - "integrity": "sha512-QUvBxPEaBXf41ZBbaidKICgVL8Hin0p6prQDu6bbetWo39BKbWJxRsErOzMNT1rXvTll+J7ChrbmMCXM9rsvOQ==", + "node_modules/caniuse-lite": { + "version": "1.0.30001612", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", + "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chai": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", + "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.15", - "@types/semver": "^7.5.8", - "@typescript-eslint/scope-manager": "7.7.1", - "@typescript-eslint/types": "7.7.1", - "@typescript-eslint/typescript-estree": "7.7.1", - "semver": "^7.6.0" + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" + "node": ">=12" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.1.tgz", - "integrity": "sha512-gBL3Eq25uADw1LQ9kVpf3hRM+DWzs0uZknHYK3hq4jcTPqVCClHGDnB6UUUV2SFeBeA4KWHWbbLqmbGcZ4FYbw==", + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { - "@typescript-eslint/types": "7.7.1", - "eslint-visitor-keys": "^3.4.3" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" - }, - "node_modules/@vitejs/plugin-vue": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.6.2.tgz", - "integrity": "sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==", + "node_modules/chalk-template": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-1.1.0.tgz", + "integrity": "sha512-T2VJbcDuZQ0Tb2EWwSotMPJjgpy1/tGee1BTpUNsGZ/qgNjV2t7Mvu+d4600U564nbLesN1x2dPL+xii174Ekg==", "dev": true, + "dependencies": { + "chalk": "^5.2.0" + }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": ">=14.16" }, - "peerDependencies": { - "vite": "^4.0.0 || ^5.0.0", - "vue": "^3.2.25" + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" } }, - "node_modules/@vitest/expect": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.6.tgz", - "integrity": "sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==", + "node_modules/chalk-template/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, - "dependencies": { - "@vitest/spy": "0.34.6", - "@vitest/utils": "0.34.6", - "chai": "^4.3.10" + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@vitest/pretty-format": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz", - "integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==", - "dependencies": { - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "engines": { + "node": ">= 16" } }, - "node_modules/@vitest/runner": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.6.tgz", - "integrity": "sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==", - "dev": true, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dependencies": { - "@vitest/utils": "0.34.6", - "p-limit": "^4.0.0", - "pathe": "^1.1.1" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/@vitest/runner/node_modules/p-limit": { + "node_modules/cli-cursor": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", "dev": true, "dependencies": { - "yocto-queue": "^1.0.0" + "restore-cursor": "^4.0.0" }, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" @@ -3052,596 +3477,565 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@vitest/runner/node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "dev": true, "engines": { - "node": ">=12.20" + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@vitest/snapshot": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.6.tgz", - "integrity": "sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==", - "dev": true, - "dependencies": { - "magic-string": "^0.30.1", - "pathe": "^1.1.1", - "pretty-format": "^29.5.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/spy": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.6.tgz", - "integrity": "sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==", + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, - "dependencies": { - "tinyspy": "^2.1.1" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">= 12" } }, - "node_modules/@vitest/utils": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.6.tgz", - "integrity": "sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==", + "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==", "dev": true, "dependencies": { - "diff-sequences": "^29.4.3", - "loupe": "^2.3.6", - "pretty-format": "^29.5.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=12" } }, - "node_modules/@volar/language-core": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.11.1.tgz", - "integrity": "sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==", + "node_modules/cliui/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==", "dev": true, - "dependencies": { - "@volar/source-map": "1.11.1" + "engines": { + "node": ">=8" } }, - "node_modules/@volar/source-map": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.11.1.tgz", - "integrity": "sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==", - "dev": true, - "dependencies": { - "muggle-string": "^0.3.1" - } + "node_modules/cliui/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==", + "dev": true }, - "node_modules/@volar/typescript": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.11.1.tgz", - "integrity": "sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==", + "node_modules/cliui/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==", "dev": true, "dependencies": { - "@volar/language-core": "1.11.1", - "path-browserify": "^1.0.1" - } - }, - "node_modules/@vue/compiler-core": { - "version": "3.4.25", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.25.tgz", - "integrity": "sha512-Y2pLLopaElgWnMNolgG8w3C5nNUVev80L7hdQ5iIKPtMJvhVpG0zhnBG/g3UajJmZdvW0fktyZTotEHD1Srhbg==", - "dependencies": { - "@babel/parser": "^7.24.4", - "@vue/shared": "3.4.25", - "entities": "^4.5.0", - "estree-walker": "^2.0.2", - "source-map-js": "^1.2.0" - } - }, - "node_modules/@vue/compiler-dom": { - "version": "3.4.25", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.25.tgz", - "integrity": "sha512-Ugz5DusW57+HjllAugLci19NsDK+VyjGvmbB2TXaTcSlQxwL++2PETHx/+Qv6qFwNLzSt7HKepPe4DcTE3pBWg==", - "dependencies": { - "@vue/compiler-core": "3.4.25", - "@vue/shared": "3.4.25" - } - }, - "node_modules/@vue/compiler-sfc": { - "version": "3.4.25", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.25.tgz", - "integrity": "sha512-m7rryuqzIoQpOBZ18wKyq05IwL6qEpZxFZfRxlNYuIPDqywrXQxgUwLXIvoU72gs6cRdY6wHD0WVZIFE4OEaAQ==", - "dependencies": { - "@babel/parser": "^7.24.4", - "@vue/compiler-core": "3.4.25", - "@vue/compiler-dom": "3.4.25", - "@vue/compiler-ssr": "3.4.25", - "@vue/shared": "3.4.25", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.10", - "postcss": "^8.4.38", - "source-map-js": "^1.2.0" - } - }, - "node_modules/@vue/compiler-ssr": { - "version": "3.4.25", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.25.tgz", - "integrity": "sha512-H2ohvM/Pf6LelGxDBnfbbXFPyM4NE3hrw0e/EpwuSiYu8c819wx+SVGdJ65p/sFrYDd6OnSDxN1MB2mN07hRSQ==", - "dependencies": { - "@vue/compiler-dom": "3.4.25", - "@vue/shared": "3.4.25" - } - }, - "node_modules/@vue/devtools-api": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.1.tgz", - "integrity": "sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==" - }, - "node_modules/@vue/eslint-config-typescript": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-13.0.0.tgz", - "integrity": "sha512-MHh9SncG/sfqjVqjcuFLOLD6Ed4dRAis4HNt0dXASeAuLqIAx4YMB1/m2o4pUKK1vCt8fUvYG8KKX2Ot3BVZTg==", - "dependencies": { - "@typescript-eslint/eslint-plugin": "^7.1.1", - "@typescript-eslint/parser": "^7.1.1", - "vue-eslint-parser": "^9.3.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "peerDependencies": { - "eslint": "^8.56.0", - "eslint-plugin-vue": "^9.0.0", - "typescript": ">=4.7.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@vue/language-core": { - "version": "1.8.27", - "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.27.tgz", - "integrity": "sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==", - "dev": true, - "dependencies": { - "@volar/language-core": "~1.11.1", - "@volar/source-map": "~1.11.1", - "@vue/compiler-dom": "^3.3.0", - "@vue/shared": "^3.3.0", - "computeds": "^0.0.1", - "minimatch": "^9.0.3", - "muggle-string": "^0.3.1", - "path-browserify": "^1.0.1", - "vue-template-compiler": "^2.7.14" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=8" } }, - "node_modules/@vue/language-core/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "node_modules/cliui/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==", "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@vue/reactivity": { - "version": "3.4.25", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.25.tgz", - "integrity": "sha512-mKbEtKr1iTxZkAG3vm3BtKHAOhuI4zzsVcN0epDldU/THsrvfXRKzq+lZnjczZGnTdh3ojd86/WrP+u9M51pWQ==", - "dependencies": { - "@vue/shared": "3.4.25" - } - }, - "node_modules/@vue/runtime-core": { - "version": "3.4.25", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.25.tgz", - "integrity": "sha512-3qhsTqbEh8BMH3pXf009epCI5E7bKu28fJLi9O6W+ZGt/6xgSfMuGPqa5HRbUxLoehTNp5uWvzCr60KuiRIL0Q==", - "dependencies": { - "@vue/reactivity": "3.4.25", - "@vue/shared": "3.4.25" + "node": ">=8" } }, - "node_modules/@vue/runtime-dom": { - "version": "3.4.25", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.25.tgz", - "integrity": "sha512-ode0sj77kuwXwSc+2Yhk8JMHZh1sZp9F/51wdBiz3KGaWltbKtdihlJFhQG4H6AY+A06zzeMLkq6qu8uDSsaoA==", + "node_modules/cliui/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==", + "dev": true, "dependencies": { - "@vue/runtime-core": "3.4.25", - "@vue/shared": "3.4.25", - "csstype": "^3.1.3" + "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/@vue/server-renderer": { - "version": "3.4.25", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.25.tgz", - "integrity": "sha512-8VTwq0Zcu3K4dWV0jOwIVINESE/gha3ifYCOKEhxOj6MEl5K5y8J8clQncTcDhKF+9U765nRw4UdUEXvrGhyVQ==", + "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==", "dependencies": { - "@vue/compiler-ssr": "3.4.25", - "@vue/shared": "3.4.25" + "color-name": "~1.1.4" }, - "peerDependencies": { - "vue": "3.4.25" + "engines": { + "node": ">=7.0.0" } }, - "node_modules/@vue/shared": { - "version": "3.4.25", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.25.tgz", - "integrity": "sha512-k0yappJ77g2+KNrIaF0FFnzwLvUBLUYr8VOwz+/6vLsmItFp51AcxLL7Ey3iPd7BIRyWPOcqUjMnm7OkahXllA==" + "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==" }, - "node_modules/@vue/test-utils": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-2.4.5.tgz", - "integrity": "sha512-oo2u7vktOyKUked36R93NB7mg2B+N7Plr8lxp2JBGwr18ch6EggFjixSCdIVVLkT6Qr0z359Xvnafc9dcKyDUg==", + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "dev": true, - "dependencies": { - "js-beautify": "^1.14.9", - "vue-component-type-helpers": "^2.0.0" + "engines": { + "node": ">=14" } }, - "node_modules/@vue/tsconfig": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@vue/tsconfig/-/tsconfig-0.4.0.tgz", - "integrity": "sha512-CPuIReonid9+zOG/CGTT05FXrPYATEqoDGNrEaqS4hwcw5BUNM2FguC0mOwJD4Jr16UpRVl9N0pY3P+srIbqmg==", + "node_modules/computeds": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz", + "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==", "dev": true }, - "node_modules/@vuepic/vue-datepicker": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/@vuepic/vue-datepicker/-/vue-datepicker-8.4.0.tgz", - "integrity": "sha512-Twgvqwd5GrQf3JT2DvAQ/Ku0+sM51zsH1OkQKoRwYqJyF+EugItS8I0CveYmcI3Gbu92RZ9C3DMutvkaiuDzAQ==", + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/confbox": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", + "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==" + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, "dependencies": { - "date-fns": "^3.6.0" - }, - "engines": { - "node": ">=18.12.0" - }, - "peerDependencies": { - "vue": ">=3.2.0" + "ini": "^1.3.4", + "proto-list": "~1.2.1" } }, - "node_modules/@vueuse/core": { - "version": "10.9.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.9.0.tgz", - "integrity": "sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==", - "dependencies": { - "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "10.9.0", - "@vueuse/shared": "10.9.0", - "vue-demi": ">=0.14.7" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" } }, - "node_modules/@vueuse/core/node_modules/vue-demi": { - "version": "0.14.7", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", - "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" }, "engines": { - "node": ">=12" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/antfu" + "url": "https://github.com/sponsors/d-fischer" }, "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" + "typescript": ">=4.9.5" }, "peerDependenciesMeta": { - "@vue/composition-api": { + "typescript": { "optional": true } } }, - "node_modules/@vueuse/metadata": { - "version": "10.9.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.9.0.tgz", - "integrity": "sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==", - "funding": { - "url": "https://github.com/sponsors/antfu" + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/@vueuse/router": { - "version": "10.9.0", - "resolved": "https://registry.npmjs.org/@vueuse/router/-/router-10.9.0.tgz", - "integrity": "sha512-MOmrCMQlRuPS4PExE1hy8T0XbZUXaNbEuh7CAG5mC8kdvdgANQMkdvJ7vIEOP27n5mXK/4YjvXJOZSsur4E0QQ==", + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "peer": true, "dependencies": { - "@vueuse/shared": "10.9.0", - "vue-demi": ">=0.14.7" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, - "funding": { - "url": "https://github.com/sponsors/antfu" + "engines": { + "node": ">= 0.4" }, - "peerDependencies": { - "vue-router": ">=4.0.0-rc.1" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@vueuse/router/node_modules/vue-demi": { - "version": "0.14.7", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", - "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/antfu" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" + "engines": { + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" } }, - "node_modules/@vueuse/shared": { - "version": "10.9.0", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.9.0.tgz", - "integrity": "sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==", + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "dependencies": { - "vue-demi": ">=0.14.7" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/shared/node_modules/vue-demi": { - "version": "0.14.7", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", - "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" + "ms": "2.1.2" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" + "node": ">=6.0" }, "peerDependenciesMeta": { - "@vue/composition-api": { + "supports-color": { "optional": true } } }, - "node_modules/abbrev": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", - "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", - "dev": true, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=6" } }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "bin": { - "acorn": "bin/acorn" + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "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==", + "peer": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "dev": true, "engines": { - "node": ">=0.4.0" + "node": ">=8" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "peer": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, "engines": { - "node": ">=6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dependencies": { - "type-fest": "^0.21.3" + "path-type": "^4.0.0" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, + "node_modules/dir-glob/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true }, - "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==", + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dependencies": { - "color-convert": "^2.0.1" + "esutils": "^2.0.2" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=6.0.0" } }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "node_modules/editorconfig": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", + "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", + "dev": true, "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "@one-ini/wasm": "0.1.1", + "commander": "^10.0.0", + "minimatch": "9.0.1", + "semver": "^7.5.3" + }, + "bin": { + "editorconfig": "bin/editorconfig" }, "engines": { - "node": ">= 8" + "node": ">=14" } }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "node_modules/effect": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/effect/-/effect-3.0.3.tgz", + "integrity": "sha512-mgG+FoWrM4sny8OxDFWCpq+6LwGf9cK/JztVhxZQeZM9ZMXY+lKbdMEQmemNYce0QVAz2+YqUKwhKzOidwbZzg==", "dev": true }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "node_modules/electron-to-chromium": { + "version": "1.4.748", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.748.tgz", + "integrity": "sha512-VWqjOlPZn70UZ8FTKUOkUvBLeTQ0xpty66qV0yJcAGY2/CthI4xyW9aEozRVtuwv3Kpf5xTesmJUcPwuJmgP4A==", + "dev": true }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "peer": true, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8.6" + } + }, + "node_modules/enquirer/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==", + "dev": true, + "engines": { + "node": ">=8" } }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "peer": true, + "node_modules/enquirer/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==", + "dev": true, "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=8" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "peer": true, "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -3650,1027 +4044,949 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "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==", "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", "peer": true, "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" + "es-errors": "^1.3.0" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" } }, - "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==", + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "peer": true, "dependencies": { - "possible-typed-array-names": "^1.0.0" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/balanced-match": { + "node_modules/es-shim-unscopables": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "peer": true, "dependencies": { - "balanced-match": "^1.0.0" + "hasown": "^2.0.0" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "peer": true, "dependencies": { - "fill-range": "^7.0.1" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, + "hasInstallScript": true, "bin": { - "browserslist": "cli.js" + "esbuild": "bin/esbuild" }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" } }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "peer": true, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, "engines": { "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/builtins": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", - "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==", + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dependencies": { - "semver": "^7.0.0" + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" } }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "peer": true, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" }, "engines": { - "node": ">= 0.4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/eslint-compat-utils": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz", + "integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==", + "peer": true, + "dependencies": { + "semver": "^7.5.4" + }, "engines": { - "node": ">=6" + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" } }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, - "engines": { - "node": ">= 6" + "node_modules/eslint-config-kwai": { + "resolved": "packages/eslint-config-kwai", + "link": true + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001612", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", - "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", - "dev": true, + "node_modules/eslint-config-standard": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", + "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", "funding": [ { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + "type": "github", + "url": "https://github.com/sponsors/feross" }, { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - }, + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "engines": { - "node": ">=4" + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": "^8.0.1", + "eslint-plugin-import": "^2.25.2", + "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", + "eslint-plugin-promise": "^6.0.0" } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "peer": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, - "node_modules/chalk-template": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-1.1.0.tgz", - "integrity": "sha512-T2VJbcDuZQ0Tb2EWwSotMPJjgpy1/tGee1BTpUNsGZ/qgNjV2t7Mvu+d4600U564nbLesN1x2dPL+xii174Ekg==", - "dev": true, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "peer": true, "dependencies": { - "chalk": "^5.2.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/chalk/chalk-template?sponsor=1" + "ms": "^2.1.1" } }, - "node_modules/chalk-template/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "peer": true, + "dependencies": { + "debug": "^3.2.7" + }, "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "node": ">=4" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "peer": true, "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" + "ms": "^2.1.1" } }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "node_modules/eslint-plugin-es-x": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.6.0.tgz", + "integrity": "sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==", + "peer": true, "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.6.0", + "eslint-compat-utils": "^0.5.0" }, "engines": { - "node": ">= 8.10.0" + "node": "^14.18.0 || >=16.0.0" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/ota-meshi" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "peerDependencies": { + "eslint": ">=8" } }, - "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", - "dev": true, + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "peer": true, "dependencies": { - "restore-cursor": "^4.0.0" + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=4" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, - "node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/cli-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", - "dev": true, - "engines": { - "node": ">= 12" + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "peer": true, + "dependencies": { + "ms": "^2.1.1" } }, - "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==", - "dev": true, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "peer": true, "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "esutils": "^2.0.2" }, "engines": { - "node": ">=12" - } - }, - "node_modules/cliui/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==", - "dev": true, - "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/cliui/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==", - "dev": true - }, - "node_modules/cliui/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==", - "dev": true, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "peer": true, "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/cliui/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==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "peer": true, + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/cliui/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==", - "dev": true, + "node_modules/eslint-plugin-n": { + "version": "16.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", + "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", + "peer": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "@eslint-community/eslint-utils": "^4.4.0", + "builtins": "^5.0.1", + "eslint-plugin-es-x": "^7.5.0", + "get-tsconfig": "^4.7.0", + "globals": "^13.24.0", + "ignore": "^5.2.4", + "is-builtin-module": "^3.2.1", + "is-core-module": "^2.12.1", + "minimatch": "^3.1.2", + "resolve": "^1.22.2", + "semver": "^7.5.3" }, "engines": { - "node": ">=10" + "node": ">=16.0.0" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "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==", - "dependencies": { - "color-name": "~1.1.4" + "url": "https://github.com/sponsors/mysticatea" }, - "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==" - }, - "node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true, - "engines": { - "node": ">=14" + "peerDependencies": { + "eslint": ">=7.0.0" } }, - "node_modules/computeds": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz", - "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/confbox": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", - "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==" - }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "dev": true, + "node_modules/eslint-plugin-n/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "peer": true, "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true, + "node_modules/eslint-plugin-n/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, "engines": { - "node": ">= 0.6" + "node": "*" } }, - "node_modules/cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", - "dev": true, + "node_modules/eslint-plugin-prettier": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", + "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", "dependencies": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.6" }, "engines": { - "node": ">=14" + "node": "^14.18.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/d-fischer" + "url": "https://opencollective.com/eslint-plugin-prettier" }, "peerDependencies": { - "typescript": ">=4.9.5" + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" }, "peerDependenciesMeta": { - "typescript": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { "optional": true } } }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, + "node_modules/eslint-plugin-promise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", + "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "peer": true, "engines": { - "node": ">= 8" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "bin": { - "cssesc": "bin/cssesc" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "peer": true, + "node_modules/eslint-plugin-vue": { + "version": "9.25.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.25.0.tgz", + "integrity": "sha512-tDWlx14bVe6Bs+Nnh3IGrD+hb11kf2nukfm6jLsmJIhmiRQ1SUaksvwY9U5MvPB0pcrg0QK0xapQkfITs3RKOA==", "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "@eslint-community/eslint-utils": "^4.4.0", + "globals": "^13.24.0", + "natural-compare": "^1.4.0", + "nth-check": "^2.1.1", + "postcss-selector-parser": "^6.0.15", + "semver": "^7.6.0", + "vue-eslint-parser": "^9.4.2", + "xml-name-validator": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": "^14.17.0 || >=16.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" } }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "peer": true, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">= 0.4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint" } }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "peer": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "engines": { - "node": ">= 0.4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint" } }, - "node_modules/date-fns": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", - "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/kossnocorp" + "node_modules/eslint/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==", + "engines": { + "node": ">=8" } }, - "node_modules/dayjs": { - "version": "1.11.10", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", - "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" - }, - "node_modules/de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", - "dev": true + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } }, - "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dependencies": { - "ms": "2.1.2" + "is-glob": "^4.0.3" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=10.13.0" } }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dependencies": { - "type-detect": "^4.0.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=6" + "node": "*" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + "node_modules/eslint/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==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } }, - "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==", - "peer": true, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": ">= 0.4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint" } }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "peer": true, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" + "estraverse": "^5.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=4.0" } }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=0.10.0" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dependencies": { - "path-type": "^4.0.0" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/dir-glob/node_modules/path-type": { + "node_modules/execa/node_modules/mimic-fn": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "node_modules/execa/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dependencies": { - "esutils": "^2.0.2" + "mimic-fn": "^4.0.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "node_modules/editorconfig": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", - "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", + "node_modules/fast-check": { + "version": "3.17.2", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.17.2.tgz", + "integrity": "sha512-+3DPTxtxABLgmmVpYxrash3DHoq0cMa1jjLYNp3qqokKKhqVEaS4lbnaDKqWU5Dd6C2pEudPPBAEEQ9nUou9OQ==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], "dependencies": { - "@one-ini/wasm": "0.1.1", - "commander": "^10.0.0", - "minimatch": "9.0.1", - "semver": "^7.5.3" - }, - "bin": { - "editorconfig": "bin/editorconfig" + "pure-rand": "^6.1.0" }, "engines": { - "node": ">=14" + "node": ">=8.0.0" } }, - "node_modules/effect": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/effect/-/effect-3.0.3.tgz", - "integrity": "sha512-mgG+FoWrM4sny8OxDFWCpq+6LwGf9cK/JztVhxZQeZM9ZMXY+lKbdMEQmemNYce0QVAz2+YqUKwhKzOidwbZzg==", - "dev": true - }, - "node_modules/electron-to-chromium": { - "version": "1.4.748", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.748.tgz", - "integrity": "sha512-VWqjOlPZn70UZ8FTKUOkUvBLeTQ0xpty66qV0yJcAGY2/CthI4xyW9aEozRVtuwv3Kpf5xTesmJUcPwuJmgP4A==", - "dev": true + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==" }, - "node_modules/enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "dev": true, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" }, "engines": { - "node": ">=8.6" + "node": ">=8.6.0" } }, - "node_modules/enquirer/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==", - "dev": true, - "engines": { - "node": ">=8" + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "^1.0.4" } }, - "node_modules/enquirer/node_modules/strip-ansi": { + "node_modules/file-entry-cache": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dependencies": { - "ansi-regex": "^5.0.1" + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, "engines": { - "node": ">=0.12" + "node": ">=10" }, "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, "engines": { - "node": ">=6" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==" }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "peer": true, "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "is-callable": "^1.1.3" } }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "peer": true, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, "dependencies": { - "get-intrinsic": "^1.2.4" + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "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==", - "peer": true, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, "engines": { - "node": ">= 0.4" + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" } }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "peer": true, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, "dependencies": { - "es-errors": "^1.3.0" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=6 <7 || >=8" } }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "peer": true, - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 0.4" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "peer": true, - "dependencies": { - "hasown": "^2.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==", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "peer": true, "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" }, "engines": { "node": ">= 0.4" @@ -4679,647 +4995,593 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "peer": true, + "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==", "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", "dev": true, "engines": { - "node": ">=6" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "engines": { - "node": ">=0.8.0" + "node": "*" } }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "peer": true, "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "engines": { - "node": ">=6.0" + "node": ">= 0.4" }, - "optionalDependencies": { - "source-map": "~0.6.1" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "engines": { - "node": ">=0.10.0" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "peer": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-compat-utils": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz", - "integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==", + "node_modules/get-tsconfig": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", + "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", "peer": true, "dependencies": { - "semver": "^7.5.4" + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=12" + "node": ">=16 || 14 >=14.17" }, - "peerDependencies": { - "eslint": ">=6.0.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/eslint-config-kwai": { - "resolved": "packages/eslint-config-kwai", - "link": true + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } }, - "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", - "bin": { - "eslint-config-prettier": "bin/cli.js" + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dependencies": { + "type-fest": "^0.20.2" }, - "peerDependencies": { - "eslint": ">=7.0.0" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-config-standard": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", - "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "engines": { - "node": ">=12.0.0" + "node": ">=10" }, - "peerDependencies": { - "eslint": "^8.0.1", - "eslint-plugin-import": "^2.25.2", - "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", - "eslint-plugin-promise": "^6.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "peer": true, "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "peer": true, + "node_modules/globby": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.1.tgz", + "integrity": "sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==", + "dev": true, "dependencies": { - "ms": "^2.1.1" + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "peer": true, "dependencies": { - "debug": "^3.2.7" + "get-intrinsic": "^1.1.3" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" + }, + "node_modules/graphql": { + "version": "16.8.1", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz", + "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==", + "dev": true, "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "peer": true, - "dependencies": { - "ms": "^2.1.1" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-es-x": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.6.0.tgz", - "integrity": "sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.6.0", - "eslint-compat-utils": "^0.5.0" - }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, - "peerDependencies": { - "eslint": ">=8" + "node": ">=8" } }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "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==", "peer": true, "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" + "es-define-property": "^1.0.0" }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "peer": true, - "dependencies": { - "ms": "^2.1.1" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "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==", "peer": true, "dependencies": { - "esutils": "^2.0.2" + "has-symbols": "^1.0.3" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "peer": true, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dependencies": { - "brace-expansion": "^1.1.7" + "function-bind": "^1.1.2" }, "engines": { - "node": "*" + "node": ">= 0.4" } }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "peer": true, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, "bin": { - "semver": "bin/semver.js" + "he": "bin/he" } }, - "node_modules/eslint-plugin-n": { - "version": "16.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", - "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", - "peer": true, + "node_modules/headers-polyfill": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.3.tgz", + "integrity": "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==", + "dev": true + }, + "node_modules/hosted-git-info": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz", + "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==", + "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "builtins": "^5.0.1", - "eslint-plugin-es-x": "^7.5.0", - "get-tsconfig": "^4.7.0", - "globals": "^13.24.0", - "ignore": "^5.2.4", - "is-builtin-module": "^3.2.1", - "is-core-module": "^2.12.1", - "minimatch": "^3.1.2", - "resolve": "^1.22.2", - "semver": "^7.5.3" + "lru-cache": "^10.0.1" }, "engines": { - "node": ">=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=7.0.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/eslint-plugin-n/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "engines": { + "node": ">=16.17.0" } }, - "node_modules/eslint-plugin-n/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "engines": { - "node": "*" + "node": ">= 4" } }, - "node_modules/eslint-plugin-prettier": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", - "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.6" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": ">=6" }, "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": "*", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-plugin-promise": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", - "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", - "peer": true, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "node": ">=8" } }, - "node_modules/eslint-plugin-vue": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.25.0.tgz", - "integrity": "sha512-tDWlx14bVe6Bs+Nnh3IGrD+hb11kf2nukfm6jLsmJIhmiRQ1SUaksvwY9U5MvPB0pcrg0QK0xapQkfITs3RKOA==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "globals": "^13.24.0", - "natural-compare": "^1.4.0", - "nth-check": "^2.1.1", - "postcss-selector-parser": "^6.0.15", - "semver": "^7.6.0", - "vue-eslint-parser": "^9.4.2", - "xml-name-validator": "^4.0.0" + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" }, "engines": { - "node": "^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" + "node": ">= 0.4" } }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "peer": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "peer": true, + "dependencies": { + "has-bigints": "^1.0.1" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint/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==", + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "peer": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "peer": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, "engines": { - "node": ">=10" + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dependencies": { - "is-glob": "^4.0.3" - }, + "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==", + "peer": true, "engines": { - "node": ">=10.13.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dependencies": { - "brace-expansion": "^1.1.7" + "hasown": "^2.0.0" }, - "engines": { - "node": "*" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint/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==", + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "peer": true, "dependencies": { - "ansi-regex": "^5.0.1" + "is-typed-array": "^1.1.13" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "peer": true, "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dependencies": { - "estraverse": "^5.1.0" + "is-docker": "cli.js" }, "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dependencies": { - "estraverse": "^5.2.0" + "node": ">=8" }, - "engines": { - "node": ">=4.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { - "node": ">=4.0" + "node": ">=0.10.0" } }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "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==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "node": ">=0.10.0" } }, - "node_modules/execa/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true, "engines": { "node": ">=12" }, @@ -5327,835 +5589,827 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/execa/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dependencies": { - "mimic-fn": "^4.0.0" - }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "peer": true, "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fast-check": { - "version": "3.17.2", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.17.2.tgz", - "integrity": "sha512-+3DPTxtxABLgmmVpYxrash3DHoq0cMa1jjLYNp3qqokKKhqVEaS4lbnaDKqWU5Dd6C2pEudPPBAEEQ9nUou9OQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "dependencies": { - "pure-rand": "^6.1.0" - }, + "node_modules/is-node-process": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", + "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", + "dev": true + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "engines": { - "node": ">=8.0.0" + "node": ">=0.12.0" } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "peer": true, "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=8.6.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dependencies": { - "reusify": "^1.0.4" + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" } }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "peer": true, "dependencies": { - "flat-cache": "^3.0.4" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "peer": true, "dependencies": { - "to-regex-range": "^5.0.1" + "call-bind": "^1.0.7" }, "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "peer": true, "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==" - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "peer": true, "dependencies": { - "is-callable": "^1.1.3" + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "peer": true, "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" + "which-typed-array": "^1.1.14" }, "engines": { - "node": ">=14" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "node_modules/is-unicode-supported": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz", + "integrity": "sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==", "dev": true, "engines": { - "node": "*" + "node": ">=18" }, "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "peer": true, "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "call-bind": "^1.0.2" }, - "engines": { - "node": ">=6 <7 || >=8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=8" } }, - "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==", - "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==", + "peer": true }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "peer": true, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "@isaacs/cliui": "^8.0.2" }, "engines": { - "node": ">= 0.4" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" } }, - "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==", + "node_modules/jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", + "dev": true + }, + "node_modules/js-beautify": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.1.tgz", + "integrity": "sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==", "dev": true, + "dependencies": { + "config-chain": "^1.1.13", + "editorconfig": "^1.0.4", + "glob": "^10.3.3", + "js-cookie": "^3.0.5", + "nopt": "^7.2.0" + }, + "bin": { + "css-beautify": "js/bin/css-beautify.js", + "html-beautify": "js/bin/html-beautify.js", + "js-beautify": "js/bin/js-beautify.js" + }, "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=14" } }, - "node_modules/get-east-asian-width": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", - "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "node_modules/js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", "dev": true, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=14" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "engines": { - "node": "*" + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "peer": true, + "node_modules/jsonc-eslint-parser": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.0.tgz", + "integrity": "sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==", "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" + "acorn": "^8.5.0", + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0", + "semver": "^7.3.5" }, "engines": { - "node": ">= 0.4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/ota-meshi" } }, - "node_modules/get-tsconfig": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", - "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", - "peer": true, - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/glob": { - "version": "10.3.12", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", - "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", - "dev": true, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.6", - "minimatch": "^9.0.1", - "minipass": "^7.0.4", - "path-scurry": "^1.10.2" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "json-buffer": "3.0.1" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, "engines": { - "node": ">= 6" + "node": ">=6" } }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "dev": true + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dependencies": { - "type-fest": "^0.20.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.8.0" } }, - "node_modules/globals/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "peer": true, - "dependencies": { - "define-properties": "^1.1.3" - }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/local-pkg": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", + "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", + "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/globby": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.1.tgz", - "integrity": "sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==", - "dev": true, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dependencies": { - "@sindresorhus/merge-streams": "^2.1.0", - "fast-glob": "^3.3.2", - "ignore": "^5.2.4", - "path-type": "^5.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.1.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "peer": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" - }, - "node_modules/graphql": { - "version": "16.8.1", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz", - "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "dev": true }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, - "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==", - "peer": true, + "node_modules/log-symbols": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", + "dev": true, "dependencies": { - "es-define-property": "^1.0.0" + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "peer": true, "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "peer": true, + "node_modules/log-symbols/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, "engines": { - "node": ">= 0.4" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "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==", - "peer": true, - "dependencies": { - "has-symbols": "^1.0.3" - }, + "node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "node_modules/loupe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", + "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" + "get-func-name": "^2.0.1" } }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", "dev": true, - "bin": { - "he": "bin/he" + "engines": { + "node": "14 || >=16.14" } }, - "node_modules/headers-polyfill": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.3.tgz", - "integrity": "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==", - "dev": true + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } }, - "node_modules/hosted-git-info": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz", - "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==", - "dev": true, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dependencies": { - "lru-cache": "^10.0.1" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": ">=8.6" } }, - "node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, "engines": { - "node": ">=16.17.0" + "node": ">=6" } }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "engines": { - "node": ">= 4" + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "dev": true, + "bin": { + "mini-svg-data-uri": "cli.js" } }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "node_modules/minimatch": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", + "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", + "dev": true, "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=6" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/import-lazy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", - "dev": true, - "engines": { - "node": ">=8" + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, "engines": { - "node": ">=0.8.19" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "node_modules/mlly": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", + "integrity": "sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==", "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.0.3", + "ufo": "^1.3.2" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "peer": true, + "node_modules/msw": { + "version": "2.2.14", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.2.14.tgz", + "integrity": "sha512-64i8rNCa1xzDK8ZYsTrVMli05D687jty8+Th+PU5VTbJ2/4P7fkQFVyDQ6ZFT5FrNR8z2BHhbY47fKNvfHrumA==", + "dev": true, + "hasInstallScript": true, "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "@bundled-es-modules/cookie": "^2.0.0", + "@bundled-es-modules/statuses": "^1.0.1", + "@inquirer/confirm": "^3.0.0", + "@mswjs/cookies": "^1.1.0", + "@mswjs/interceptors": "^0.26.14", + "@open-draft/until": "^2.1.0", + "@types/cookie": "^0.6.0", + "@types/statuses": "^2.0.4", + "chalk": "^4.1.2", + "graphql": "^16.8.1", + "headers-polyfill": "^4.0.2", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.2", + "path-to-regexp": "^6.2.0", + "strict-event-emitter": "^0.5.1", + "type-fest": "^4.9.0", + "yargs": "^17.7.2" }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" + "bin": { + "msw": "cli/index.js" }, "engines": { - "node": ">= 0.4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mswjs" + }, + "peerDependencies": { + "typescript": ">= 4.7.x" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "node_modules/muggle-string": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.3.1.tgz", + "integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==", "dev": true }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "peer": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "peer": true, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/nopt": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.0.tgz", + "integrity": "sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==", + "dev": true, "dependencies": { - "builtin-modules": "^3.3.0" + "abbrev": "^2.0.0" }, - "engines": { - "node": ">=6" + "bin": { + "nopt": "bin/nopt.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "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==", - "peer": true, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "peer": true, + "node_modules/npm-package-arg": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.2.tgz", + "integrity": "sha512-IGN0IAwmhDJwy13Wc8k+4PEbTPhpJnMtfR53ZbOyjkvmEcLS4nCwp6mvMWjS5sUjeiW3mpx6cHmuhKEu9XmcQw==", + "dev": true, "dependencies": { - "is-typed-array": "^1.1.13" + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "peer": true, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dependencies": { - "has-tostringtag": "^1.0.0" + "path-key": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-extglob": { + "node_modules/nth-check": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "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==", + "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/is-fullwidth-code-point": { + "node_modules/object-hash": { "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==", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", "dev": true, "engines": { - "node": ">=8" + "node": ">= 6" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "dev": true, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -6163,27 +6417,29 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-node-process": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", - "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", - "dev": true - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, "engines": { - "node": ">=0.12.0" + "node": ">= 0.4" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "peer": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -6192,817 +6448,1033 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "engines": { - "node": ">=8" + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" } }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "peer": true, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "mimic-fn": "^2.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "peer": true, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, "dependencies": { - "call-bind": "^1.0.7" + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" }, "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.0.1.tgz", + "integrity": "sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ==", + "dev": true, + "dependencies": { + "chalk": "^5.3.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "peer": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, + "node_modules/ora/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, "engines": { - "node": ">= 0.4" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "peer": true, + "node_modules/ora/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/ora/node_modules/string-width": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", + "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "peer": true, + "node_modules/outvariant": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.2.tgz", + "integrity": "sha512-Ou3dJ6bA/UJ5GVHxah4LnqDwZRwAmWxrG3wtrHrbGnP4RnLCtA64A4F+ae7Y8ww660JaddSoArUR5HjipWSHAQ==", + "dev": true + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dependencies": { - "which-typed-array": "^1.1.14" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-unicode-supported": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz", - "integrity": "sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==", - "dev": true, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "peer": true, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dependencies": { - "call-bind": "^1.0.2" + "callsites": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=6" } }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { - "is-docker": "^2.0.0" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "peer": true + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "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==" }, - "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "node_modules/path-scurry": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", "dev": true, "dependencies": { - "@isaacs/cliui": "^8.0.2" + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=14" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", - "dev": true, - "bin": { - "jiti": "bin/jiti.js" } }, - "node_modules/jju": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", - "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", + "node_modules/path-to-regexp": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", + "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", "dev": true }, - "node_modules/js-beautify": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.1.tgz", - "integrity": "sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==", + "node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true, - "dependencies": { - "config-chain": "^1.1.13", - "editorconfig": "^1.0.4", - "glob": "^10.3.3", - "js-cookie": "^3.0.5", - "nopt": "^7.2.0" - }, - "bin": { - "css-beautify": "js/bin/css-beautify.js", - "html-beautify": "js/bin/html-beautify.js", - "js-beautify": "js/bin/js-beautify.js" - }, "engines": { - "node": ">=14" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/js-cookie": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", - "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", - "dev": true, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==" + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", "engines": { - "node": ">=14" + "node": ">= 14.16" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "node_modules/picocolors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/jsonc-eslint-parser": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.0.tgz", - "integrity": "sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==", + "node_modules/pinia": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz", + "integrity": "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==", "dependencies": { - "acorn": "^8.5.0", - "eslint-visitor-keys": "^3.0.0", - "espree": "^9.0.0", - "semver": "^7.3.5" + "@vue/devtools-api": "^6.5.0", + "vue-demi": ">=0.14.5" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "@vue/composition-api": "^1.4.0", + "typescript": ">=4.4.4", + "vue": "^2.6.14 || ^3.3.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/pinia/node_modules/vue-demi": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ota-meshi" + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } } }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "engines": { + "node": ">= 6" } }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "node_modules/pkg-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.0.tgz", + "integrity": "sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==", + "dependencies": { + "confbox": "^0.1.7", + "mlly": "^1.6.1", + "pathe": "^1.1.2" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.45", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz", + "integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "json-buffer": "3.0.1" + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" } }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", "dev": true, + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, "engines": { - "node": ">=6" + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" } }, - "node_modules/kolorist": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", - "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", - "dev": true - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "camelcase-css": "^2.0.1" }, "engines": { - "node": ">= 0.8.0" + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" } }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, "engines": { - "node": ">=10" + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/local-pkg": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", - "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", + "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", "dev": true, "engines": { "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/antfu" + "url": "https://github.com/sponsors/antonk52" } }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dev": true, "dependencies": { - "p-locate": "^5.0.0" + "postcss-selector-parser": "^6.0.11" }, "engines": { - "node": ">=10" + "node": ">=12.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, - "node_modules/lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" - }, - "node_modules/log-symbols": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", - "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", - "dev": true, + "node_modules/postcss-selector-parser": { + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", + "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", "dependencies": { - "chalk": "^5.3.0", - "is-unicode-supported": "^1.3.0" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">= 0.8.0" } }, - "node_modules/log-symbols/node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "dev": true, + "node_modules/prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "peer": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, "engines": { - "node": ">=12" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dependencies": { - "get-func-name": "^2.0.1" - } - }, - "node_modules/lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", - "dev": true, + "fast-diff": "^1.1.2" + }, "engines": { - "node": "14 || >=16.14" + "node": ">=6.0.0" } }, - "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, "engines": { - "node": ">= 8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/micromatch": { + "node_modules/primevue": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "resolved": "https://registry.npmjs.org/primevue/-/primevue-4.0.5.tgz", + "integrity": "sha512-MALszGIZ5SnEQy1XeZLBFhpMXQ1OS7D1U7H+l/JAX5U46RQ1vufo7NAiWbbV5/ADjPGw4uLplqMQxujkksNY2g==", "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" + "@primeuix/styled": "^0.0.5", + "@primeuix/utils": "^0.0.5", + "@primevue/core": "4.0.5", + "@primevue/icons": "4.0.5" }, "engines": { - "node": ">=8.6" + "node": ">=12.11.0" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, "engines": { - "node": ">=6" - } - }, - "node_modules/mini-svg-data-uri": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", - "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", - "dev": true, - "bin": { - "mini-svg-data-uri": "cli.js" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/minimatch": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", - "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">= 6" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true }, - "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "dev": true, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mlly": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", - "integrity": "sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==", - "dependencies": { - "acorn": "^8.11.3", - "pathe": "^1.1.2", - "pkg-types": "^1.0.3", - "ufo": "^1.3.2" + "node": ">=6" } }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/msw": { - "version": "2.2.14", - "resolved": "https://registry.npmjs.org/msw/-/msw-2.2.14.tgz", - "integrity": "sha512-64i8rNCa1xzDK8ZYsTrVMli05D687jty8+Th+PU5VTbJ2/4P7fkQFVyDQ6ZFT5FrNR8z2BHhbY47fKNvfHrumA==", + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", "dev": true, - "hasInstallScript": true, - "dependencies": { - "@bundled-es-modules/cookie": "^2.0.0", - "@bundled-es-modules/statuses": "^1.0.1", - "@inquirer/confirm": "^3.0.0", - "@mswjs/cookies": "^1.1.0", - "@mswjs/interceptors": "^0.26.14", - "@open-draft/until": "^2.1.0", - "@types/cookie": "^0.6.0", - "@types/statuses": "^2.0.4", - "chalk": "^4.1.2", - "graphql": "^16.8.1", - "headers-polyfill": "^4.0.2", - "is-node-process": "^1.2.0", - "outvariant": "^1.4.2", - "path-to-regexp": "^6.2.0", - "strict-event-emitter": "^0.5.1", - "type-fest": "^4.9.0", - "yargs": "^17.7.2" - }, - "bin": { - "msw": "cli/index.js" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/mswjs" - }, - "peerDependencies": { - "typescript": ">= 4.7.x" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" } - } + ] }, - "node_modules/muggle-string": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.3.1.tgz", - "integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==", + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true }, - "node_modules/mute-stream": { + "node_modules/read-cache": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", - "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "dependencies": { + "pify": "^2.3.0" } }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "node_modules/read-yaml-file": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-2.1.0.tgz", + "integrity": "sha512-UkRNRIwnhG+y7hpqnycCL/xbTk7+ia9VuVTC0S+zVbwd65DI9eUpRMfsWIGrCWxTU/mi+JW8cHQCrv+zfCbEPQ==", "dev": true, "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" + "js-yaml": "^4.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=10.13" } }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">=8.10.0" } }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "node_modules/remove-accents": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz", + "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==" }, - "node_modules/nopt": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.0.tgz", - "integrity": "sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==", + "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==", "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dependencies": { - "abbrev": "^2.0.0" + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { - "nopt": "bin/nopt.js" + "resolve": "bin/resolve" }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "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==", + "peer": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "node_modules/npm-package-arg": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.2.tgz", - "integrity": "sha512-IGN0IAwmhDJwy13Wc8k+4PEbTPhpJnMtfR53ZbOyjkvmEcLS4nCwp6mvMWjS5sUjeiW3mpx6cHmuhKEu9XmcQw==", + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", "dev": true, "dependencies": { - "hosted-git-info": "^7.0.0", - "proc-log": "^4.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dependencies": { - "path-key": "^4.0.0" + "glob": "^7.1.3" }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "bin": { + "rimraf": "bin.js" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, "engines": { - "node": ">=12" + "node": "*" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dependencies": { - "boolbase": "^1.0.0" + "brace-expansion": "^1.1.7" }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" + "engines": { + "node": "*" } }, - "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==", - "dev": true, + "node_modules/rollup": { + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "devOptional": true, + "bin": { + "rollup": "dist/bin/rollup" + }, "engines": { - "node": ">=0.10.0" + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "node_modules/rollup-plugin-visualizer": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.12.0.tgz", + "integrity": "sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==", "dev": true, + "dependencies": { + "open": "^8.4.0", + "picomatch": "^2.3.1", + "source-map": "^0.7.4", + "yargs": "^17.5.1" + }, + "bin": { + "rollup-plugin-visualizer": "dist/bin/cli.js" + }, "engines": { - "node": ">= 6" + "node": ">=14" + }, + "peerDependencies": { + "rollup": "2.x || 3.x || 4.x" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "peer": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "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==", "peer": true, "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" + "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" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "peer": true, "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "peer": true, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=8" } }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "peer": true, "dependencies": { "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" }, "engines": { "node": ">= 0.4" @@ -7011,245 +7483,267 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, "engines": { - "node": ">=6" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true, - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, "engines": { - "node": ">=12" + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==" + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==" + }, + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "dev": true, + "engines": { + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, + "node_modules/strict-event-emitter": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", + "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==", + "dev": true + }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, "engines": { - "node": ">= 0.8.0" + "node": ">=0.6.19" } }, - "node_modules/ora": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-8.0.1.tgz", - "integrity": "sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ==", + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "dependencies": { - "chalk": "^5.3.0", - "cli-cursor": "^4.0.0", - "cli-spinners": "^2.9.2", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^2.0.0", - "log-symbols": "^6.0.0", - "stdin-discarder": "^0.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=18" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ora/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "node_modules/string-width-cjs": { + "name": "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==", "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "engines": { + "node": ">=8" } }, - "node_modules/ora/node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "node_modules/string-width-cjs/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/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==", "dev": true }, - "node_modules/ora/node_modules/string-width": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", - "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "node_modules/string-width-cjs/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==", "dev": true, "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/outvariant": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.2.tgz", - "integrity": "sha512-Ou3dJ6bA/UJ5GVHxah4LnqDwZRwAmWxrG3wtrHrbGnP4RnLCtA64A4F+ae7Y8ww660JaddSoArUR5HjipWSHAQ==", - "dev": true - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "peer": true, "dependencies": { - "yocto-queue": "^0.1.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "peer": true, "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "peer": true, "dependencies": { - "callsites": "^3.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, "engines": { "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/strip-ansi-cjs/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==", + "dev": true, "engines": { "node": ">=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==" - }, - "node_modules/path-scurry": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", - "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=8" } }, - "node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", - "dev": true - }, - "node_modules/path-type": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", - "dev": true, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "engines": { "node": ">=12" }, @@ -7257,458 +7751,509 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==" - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "engines": { - "node": ">=8.6" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "node_modules/strip-literal": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", + "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinia": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz", - "integrity": "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==", "dependencies": { - "@vue/devtools-api": "^6.5.0", - "vue-demi": ">=0.14.5" + "acorn": "^8.10.0" }, "funding": { - "url": "https://github.com/sponsors/posva" - }, - "peerDependencies": { - "@vue/composition-api": "^1.4.0", - "typescript": ">=4.4.4", - "vue": "^2.6.14 || ^3.3.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - }, - "typescript": { - "optional": true - } + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/pinia/node_modules/vue-demi": { - "version": "0.14.7", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", - "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } + "engines": { + "node": ">=16 || 14 >=14.17" } }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true, "engines": { "node": ">= 6" } }, - "node_modules/pkg-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.0.tgz", - "integrity": "sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==", + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { - "confbox": "^0.1.7", - "mlly": "^1.6.1", - "pathe": "^1.1.2" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/possible-typed-array-names": { + "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "peer": true, + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/postcss": { - "version": "8.4.45", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz", - "integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/synckit": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", + "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" } }, - "node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "node_modules/syncpack": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/syncpack/-/syncpack-12.3.2.tgz", + "integrity": "sha512-ePvaDfasxF8mwaPItN6urmABaH6FPT3/vJU+2DHt24j8EIKjgz6NCxXDx2bTXJXZ4QcEFwvoiu3EqaJsVrHvUg==", "dev": true, "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" + "@effect/schema": "0.66.5", + "chalk": "5.3.0", + "chalk-template": "1.1.0", + "commander": "12.0.0", + "cosmiconfig": "9.0.0", + "effect": "3.0.3", + "enquirer": "2.4.1", + "fast-check": "3.17.2", + "globby": "14.0.1", + "minimatch": "9.0.4", + "npm-package-arg": "11.0.2", + "ora": "8.0.1", + "prompts": "2.4.2", + "read-yaml-file": "2.1.0", + "semver": "7.6.0", + "tightrope": "0.2.0", + "ts-toolbelt": "9.6.0" + }, + "bin": { + "syncpack": "dist/bin.js", + "syncpack-fix-mismatches": "dist/bin-fix-mismatches/index.js", + "syncpack-format": "dist/bin-format/index.js", + "syncpack-lint": "dist/bin-lint/index.js", + "syncpack-lint-semver-ranges": "dist/bin-lint-semver-ranges/index.js", + "syncpack-list": "dist/bin-list/index.js", + "syncpack-list-mismatches": "dist/bin-list-mismatches/index.js", + "syncpack-prompt": "dist/bin-prompt/index.js", + "syncpack-set-semver-ranges": "dist/bin-set-semver-ranges/index.js", + "syncpack-update": "dist/bin-update/index.js" }, "engines": { - "node": ">=14.0.0" + "node": ">=16" + } + }, + "node_modules/syncpack/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, - "peerDependencies": { - "postcss": "^8.0.0" + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "node_modules/syncpack/node_modules/commander": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz", + "integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/syncpack/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "dependencies": { - "camelcase-css": "^2.0.1" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "^12 || ^14 || >= 16" + "node": ">=16 || 14 >=14.17" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.4.21" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/postcss-load-config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", - "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "node_modules/tailwindcss": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz", + "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "dependencies": { - "lilconfig": "^3.0.0", - "yaml": "^2.3.4" - }, - "engines": { - "node": ">= 14" + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.0", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" }, - "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } + "engines": { + "node": ">=14.0.0" } }, - "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", - "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", + "node_modules/tailwindcss/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, - "engines": { - "node": ">=14" + "dependencies": { + "is-glob": "^4.0.3" }, - "funding": { - "url": "https://github.com/sponsors/antonk52" + "engines": { + "node": ">=10.13.0" } }, - "node_modules/postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", "dev": true, "dependencies": { - "postcss-selector-parser": "^6.0.11" + "thenify": ">= 3.1.0 < 4" }, "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.2.14" + "node": ">=0.8" } }, - "node_modules/postcss-selector-parser": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", - "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, + "node_modules/tightrope": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/tightrope/-/tightrope-0.2.0.tgz", + "integrity": "sha512-Kw36UHxJEELq2VUqdaSGR2/8cAsPgMtvX8uGVU6Jk26O66PhXec0A5ZnRYs47btbtwPDpXXF66+Fo3vimCM9aQ==", + "dev": true, "engines": { - "node": ">=4" + "node": ">=16" } }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "node_modules/tinybench": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", + "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==" }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "node_modules/tinypool": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz", + "integrity": "sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==", "engines": { - "node": ">= 0.8.0" + "node": "^18.0.0 || >=20.0.0" } }, - "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", - "peer": true, - "bin": { - "prettier": "bin/prettier.cjs" - }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" + "node": ">=14.0.0" } }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dependencies": { - "fast-diff": "^1.1.2" - }, + "node_modules/tinyspy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz", + "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==", "engines": { - "node": ">=6.0.0" + "node": ">=14.0.0" } }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "is-number": "^7.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8.0" } }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "engines": { - "node": ">=10" + "node": ">=16" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/primevue": { - "version": "3.51.0", - "resolved": "https://registry.npmjs.org/primevue/-/primevue-3.51.0.tgz", - "integrity": "sha512-BdMveidLSr0fNJ5+mxuke8mMCHyiXwvfDP4iwPr6R98rl3E0Wcm1u4/RKVrL7o0Iq606SXyhPQL3LGyAfXngcA==", "peerDependencies": { - "vue": "^3.0.0" + "typescript": ">=4.2.0" } }, - "node_modules/proc-log": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", - "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, + "node_modules/ts-toolbelt": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", + "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==", + "dev": true + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "peer": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" } }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "peer": true, "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" + "minimist": "^1.2.0" }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "peer": true, "engines": { - "node": ">= 6" + "node": ">=4" } }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "dev": true + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" + "node_modules/turbo": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/turbo/-/turbo-1.13.2.tgz", + "integrity": "sha512-rX/d9f4MgRT3yK6cERPAkfavIxbpBZowDQpgvkYwGMGDQ0Nvw1nc0NVjruE76GrzXQqoxR1UpnmEP54vBARFHQ==", + "dev": true, + "bin": { + "turbo": "bin/turbo" + }, + "optionalDependencies": { + "turbo-darwin-64": "1.13.2", + "turbo-darwin-arm64": "1.13.2", + "turbo-linux-64": "1.13.2", + "turbo-linux-arm64": "1.13.2", + "turbo-windows-64": "1.13.2", + "turbo-windows-arm64": "1.13.2" } }, - "node_modules/pure-rand": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", - "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "node_modules/turbo-darwin-64": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-1.13.2.tgz", + "integrity": "sha512-CCSuD8CfmtncpohCuIgq7eAzUas0IwSbHfI8/Q3vKObTdXyN8vAo01gwqXjDGpzG9bTEVedD0GmLbD23dR0MLA==", + "cpu": [ + "x64" + ], "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } + "optional": true, + "os": [ + "darwin" ] }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } + "node_modules/turbo-darwin-arm64": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-1.13.2.tgz", + "integrity": "sha512-0HySm06/D2N91rJJ89FbiI/AodmY8B3WDSFTVEpu2+8spUw7hOJ8okWOT0e5iGlyayUP9gr31eOeL3VFZkpfCw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/turbo-linux-64": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-1.13.2.tgz", + "integrity": "sha512-7HnibgbqZrjn4lcfIouzlPu8ZHSBtURG4c7Bedu7WJUDeZo+RE1crlrQm8wuwO54S0siYqUqo7GNHxu4IXbioQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" ] }, - "node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true + "node_modules/turbo-linux-arm64": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-1.13.2.tgz", + "integrity": "sha512-sUq4dbpk6SNKg/Hkwn256Vj2AEYSQdG96repio894h5/LEfauIK2QYiC/xxAeW3WBMc6BngmvNyURIg7ltrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "node_modules/turbo-windows-64": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-1.13.2.tgz", + "integrity": "sha512-DqzhcrciWq3dpzllJR2VVIyOhSlXYCo4mNEWl98DJ3FZ08PEzcI3ceudlH6F0t/nIcfSItK1bDP39cs7YoZHEA==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "pify": "^2.3.0" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/read-yaml-file": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-2.1.0.tgz", - "integrity": "sha512-UkRNRIwnhG+y7hpqnycCL/xbTk7+ia9VuVTC0S+zVbwd65DI9eUpRMfsWIGrCWxTU/mi+JW8cHQCrv+zfCbEPQ==", + "node_modules/turbo-windows-arm64": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-1.13.2.tgz", + "integrity": "sha512-WnPMrwfCXxK69CdDfS1/j2DlzcKxSmycgDAqV0XCYpK/812KB0KlvsVAt5PjEbZGXkY88pCJ1BLZHAjF5FcbqA==", + "cpu": [ + "arm64" + ], "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dependencies": { - "js-yaml": "^4.0.0", - "strip-bom": "^4.0.0" + "prelude-ls": "^1.2.1" }, "engines": { - "node": ">=10.13" + "node": ">= 0.8.0" } }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.17.0.tgz", + "integrity": "sha512-9flrz1zkfLRH3jO3bLflmTxryzKMxVa7841VeMgBaNQGY6vH4RCcpN/sQLB7mQQYh1GZ5utT2deypMuCy4yicw==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "peer": true, "dependencies": { - "picomatch": "^2.2.1" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" }, "engines": { - "node": ">=8.10.0" + "node": ">= 0.4" } }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "peer": true, "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -7717,1143 +8262,1442 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/remove-accents": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz", - "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==" - }, - "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==", - "dev": true, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "peer": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "peer": true, "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" }, - "bin": { - "resolve": "bin/resolve" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, "engines": { - "node": ">=4" + "node": ">=14.17" } }, - "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==", + "node_modules/ufo": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", + "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==" + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "devOptional": true + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "node_modules/unplugin": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.10.1.tgz", + "integrity": "sha512-d6Mhq8RJeGA8UfKCu54Um4lFA0eSaRa3XxdAJg8tIdxbu1ubW0hBCZUL7yI2uGyYCRndvbK8FLHzqy2XKfeMsg==", + "dependencies": { + "acorn": "^8.11.3", + "chokidar": "^3.6.0", + "webpack-sources": "^3.2.3", + "webpack-virtual-modules": "^0.6.1" + }, "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" + "node": ">=14.0.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "glob": "^7.1.3" + "escalade": "^3.1.1", + "picocolors": "^1.0.0" }, "bin": { - "rimraf": "bin.js" + "update-browserslist-db": "cli.js" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "punycode": "^2.1.0" } }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz", + "integrity": "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==", + "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "builtins": "^5.0.0" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "node_modules/validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "dev": true, "engines": { - "node": "*" + "node": ">= 0.10" } }, - "node_modules/rollup": { - "version": "3.29.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", - "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", - "devOptional": true, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=14.18.0", - "npm": ">=8.0.0" + "node_modules/vee-validate": { + "version": "4.12.6", + "resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-4.12.6.tgz", + "integrity": "sha512-EKM3YHy8t1miPh30d5X6xOrfG/Ctq0nbN4eMpCK7ezvI6T98/S66vswP+ihL4QqAK/k5KqreWOxof09+JG7N/A==", + "dependencies": { + "@vue/devtools-api": "^6.5.1", + "type-fest": "^4.8.3" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "peerDependencies": { + "vue": "^3.3.11" } }, - "node_modules/rollup-plugin-visualizer": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.12.0.tgz", - "integrity": "sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==", + "node_modules/vite": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", + "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", "dev": true, "dependencies": { - "open": "^8.4.0", - "picomatch": "^2.3.1", - "source-map": "^0.7.4", - "yargs": "^17.5.1" + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" }, "bin": { - "rollup-plugin-visualizer": "dist/bin/cli.js" + "vite": "bin/vite.js" }, "engines": { - "node": ">=14" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" }, "peerDependencies": { - "rollup": "2.x || 3.x || 4.x" + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" }, "peerDependenciesMeta": { - "rollup": { + "@types/node": { "optional": true - } - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" + "less": { + "optional": true }, - { - "type": "consulting", - "url": "https://feross.org/support" + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true } - ], - "dependencies": { - "queue-microtask": "^1.2.2" } }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "peer": true, + "node_modules/vite-node": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.5.tgz", + "integrity": "sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" + "cac": "^6.7.14", + "debug": "^4.3.5", + "pathe": "^1.1.2", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" }, "engines": { - "node": ">=0.4" + "node": "^18.0.0 || >=20.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" } }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "peer": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, + "node_modules/vite-node/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, + "node_modules/vite-node/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=10" + "node": ">=12" } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, + "node_modules/vite-node/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10" + "node": ">=12" } }, - "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==", - "peer": true, - "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" - }, + "node_modules/vite-node/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" + "node": ">=12" } }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "peer": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, + "node_modules/vite-node/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" + "node": ">=12" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, + "node_modules/vite-node/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "node_modules/vite-node/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "peer": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, + "node_modules/vite-node/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==" - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/vite-node/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=12" } }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "node_modules/vite-node/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", - "dev": true, + "node_modules/vite-node/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, + "node_modules/vite-node/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">= 8" + "node": ">=12" } }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "node_modules/vite-node/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==" - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, + "node_modules/vite-node/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": ">= 0.8" + "node": ">=12" } }, - "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==" - }, - "node_modules/stdin-discarder": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", - "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", - "dev": true, + "node_modules/vite-node/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/strict-event-emitter": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", - "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==", - "dev": true + "node_modules/vite-node/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/string-argv": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", - "dev": true, + "node_modules/vite-node/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=0.6.19" + "node": ">=12" } }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "node_modules/vite-node/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" }, "engines": { "node": ">=12" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, - "node_modules/string-width-cjs": { - "name": "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==", - "dev": true, + "node_modules/vite-node/node_modules/rollup": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz", + "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/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==", - "dev": true, - "engines": { - "node": ">=8" + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.21.2", + "@rollup/rollup-android-arm64": "4.21.2", + "@rollup/rollup-darwin-arm64": "4.21.2", + "@rollup/rollup-darwin-x64": "4.21.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.21.2", + "@rollup/rollup-linux-arm-musleabihf": "4.21.2", + "@rollup/rollup-linux-arm64-gnu": "4.21.2", + "@rollup/rollup-linux-arm64-musl": "4.21.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.21.2", + "@rollup/rollup-linux-riscv64-gnu": "4.21.2", + "@rollup/rollup-linux-s390x-gnu": "4.21.2", + "@rollup/rollup-linux-x64-gnu": "4.21.2", + "@rollup/rollup-linux-x64-musl": "4.21.2", + "@rollup/rollup-win32-arm64-msvc": "4.21.2", + "@rollup/rollup-win32-ia32-msvc": "4.21.2", + "@rollup/rollup-win32-x64-msvc": "4.21.2", + "fsevents": "~2.3.2" } }, - "node_modules/string-width-cjs/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==", - "dev": true - }, - "node_modules/string-width-cjs/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==", - "dev": true, + "node_modules/vite-node/node_modules/vite": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.3.tgz", + "integrity": "sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==", "dependencies": { - "ansi-regex": "^5.0.1" + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" }, "engines": { - "node": ">=8" + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } } }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "peer": true, + "node_modules/vite-plugin-dts": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/vite-plugin-dts/-/vite-plugin-dts-3.9.0.tgz", + "integrity": "sha512-pwFIEYQ3LZvMafkEGvNnileb6af5JuyZsBfYQrTDYxdeGEy0OS4B4hCsLPo5YGnhK5k9EzyO6BXVO6y+Lt5T2A==", + "dev": true, "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" + "@microsoft/api-extractor": "7.43.0", + "@rollup/pluginutils": "^5.1.0", + "@vue/language-core": "^1.8.27", + "debug": "^4.3.4", + "kolorist": "^1.8.0", + "magic-string": "^0.30.8", + "vue-tsc": "^1.8.27" }, "engines": { - "node": ">= 0.4" + "node": "^14.18.0 || >=16.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "peer": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "peerDependencies": { + "typescript": "*", + "vite": "*" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependenciesMeta": { + "vite": { + "optional": true + } } }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "peer": true, + "node_modules/vitest": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.5.tgz", + "integrity": "sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "@ampproject/remapping": "^2.3.0", + "@vitest/expect": "2.0.5", + "@vitest/pretty-format": "^2.0.5", + "@vitest/runner": "2.0.5", + "@vitest/snapshot": "2.0.5", + "@vitest/spy": "2.0.5", + "@vitest/utils": "2.0.5", + "chai": "^5.1.1", + "debug": "^4.3.5", + "execa": "^8.0.1", + "magic-string": "^0.30.10", + "pathe": "^1.1.2", + "std-env": "^3.7.0", + "tinybench": "^2.8.0", + "tinypool": "^1.0.0", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.0.5", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" }, "engines": { - "node": ">= 0.4" + "node": "^18.0.0 || >=20.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" + "url": "https://opencollective.com/vitest" }, - "engines": { - "node": ">=12" + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.0.5", + "@vitest/ui": "2.0.5", + "happy-dom": "*", + "jsdom": "*" }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } } }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, + "node_modules/vitest/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/strip-ansi-cjs/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==", - "dev": true, + "node_modules/vitest/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, + "node_modules/vitest/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "node_modules/vitest/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], "engines": { "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "node_modules/vitest/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/strip-literal": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", - "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", - "dev": true, - "dependencies": { - "acorn": "^8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" + "node_modules/vitest/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" } }, - "node_modules/sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^10.3.10", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, + "node_modules/vitest/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=12" } }, - "node_modules/sucrase/node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, + "node_modules/vitest/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 6" + "node": ">=12" } }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, + "node_modules/vitest/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "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==", + "node_modules/vitest/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "node_modules/synckit": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", - "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", - "dependencies": { - "@pkgr/core": "^0.1.0", - "tslib": "^2.6.2" - }, + "node_modules/vitest/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" + "node": ">=12" } }, - "node_modules/syncpack": { - "version": "12.3.2", - "resolved": "https://registry.npmjs.org/syncpack/-/syncpack-12.3.2.tgz", - "integrity": "sha512-ePvaDfasxF8mwaPItN6urmABaH6FPT3/vJU+2DHt24j8EIKjgz6NCxXDx2bTXJXZ4QcEFwvoiu3EqaJsVrHvUg==", - "dev": true, - "dependencies": { - "@effect/schema": "0.66.5", - "chalk": "5.3.0", - "chalk-template": "1.1.0", - "commander": "12.0.0", - "cosmiconfig": "9.0.0", - "effect": "3.0.3", - "enquirer": "2.4.1", - "fast-check": "3.17.2", - "globby": "14.0.1", - "minimatch": "9.0.4", - "npm-package-arg": "11.0.2", - "ora": "8.0.1", - "prompts": "2.4.2", - "read-yaml-file": "2.1.0", - "semver": "7.6.0", - "tightrope": "0.2.0", - "ts-toolbelt": "9.6.0" - }, - "bin": { - "syncpack": "dist/bin.js", - "syncpack-fix-mismatches": "dist/bin-fix-mismatches/index.js", - "syncpack-format": "dist/bin-format/index.js", - "syncpack-lint": "dist/bin-lint/index.js", - "syncpack-lint-semver-ranges": "dist/bin-lint-semver-ranges/index.js", - "syncpack-list": "dist/bin-list/index.js", - "syncpack-list-mismatches": "dist/bin-list-mismatches/index.js", - "syncpack-prompt": "dist/bin-prompt/index.js", - "syncpack-set-semver-ranges": "dist/bin-set-semver-ranges/index.js", - "syncpack-update": "dist/bin-update/index.js" - }, + "node_modules/vitest/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=16" + "node": ">=12" } }, - "node_modules/syncpack/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, + "node_modules/vitest/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=12" } }, - "node_modules/syncpack/node_modules/commander": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz", - "integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==", - "dev": true, + "node_modules/vitest/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18" + "node": ">=12" } }, - "node_modules/syncpack/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, + "node_modules/vitest/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=12" } }, - "node_modules/tailwindcss": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz", - "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==", - "dev": true, - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.5.3", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.0", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.0", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, + "node_modules/vitest/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=14.0.0" + "node": ">=12" } }, - "node_modules/tailwindcss/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, + "node_modules/vitest/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=10.13.0" + "node": ">=12" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "dependencies": { - "any-promise": "^1.0.0" + "node_modules/vitest/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" } }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, + "node_modules/vitest/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": ">=0.8" + "node": ">=12" } }, - "node_modules/tightrope": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/tightrope/-/tightrope-0.2.0.tgz", - "integrity": "sha512-Kw36UHxJEELq2VUqdaSGR2/8cAsPgMtvX8uGVU6Jk26O66PhXec0A5ZnRYs47btbtwPDpXXF66+Fo3vimCM9aQ==", - "dev": true, + "node_modules/vitest/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=16" + "node": ">=12" } }, - "node_modules/tinybench": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", - "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==" - }, - "node_modules/tinypool": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz", - "integrity": "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==", - "dev": true, + "node_modules/vitest/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=14.0.0" + "node": ">=12" } }, - "node_modules/tinyrainbow": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", - "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "node_modules/vitest/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=14.0.0" + "node": ">=12" } }, - "node_modules/tinyspy": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", - "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", - "dev": true, + "node_modules/vitest/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, "engines": { - "node": ">=14.0.0" + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/vitest/node_modules/rollup": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz", + "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==", "dependencies": { - "is-number": "^7.0.0" + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=8.0" + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.21.2", + "@rollup/rollup-android-arm64": "4.21.2", + "@rollup/rollup-darwin-arm64": "4.21.2", + "@rollup/rollup-darwin-x64": "4.21.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.21.2", + "@rollup/rollup-linux-arm-musleabihf": "4.21.2", + "@rollup/rollup-linux-arm64-gnu": "4.21.2", + "@rollup/rollup-linux-arm64-musl": "4.21.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.21.2", + "@rollup/rollup-linux-riscv64-gnu": "4.21.2", + "@rollup/rollup-linux-s390x-gnu": "4.21.2", + "@rollup/rollup-linux-x64-gnu": "4.21.2", + "@rollup/rollup-linux-x64-musl": "4.21.2", + "@rollup/rollup-win32-arm64-msvc": "4.21.2", + "@rollup/rollup-win32-ia32-msvc": "4.21.2", + "@rollup/rollup-win32-x64-msvc": "4.21.2", + "fsevents": "~2.3.2" } }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "node_modules/vitest/node_modules/vite": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.3.tgz", + "integrity": "sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, "engines": { - "node": ">=16" + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" }, "peerDependencies": { - "typescript": ">=4.2.0" + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vue": { + "version": "3.4.25", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.25.tgz", + "integrity": "sha512-HWyDqoBHMgav/OKiYA2ZQg+kjfMgLt/T0vg4cbIF7JbXAjDexRf5JRg+PWAfrAkSmTd2I8aPSXtooBFWHB98cg==", + "dependencies": { + "@vue/compiler-dom": "3.4.25", + "@vue/compiler-sfc": "3.4.25", + "@vue/runtime-dom": "3.4.25", + "@vue/server-renderer": "3.4.25", + "@vue/shared": "3.4.25" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true - }, - "node_modules/ts-toolbelt": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", - "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==", + "node_modules/vue-component-type-helpers": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.0.14.tgz", + "integrity": "sha512-DInfgOyXlMyliyqAAD9frK28tTfch0+tMi4qoWJcZlRxUf+NFAtraJBnAsKLep+FOyLMiajkhfyEb3xLK08i7w==", "dev": true }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "peer": true, + "node_modules/vue-eslint-parser": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz", + "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==", "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" + "debug": "^4.3.4", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.6" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=6.0.0" } }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "peer": true, + "node_modules/vue-i18n": { + "version": "9.13.1", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.13.1.tgz", + "integrity": "sha512-mh0GIxx0wPtPlcB1q4k277y0iKgo25xmDPWioVVYanjPufDBpvu5ySTjP5wOrSvlYQ2m1xI+CFhGdauv/61uQg==", "dependencies": { - "minimist": "^1.2.0" + "@intlify/core-base": "9.13.1", + "@intlify/shared": "9.13.1", + "@vue/devtools-api": "^6.5.0" }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "peer": true, "engines": { - "node": ">=4" + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + }, + "peerDependencies": { + "vue": "^3.0.0" } }, - "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "node_modules/turbo": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/turbo/-/turbo-1.13.2.tgz", - "integrity": "sha512-rX/d9f4MgRT3yK6cERPAkfavIxbpBZowDQpgvkYwGMGDQ0Nvw1nc0NVjruE76GrzXQqoxR1UpnmEP54vBARFHQ==", - "dev": true, - "bin": { - "turbo": "bin/turbo" + "node_modules/vue-router": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.2.tgz", + "integrity": "sha512-hKQJ1vDAZ5LVkKEnHhmm1f9pMiWIBNGF5AwU67PdH7TyXCj/a4hTccuUuYCAMgJK6rO/NVYtQIEN3yL8CECa7Q==", + "dependencies": { + "@vue/devtools-api": "^6.5.1" }, - "optionalDependencies": { - "turbo-darwin-64": "1.13.2", - "turbo-darwin-arm64": "1.13.2", - "turbo-linux-64": "1.13.2", - "turbo-linux-arm64": "1.13.2", - "turbo-windows-64": "1.13.2", - "turbo-windows-arm64": "1.13.2" + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" } }, - "node_modules/turbo-darwin-64": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-1.13.2.tgz", - "integrity": "sha512-CCSuD8CfmtncpohCuIgq7eAzUas0IwSbHfI8/Q3vKObTdXyN8vAo01gwqXjDGpzG9bTEVedD0GmLbD23dR0MLA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/turbo-darwin-arm64": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-1.13.2.tgz", - "integrity": "sha512-0HySm06/D2N91rJJ89FbiI/AodmY8B3WDSFTVEpu2+8spUw7hOJ8okWOT0e5iGlyayUP9gr31eOeL3VFZkpfCw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/turbo-linux-64": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-1.13.2.tgz", - "integrity": "sha512-7HnibgbqZrjn4lcfIouzlPu8ZHSBtURG4c7Bedu7WJUDeZo+RE1crlrQm8wuwO54S0siYqUqo7GNHxu4IXbioQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/turbo-linux-arm64": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-1.13.2.tgz", - "integrity": "sha512-sUq4dbpk6SNKg/Hkwn256Vj2AEYSQdG96repio894h5/LEfauIK2QYiC/xxAeW3WBMc6BngmvNyURIg7ltrePg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/turbo-windows-64": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-1.13.2.tgz", - "integrity": "sha512-DqzhcrciWq3dpzllJR2VVIyOhSlXYCo4mNEWl98DJ3FZ08PEzcI3ceudlH6F0t/nIcfSItK1bDP39cs7YoZHEA==", - "cpu": [ - "x64" - ], + "node_modules/vue-template-compiler": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", + "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", "dev": true, - "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } }, - "node_modules/turbo-windows-arm64": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-1.13.2.tgz", - "integrity": "sha512-WnPMrwfCXxK69CdDfS1/j2DlzcKxSmycgDAqV0XCYpK/812KB0KlvsVAt5PjEbZGXkY88pCJ1BLZHAjF5FcbqA==", - "cpu": [ - "arm64" - ], + "node_modules/vue-tsc": { + "version": "1.8.27", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.27.tgz", + "integrity": "sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==", "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dependencies": { - "prelude-ls": "^1.2.1" + "@volar/typescript": "~1.11.1", + "@vue/language-core": "1.8.27", + "semver": "^7.5.4" }, - "engines": { - "node": ">= 0.8.0" + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": "*" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "engines": { - "node": ">=4" + "node": ">=10.13.0" } }, - "node_modules/type-fest": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.17.0.tgz", - "integrity": "sha512-9flrz1zkfLRH3jO3bLflmTxryzKMxVa7841VeMgBaNQGY6vH4RCcpN/sQLB7mQQYh1GZ5utT2deypMuCy4yicw==", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "node_modules/webpack-virtual-modules": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.1.tgz", + "integrity": "sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==" }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "peer": true, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" + "isexe": "^2.0.0" }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "peer": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "bin": { + "node-which": "bin/node-which" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 8" } }, - "node_modules/typed-array-byte-offset": { + "node_modules/which-boxed-primitive": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "peer": true, "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "peer": true, "dependencies": { + "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -8862,837 +9706,899 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "why-is-node-running": "cli.js" }, "engines": { - "node": ">=14.17" + "node": ">=8" } }, - "node_modules/ufo": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", - "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==" - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "peer": true, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "devOptional": true - }, - "node_modules/unicorn-magic": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", - "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "node_modules/wrap-ansi-cjs": { + "name": "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==", "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "node_modules/wrap-ansi-cjs/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==", "dev": true, "engines": { - "node": ">= 4.0.0" + "node": ">=8" } }, - "node_modules/unplugin": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.10.1.tgz", - "integrity": "sha512-d6Mhq8RJeGA8UfKCu54Um4lFA0eSaRa3XxdAJg8tIdxbu1ubW0hBCZUL7yI2uGyYCRndvbK8FLHzqy2XKfeMsg==", + "node_modules/wrap-ansi-cjs/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==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/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==", + "dev": true, "dependencies": { - "acorn": "^8.11.3", - "chokidar": "^3.6.0", - "webpack-sources": "^3.2.3", - "webpack-virtual-modules": "^0.6.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=14.0.0" + "node": ">=8" } }, - "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "node_modules/wrap-ansi-cjs/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==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/wretch": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/wretch/-/wretch-2.8.1.tgz", + "integrity": "sha512-as9Mta8Nrnu6mL9ApNvmKGWqZtvoQtOILEfjox1BYYBYyUSKUdATVEAlQIMGLSZyzRfNbpUvPKDcGJTGA1b5LA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yaml": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", + "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", "bin": { - "update-browserslist-db": "cli.js" + "yaml": "bin.mjs" }, - "peerDependencies": { - "browserslist": ">= 4.21.0" + "engines": { + "node": ">= 14" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "node_modules/yaml-eslint-parser": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.2.tgz", + "integrity": "sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==", "dependencies": { - "punycode": "^2.1.0" + "eslint-visitor-keys": "^3.0.0", + "lodash": "^4.17.21", + "yaml": "^2.0.0" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/validate-npm-package-name": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz", - "integrity": "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==", + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "dependencies": { - "builtins": "^5.0.0" + "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": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/validator": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", - "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "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==", "dev": true, "engines": { - "node": ">= 0.10" + "node": ">=12" } }, - "node_modules/vee-validate": { - "version": "4.12.6", - "resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-4.12.6.tgz", - "integrity": "sha512-EKM3YHy8t1miPh30d5X6xOrfG/Ctq0nbN4eMpCK7ezvI6T98/S66vswP+ihL4QqAK/k5KqreWOxof09+JG7N/A==", - "dependencies": { - "@vue/devtools-api": "^6.5.1", - "type-fest": "^4.8.3" - }, - "peerDependencies": { - "vue": "^3.3.11" + "node_modules/yargs/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==", + "dev": true, + "engines": { + "node": ">=8" } }, - "node_modules/vite": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", - "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", + "node_modules/yargs/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==", + "dev": true + }, + "node_modules/yargs/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==", "dev": true, "dependencies": { - "esbuild": "^0.18.10", - "postcss": "^8.4.27", - "rollup": "^3.27.1" - }, - "bin": { - "vite": "bin/vite.js" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - }, - "peerDependencies": { - "@types/node": ">= 14", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } + "node": ">=8" } }, - "node_modules/vite-node": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.6.tgz", - "integrity": "sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==", + "node_modules/yargs/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==", "dev": true, "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.4", - "mlly": "^1.4.0", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0-0" - }, - "bin": { - "vite-node": "vite-node.mjs" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=v14.18.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "node": ">=8" } }, - "node_modules/vite-plugin-dts": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/vite-plugin-dts/-/vite-plugin-dts-3.9.0.tgz", - "integrity": "sha512-pwFIEYQ3LZvMafkEGvNnileb6af5JuyZsBfYQrTDYxdeGEy0OS4B4hCsLPo5YGnhK5k9EzyO6BXVO6y+Lt5T2A==", - "dev": true, - "dependencies": { - "@microsoft/api-extractor": "7.43.0", - "@rollup/pluginutils": "^5.1.0", - "@vue/language-core": "^1.8.27", - "debug": "^4.3.4", - "kolorist": "^1.8.0", - "magic-string": "^0.30.8", - "vue-tsc": "^1.8.27" - }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "typescript": "*", - "vite": "*" + "node": ">=10" }, - "peerDependenciesMeta": { - "vite": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/vitest": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.6.tgz", - "integrity": "sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==", + "node_modules/z-schema": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", + "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", "dev": true, "dependencies": { - "@types/chai": "^4.3.5", - "@types/chai-subset": "^1.3.3", - "@types/node": "*", - "@vitest/expect": "0.34.6", - "@vitest/runner": "0.34.6", - "@vitest/snapshot": "0.34.6", - "@vitest/spy": "0.34.6", - "@vitest/utils": "0.34.6", - "acorn": "^8.9.0", - "acorn-walk": "^8.2.0", - "cac": "^6.7.14", - "chai": "^4.3.10", - "debug": "^4.3.4", - "local-pkg": "^0.4.3", - "magic-string": "^0.30.1", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "std-env": "^3.3.3", - "strip-literal": "^1.0.1", - "tinybench": "^2.5.0", - "tinypool": "^0.7.0", - "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0", - "vite-node": "0.34.6", - "why-is-node-running": "^2.2.2" + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "validator": "^13.7.0" }, "bin": { - "vitest": "vitest.mjs" + "z-schema": "bin/z-schema" }, "engines": { - "node": ">=v14.18.0" + "node": ">=8.0.0" }, + "optionalDependencies": { + "commander": "^9.4.1" + } + }, + "node_modules/z-schema/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "optional": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/zod": { + "version": "3.23.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.4.tgz", + "integrity": "sha512-/AtWOKbBgjzEYYQRNfoGKHObgfAZag6qUJX1VbHo2PRBgS+wfWagEY2mizjfyAPcGesrJOcx/wcl0L9WnVrHFw==", "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@vitest/browser": "*", - "@vitest/ui": "*", - "happy-dom": "*", - "jsdom": "*", - "playwright": "*", - "safaridriver": "*", - "webdriverio": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - }, - "playwright": { - "optional": true - }, - "safaridriver": { - "optional": true - }, - "webdriverio": { - "optional": true - } + "url": "https://github.com/sponsors/colinhacks" + } + }, + "packages/eslint-config-kwai": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "latest", + "@typescript-eslint/parser": "latest", + "@vue/eslint-config-typescript": "latest", + "eslint": "latest", + "eslint-config-prettier": "latest", + "eslint-config-standard": "latest", + "eslint-plugin-prettier": "latest", + "eslint-plugin-vue": "latest", + "vue-eslint-parser": "latest" } }, - "node_modules/vue": { - "version": "3.4.25", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.25.tgz", - "integrity": "sha512-HWyDqoBHMgav/OKiYA2ZQg+kjfMgLt/T0vg4cbIF7JbXAjDexRf5JRg+PWAfrAkSmTd2I8aPSXtooBFWHB98cg==", + "packages/kwai-api": { + "name": "@kwai/api", + "version": "0.0.1", + "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.4.25", - "@vue/compiler-sfc": "3.4.25", - "@vue/runtime-dom": "3.4.25", - "@vue/server-renderer": "3.4.25", - "@vue/shared": "3.4.25" - }, - "peerDependencies": { - "typescript": "*" + "@kwai/config": "*", + "@vueuse/core": "^10.9.0", + "wretch": "^2.7.0", + "zod": "^3.23.4" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "devDependencies": { + "vite-plugin-dts": "^3.6.3", + "vitest": "^0.34.6" } }, - "node_modules/vue-component-type-helpers": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.0.14.tgz", - "integrity": "sha512-DInfgOyXlMyliyqAAD9frK28tTfch0+tMi4qoWJcZlRxUf+NFAtraJBnAsKLep+FOyLMiajkhfyEb3xLK08i7w==", - "dev": true - }, - "node_modules/vue-eslint-parser": { - "version": "9.4.2", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz", - "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==", + "packages/kwai-api/node_modules/@vitest/expect": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.6.tgz", + "integrity": "sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==", + "dev": true, "dependencies": { - "debug": "^4.3.4", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", - "esquery": "^1.4.0", - "lodash": "^4.17.21", - "semver": "^7.3.6" - }, - "engines": { - "node": "^14.17.0 || >=16.0.0" + "@vitest/spy": "0.34.6", + "@vitest/utils": "0.34.6", + "chai": "^4.3.10" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=6.0.0" + "url": "https://opencollective.com/vitest" } }, - "node_modules/vue-i18n": { - "version": "9.13.1", - "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.13.1.tgz", - "integrity": "sha512-mh0GIxx0wPtPlcB1q4k277y0iKgo25xmDPWioVVYanjPufDBpvu5ySTjP5wOrSvlYQ2m1xI+CFhGdauv/61uQg==", + "packages/kwai-api/node_modules/@vitest/runner": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.6.tgz", + "integrity": "sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==", + "dev": true, "dependencies": { - "@intlify/core-base": "9.13.1", - "@intlify/shared": "9.13.1", - "@vue/devtools-api": "^6.5.0" - }, - "engines": { - "node": ">= 16" + "@vitest/utils": "0.34.6", + "p-limit": "^4.0.0", + "pathe": "^1.1.1" }, "funding": { - "url": "https://github.com/sponsors/kazupon" - }, - "peerDependencies": { - "vue": "^3.0.0" + "url": "https://opencollective.com/vitest" } }, - "node_modules/vue-router": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.2.tgz", - "integrity": "sha512-hKQJ1vDAZ5LVkKEnHhmm1f9pMiWIBNGF5AwU67PdH7TyXCj/a4hTccuUuYCAMgJK6rO/NVYtQIEN3yL8CECa7Q==", + "packages/kwai-api/node_modules/@vitest/snapshot": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.6.tgz", + "integrity": "sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==", + "dev": true, "dependencies": { - "@vue/devtools-api": "^6.5.1" + "magic-string": "^0.30.1", + "pathe": "^1.1.1", + "pretty-format": "^29.5.0" }, "funding": { - "url": "https://github.com/sponsors/posva" - }, - "peerDependencies": { - "vue": "^3.2.0" + "url": "https://opencollective.com/vitest" } }, - "node_modules/vue-template-compiler": { - "version": "2.7.16", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", - "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", + "packages/kwai-api/node_modules/@vitest/spy": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.6.tgz", + "integrity": "sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==", "dev": true, "dependencies": { - "de-indent": "^1.0.2", - "he": "^1.2.0" + "tinyspy": "^2.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/vue-tsc": { - "version": "1.8.27", - "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.27.tgz", - "integrity": "sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==", + "packages/kwai-api/node_modules/@vitest/utils": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.6.tgz", + "integrity": "sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==", "dev": true, "dependencies": { - "@volar/typescript": "~1.11.1", - "@vue/language-core": "1.8.27", - "semver": "^7.5.4" - }, - "bin": { - "vue-tsc": "bin/vue-tsc.js" + "diff-sequences": "^29.4.3", + "loupe": "^2.3.6", + "pretty-format": "^29.5.0" }, - "peerDependencies": { - "typescript": "*" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "packages/kwai-api/node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, "engines": { - "node": ">=10.13.0" + "node": "*" } }, - "node_modules/webpack-virtual-modules": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.1.tgz", - "integrity": "sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==" - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "packages/kwai-api/node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" }, "engines": { - "node": ">= 8" + "node": ">=4" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "peer": true, + "packages/kwai-api/node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "get-func-name": "^2.0.2" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "*" } }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "peer": true, + "packages/kwai-api/node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" + "type-detect": "^4.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, - "node_modules/why-is-node-running": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "packages/kwai-api/node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" + "get-func-name": "^2.0.1" + } + }, + "packages/kwai-api/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" }, - "bin": { - "why-is-node-running": "cli.js" + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/kwai-api/node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "packages/kwai-api/node_modules/tinypool": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz", + "integrity": "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "packages/kwai-api/node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, "engines": { - "node": ">=8" + "node": ">=14.0.0" } }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "packages/kwai-api/node_modules/vite-node": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.6.tgz", + "integrity": "sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==", "dev": true, "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" + "cac": "^6.7.14", + "debug": "^4.3.4", + "mlly": "^1.4.0", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" }, "engines": { - "node": ">=12" + "node": ">=v14.18.0" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://opencollective.com/vitest" } }, - "node_modules/wrap-ansi-cjs": { - "name": "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==", + "packages/kwai-api/node_modules/vitest": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.6.tgz", + "integrity": "sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "@types/chai": "^4.3.5", + "@types/chai-subset": "^1.3.3", + "@types/node": "*", + "@vitest/expect": "0.34.6", + "@vitest/runner": "0.34.6", + "@vitest/snapshot": "0.34.6", + "@vitest/spy": "0.34.6", + "@vitest/utils": "0.34.6", + "acorn": "^8.9.0", + "acorn-walk": "^8.2.0", + "cac": "^6.7.14", + "chai": "^4.3.10", + "debug": "^4.3.4", + "local-pkg": "^0.4.3", + "magic-string": "^0.30.1", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.3.3", + "strip-literal": "^1.0.1", + "tinybench": "^2.5.0", + "tinypool": "^0.7.0", + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0", + "vite-node": "0.34.6", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" }, "engines": { - "node": ">=10" + "node": ">=v14.18.0" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@vitest/browser": "*", + "@vitest/ui": "*", + "happy-dom": "*", + "jsdom": "*", + "playwright": "*", + "safaridriver": "*", + "webdriverio": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "playwright": { + "optional": true + }, + "safaridriver": { + "optional": true + }, + "webdriverio": { + "optional": true + } } }, - "node_modules/wrap-ansi-cjs/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==", + "packages/kwai-api/node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/wrap-ansi-cjs/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==", - "dev": true + "packages/kwai-config": { + "name": "@kwai/config", + "version": "1.0.0", + "devDependencies": { + "@fbraem/rollup-plugin-toml": "^0.0.4", + "vite-plugin-dts": "^3.6.3" + } }, - "node_modules/wrap-ansi-cjs/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==", - "dev": true, + "packages/kwai-date": { + "name": "@kwai/date", + "version": "1.0.0", + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "dayjs": "^1.11.10" }, - "engines": { - "node": ">=8" + "devDependencies": { + "vitest": "^0.34.6" } }, - "node_modules/wrap-ansi-cjs/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==", + "packages/kwai-date/node_modules/@vitest/expect": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.6.tgz", + "integrity": "sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.1" + "@vitest/spy": "0.34.6", + "@vitest/utils": "0.34.6", + "chai": "^4.3.10" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "packages/kwai-date/node_modules/@vitest/runner": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.6.tgz", + "integrity": "sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==", "dev": true, - "engines": { - "node": ">=12" + "dependencies": { + "@vitest/utils": "0.34.6", + "p-limit": "^4.0.0", + "pathe": "^1.1.1" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/wretch": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/wretch/-/wretch-2.8.1.tgz", - "integrity": "sha512-as9Mta8Nrnu6mL9ApNvmKGWqZtvoQtOILEfjox1BYYBYyUSKUdATVEAlQIMGLSZyzRfNbpUvPKDcGJTGA1b5LA==", - "engines": { - "node": ">=14" - } - }, - "node_modules/xml-name-validator": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", - "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", - "engines": { - "node": ">=12" + "url": "https://opencollective.com/vitest" } }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "packages/kwai-date/node_modules/@vitest/snapshot": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.6.tgz", + "integrity": "sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==", "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yaml": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", - "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", - "bin": { - "yaml": "bin.mjs" + "dependencies": { + "magic-string": "^0.30.1", + "pathe": "^1.1.1", + "pretty-format": "^29.5.0" }, - "engines": { - "node": ">= 14" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/yaml-eslint-parser": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.2.tgz", - "integrity": "sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==", + "packages/kwai-date/node_modules/@vitest/spy": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.6.tgz", + "integrity": "sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==", + "dev": true, "dependencies": { - "eslint-visitor-keys": "^3.0.0", - "lodash": "^4.17.21", - "yaml": "^2.0.0" - }, - "engines": { - "node": "^14.17.0 || >=16.0.0" + "tinyspy": "^2.1.1" }, "funding": { - "url": "https://github.com/sponsors/ota-meshi" + "url": "https://opencollective.com/vitest" } }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "packages/kwai-date/node_modules/@vitest/utils": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.6.tgz", + "integrity": "sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==", "dev": true, "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" + "diff-sequences": "^29.4.3", + "loupe": "^2.3.6", + "pretty-format": "^29.5.0" }, - "engines": { - "node": ">=12" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "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==", + "packages/kwai-date/node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, "engines": { - "node": ">=12" + "node": "*" } }, - "node_modules/yargs/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==", + "packages/kwai-date/node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/yargs/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==", - "dev": true - }, - "node_modules/yargs/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==", + "packages/kwai-date/node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "get-func-name": "^2.0.2" }, "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/yargs/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==", + "packages/kwai-date/node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.1" + "type-detect": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "packages/kwai-date/node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" } }, - "node_modules/z-schema": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", - "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", + "packages/kwai-date/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", "dev": true, "dependencies": { - "lodash.get": "^4.4.2", - "lodash.isequal": "^4.5.0", - "validator": "^13.7.0" - }, - "bin": { - "z-schema": "bin/z-schema" + "yocto-queue": "^1.0.0" }, "engines": { - "node": ">=8.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "optionalDependencies": { - "commander": "^9.4.1" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/z-schema/node_modules/commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "packages/kwai-date/node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, - "optional": true, "engines": { - "node": "^12.20.0 || >=14" + "node": "*" } }, - "node_modules/zod": { - "version": "3.23.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.4.tgz", - "integrity": "sha512-/AtWOKbBgjzEYYQRNfoGKHObgfAZag6qUJX1VbHo2PRBgS+wfWagEY2mizjfyAPcGesrJOcx/wcl0L9WnVrHFw==", - "funding": { - "url": "https://github.com/sponsors/colinhacks" + "packages/kwai-date/node_modules/tinypool": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz", + "integrity": "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==", + "dev": true, + "engines": { + "node": ">=14.0.0" } }, - "packages/eslint-config-kwai": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "@typescript-eslint/eslint-plugin": "latest", - "@typescript-eslint/parser": "latest", - "@vue/eslint-config-typescript": "latest", - "eslint": "latest", - "eslint-config-prettier": "latest", - "eslint-config-standard": "latest", - "eslint-plugin-prettier": "latest", - "eslint-plugin-vue": "latest", - "vue-eslint-parser": "latest" + "packages/kwai-date/node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "engines": { + "node": ">=14.0.0" } }, - "packages/kwai-api": { - "name": "@kwai/api", - "version": "0.0.1", - "license": "MIT", + "packages/kwai-date/node_modules/vite-node": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.6.tgz", + "integrity": "sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==", + "dev": true, "dependencies": { - "@kwai/config": "*", - "@vueuse/core": "^10.9.0", - "wretch": "^2.7.0", - "zod": "^3.23.4" + "cac": "^6.7.14", + "debug": "^4.3.4", + "mlly": "^1.4.0", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0-0" }, - "devDependencies": { - "vite-plugin-dts": "^3.6.3", - "vitest": "^0.34.6" + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": ">=v14.18.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "packages/kwai-config": { - "name": "@kwai/config", - "version": "1.0.0", - "devDependencies": { - "@fbraem/rollup-plugin-toml": "^0.0.4", - "vite-plugin-dts": "^3.6.3" + "packages/kwai-date/node_modules/vitest": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.6.tgz", + "integrity": "sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==", + "dev": true, + "dependencies": { + "@types/chai": "^4.3.5", + "@types/chai-subset": "^1.3.3", + "@types/node": "*", + "@vitest/expect": "0.34.6", + "@vitest/runner": "0.34.6", + "@vitest/snapshot": "0.34.6", + "@vitest/spy": "0.34.6", + "@vitest/utils": "0.34.6", + "acorn": "^8.9.0", + "acorn-walk": "^8.2.0", + "cac": "^6.7.14", + "chai": "^4.3.10", + "debug": "^4.3.4", + "local-pkg": "^0.4.3", + "magic-string": "^0.30.1", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.3.3", + "strip-literal": "^1.0.1", + "tinybench": "^2.5.0", + "tinypool": "^0.7.0", + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0", + "vite-node": "0.34.6", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": ">=v14.18.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@vitest/browser": "*", + "@vitest/ui": "*", + "happy-dom": "*", + "jsdom": "*", + "playwright": "*", + "safaridriver": "*", + "webdriverio": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "playwright": { + "optional": true + }, + "safaridriver": { + "optional": true + }, + "webdriverio": { + "optional": true + } } }, - "packages/kwai-date": { - "name": "@kwai/date", - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "dayjs": "^1.11.10" + "packages/kwai-date/node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true, + "engines": { + "node": ">=12.20" }, - "devDependencies": { - "vitest": "^0.34.6" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "packages/kwai-types": { @@ -9711,7 +10617,7 @@ "dependencies": { "@kwai/date": "*", "@vuepic/vue-datepicker": "8.4.0", - "primevue": "^3.51.0" + "primevue": "4.0.5" }, "devDependencies": { "@tailwindcss/forms": "^0.5.6", diff --git a/frontend/package.json b/frontend/package.json index 5ff6e4b1..98cd5b96 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -22,5 +22,8 @@ "workspaces": [ "apps/*", "packages/*" - ] + ], + "dependencies": { + "vitest": "^2.0.5" + } } diff --git a/frontend/packages/kwai-ui/package.json b/frontend/packages/kwai-ui/package.json index b707191e..460bed9e 100644 --- a/frontend/packages/kwai-ui/package.json +++ b/frontend/packages/kwai-ui/package.json @@ -5,7 +5,7 @@ "dependencies": { "@kwai/date": "*", "@vuepic/vue-datepicker": "8.4.0", - "primevue": "^3.51.0" + "primevue": "4.0.5" }, "devDependencies": { "@tailwindcss/forms": "^0.5.6", From 7d22dd430be8e2adfcb0a6756e0614e86362377f Mon Sep 17 00:00:00 2001 From: zumuta Date: Mon, 9 Sep 2024 20:21:33 +0200 Subject: [PATCH 201/410] ci: update presets --- .../src/presets/kwai/accordion/index.js | 1 + .../src/presets/kwai/autocomplete/index.js | 161 ++-- .../kwai-ui/src/presets/kwai/badge/index.js | 36 +- .../kwai-ui/src/presets/kwai/blockui/index.js | 8 +- .../src/presets/kwai/breadcrumb/index.js | 8 +- .../kwai-ui/src/presets/kwai/button/index.js | 454 ++++----- .../src/presets/kwai/carousel/index.js | 68 +- .../src/presets/kwai/cascadeselect/index.js | 46 +- .../src/presets/kwai/checkbox/index.js | 15 +- .../kwai-ui/src/presets/kwai/chip/index.js | 7 +- .../src/presets/kwai/colorpicker/index.js | 12 +- .../src/presets/kwai/confirmpopup/index.js | 50 - .../src/presets/kwai/contextmenu/index.js | 21 +- .../src/presets/kwai/datatable/index.js | 859 +----------------- .../src/presets/kwai/dataview/index.js | 12 - .../kwai-ui/src/presets/kwai/dialog/index.js | 89 +- .../kwai-ui/src/presets/kwai/dock/index.js | 23 +- .../src/presets/kwai/fieldset/index.js | 6 +- .../src/presets/kwai/fileupload/index.js | 116 +-- .../src/presets/kwai/galleria/index.js | 46 +- .../src/presets/kwai/iconfield/index.js | 37 +- .../kwai-ui/src/presets/kwai/image/index.js | 22 +- .../kwai-ui/src/presets/kwai/index.js | 86 +- .../src/presets/kwai/inputmask/index.js | 11 +- .../src/presets/kwai/inputnumber/index.js | 209 ++--- .../src/presets/kwai/inputotp/index.js | 54 +- .../src/presets/kwai/inputtext/index.js | 11 +- .../kwai-ui/src/presets/kwai/knob/index.js | 4 +- .../kwai-ui/src/presets/kwai/listbox/index.js | 77 +- .../src/presets/kwai/megamenu/index.js | 23 +- .../kwai-ui/src/presets/kwai/menu/index.js | 12 +- .../kwai-ui/src/presets/kwai/menubar/index.js | 18 +- .../kwai-ui/src/presets/kwai/message/index.js | 31 +- .../src/presets/kwai/metergroup/index.js | 13 +- .../src/presets/kwai/multiselect/index.js | 383 +------- .../src/presets/kwai/orderlist/index.js | 248 +---- .../presets/kwai/organizationchart/index.js | 21 +- .../src/presets/kwai/paginator/index.js | 371 +------- .../src/presets/kwai/panelmenu/index.js | 20 +- .../src/presets/kwai/password/index.js | 58 +- .../src/presets/kwai/picklist/index.js | 634 +------------ .../src/presets/kwai/progressbar/index.js | 2 +- .../src/presets/kwai/radiobutton/index.js | 10 +- .../kwai-ui/src/presets/kwai/rating/index.js | 37 +- .../src/presets/kwai/scrollpanel/index.js | 2 +- .../src/presets/kwai/scrolltop/index.js | 47 +- .../src/presets/kwai/selectbutton/index.js | 49 +- .../kwai-ui/src/presets/kwai/slider/index.js | 18 +- .../src/presets/kwai/speeddial/index.js | 248 +---- .../src/presets/kwai/splitbutton/index.js | 499 +--------- .../kwai-ui/src/presets/kwai/stepper/index.js | 168 +--- .../kwai-ui/src/presets/kwai/tabmenu/index.js | 4 +- .../kwai-ui/src/presets/kwai/tag/index.js | 14 +- .../src/presets/kwai/textarea/index.js | 9 +- .../src/presets/kwai/tieredmenu/index.js | 21 +- .../src/presets/kwai/timeline/index.js | 16 +- .../kwai-ui/src/presets/kwai/toast/index.js | 24 +- .../src/presets/kwai/togglebutton/index.js | 86 +- .../kwai-ui/src/presets/kwai/tree/index.js | 175 +--- .../src/presets/kwai/treeselect/index.js | 258 +----- .../src/presets/kwai/treetable/index.js | 163 +--- 61 files changed, 987 insertions(+), 5244 deletions(-) diff --git a/frontend/packages/kwai-ui/src/presets/kwai/accordion/index.js b/frontend/packages/kwai-ui/src/presets/kwai/accordion/index.js index 24fcb506..23985e29 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/accordion/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/accordion/index.js @@ -1,4 +1,5 @@ export default { + // For PrimeVue 3 accordiontab: { root: { class: 'mb-1' diff --git a/frontend/packages/kwai-ui/src/presets/kwai/autocomplete/index.js b/frontend/packages/kwai-ui/src/presets/kwai/autocomplete/index.js index d45e7f24..ce55a9eb 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/autocomplete/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/autocomplete/index.js @@ -4,7 +4,10 @@ export default { 'relative', // Flex - 'inline-flex', + { + flex: props.fluid, + 'inline-flex': !props.fluid + }, // Size { 'w-full': props.multiple }, @@ -18,10 +21,10 @@ export default { } ] }), - container: ({ props, state }) => ({ + inputMultiple: ({ props, state }) => ({ class: [ // Font - 'font-sans text-base leading-none', + 'text-base leading-[normal]', // Flex 'flex items-center flex-wrap', @@ -49,7 +52,7 @@ export default { { 'border-red-500 dark:border-red-400': props.invalid }, // States - { 'hover:border-primary-500 dark:hover:border-primary-400': !props.invalid }, + { 'hover:border-primary': !props.invalid }, 'focus:outline-none focus:outline-offset-0', { 'ring ring-primary-400/50 dark:ring-primary-300/50': state.focused }, { 'ring ring-primary-400/50 dark:ring-primary-300/50': state.hovered }, @@ -60,115 +63,64 @@ export default { 'cursor-text overflow-hidden' ] }), - inputtoken: { + inputToken: { class: ['py-1.5 px-0', 'inline-flex flex-auto'] }, - input: ({ props }) => ({ - class: [ - // Font - 'font-sans text-base leading-none', - - // Shape - 'appearance-none rounded-md', - { 'rounded-tr-none rounded-br-none': props.dropdown }, - { 'outline-none shadow-none rounded-none': props.multiple }, - - // Size - { 'w-full': props.multiple }, + inputChip: { + class: 'flex-auto inline-flex pt-1 pb-1' + }, + input: { + class: 'border-none outline-none bg-transparent m-0 p-0 shadow-none rounded-none w-full' + }, + chipItem: { + root: { + class: [ + // Flex + 'inline-flex items-center', - // Spacing - 'm-0', - { 'p-3': !props.multiple, 'p-0': props.multiple }, + // Spacings + 'py-1.5 px-3', - // Colors - 'text-surface-700 dark:text-white/80', - 'border', - { - 'bg-surface-0 dark:bg-surface-900': !props.multiple, - ' border-surface-300 dark:border-surface-700': !props.multiple && !props.invalid, - 'border-0 bg-transparent': props.multiple - }, - - // Invalid State - { 'border-red-500 dark:border-red-400': props.invalid }, + // Shape + 'rounded-[1.14rem]', - // States - { 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50': !props.multiple }, + // Colors + 'bg-surface-200 dark:bg-surface-700', + 'text-surface-700 dark:text-white/70', - // Transition - 'transition-colors duration-200' - ] - }), - token: { + // Misc + 'cursor-default' + ] + } + }, + dropdown: { class: [ - // Flex - 'inline-flex items-center', - - // Spacings - 'py-1.5 px-3', - - // Shape - 'rounded-[1.14rem]', + 'relative', - // Colors - 'bg-surface-200 dark:bg-surface-700', - 'text-surface-700 dark:text-white/70', + // Alignments + 'items-center inline-flex text-center align-bottom', - // Misc - 'cursor-default' - ] - }, - label: { - class: 'leading-5' - }, - removeTokenIcon: { - class: [ // Shape - 'rounded-md leading-6', - - // Spacing - 'ml-2', + 'rounded-r-md', // Size - 'w-4 h-4', + 'px-4 py-3 leading-[normal]', - // Transition - 'transition duration-200 ease-in-out', + // Colors + 'text-primary-contrast', + 'bg-primary', + 'border border-primary', - // Misc - 'cursor-pointer' + // States + 'focus:outline-none focus:outline-offset-0 focus:ring', + 'hover:bg-primary-emphasis hover:border-primary-emphasis', + 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50' ] }, - dropdownbutton: { - root: { - class: [ - 'relative', - - // Alignments - 'items-center inline-flex text-center align-bottom', - - // Shape - 'rounded-r-md', - - // Size - 'px-4 py-3 leading-none', - - // Colors - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // States - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50' - ] - } - }, - loadingicon: { + loader: { class: ['text-surface-500 dark:text-surface-0/70', 'absolute top-[50%] right-[0.5rem] -mt-2 animate-spin'] }, - panel: { + overlay: { class: [ // Colors 'bg-surface-0 dark:bg-surface-800', @@ -186,12 +138,12 @@ export default { list: { class: 'py-3 px-0 list-none m-0' }, - item: ({ context }) => ({ + option: ({ context }) => ({ class: [ 'relative', // Font - 'font-normal text-base leading-none', + 'font-normal text-base leading-[normal]', // Spacing 'm-0 px-5 py-3', @@ -204,16 +156,13 @@ export default { 'text-surface-700 dark:text-white/80': !context.focused && !context.selected, 'bg-surface-200 dark:bg-surface-600/60': context.focused && !context.selected, 'text-surface-700 dark:text-white/80': context.focused && !context.selected, - - 'text-primary-700 dark:text-white/80': context.focused && context.selected, - 'bg-primary-100 dark:bg-primary-400': context.focused && context.selected, - 'text-primary-700 dark:text-white/80': !context.focused && context.selected, - 'bg-primary-50 dark:bg-primary-300': !context.focused && context.selected + 'bg-highlight': context.selected }, //States { 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context.focused && !context.selected }, - { 'hover:text-surface-700 hover:bg-surface-100 dark:hover:text-white dark:hover:bg-surface-600/80': context.focused && !context.selected }, + { 'hover:bg-highlight-emphasis': context.selected }, + 'focus-visible:outline-none focus-visible:outline-offset-0 focus-visible:ring focus-visible:ring-inset focus-visible:ring-primary-400/50 dark:focus-visible:ring-primary-300/50', // Transition 'transition-shadow duration-200', @@ -222,7 +171,7 @@ export default { 'cursor-pointer overflow-hidden whitespace-nowrap' ] }), - itemgroup: { + optionGroup: { class: [ 'font-bold', @@ -237,10 +186,10 @@ export default { 'cursor-auto' ] }, - emptymessage: { + emptyMessage: { class: [ // Font - 'leading-none', + 'leading-[normal]', // Spacing 'py-3 px-5', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/badge/index.js b/frontend/packages/kwai-ui/src/presets/kwai/badge/index.js index 513562c8..ee90762e 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/badge/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/badge/index.js @@ -5,9 +5,10 @@ export default { 'font-bold', { - 'text-xs leading-[1.5rem]': props.size == null, - 'text-lg leading-[2.25rem]': props.size == 'large', - 'text-2xl leading-[3rem]': props.size == 'xlarge' + 'text-xs leading-[1.5rem]': props.size === null, + 'text-[0.625rem] leading-[1.25rem]': props.size === 'small', + 'text-lg leading-[2.25rem]': props.size === 'large', + 'text-2xl leading-[3rem]': props.size === 'xlarge' }, // Alignment @@ -16,27 +17,30 @@ export default { // Size 'p-0 px-1', { - 'min-w-[1.5rem] h-[1.5rem]': props.size == null, - 'min-w-[2.25rem] h-[2.25rem]': props.size == 'large', - 'min-w-[3rem] h-[3rem]': props.size == 'xlarge' + 'w-2 h-2': props.value === null, + 'min-w-[1.5rem] h-[1.5rem]': props.value !== null && props.size === null, + 'min-w-[1.25rem] h-[1.25rem]': props.size === 'small', + 'min-w-[2.25rem] h-[2.25rem]': props.size === 'large', + 'min-w-[3rem] h-[3rem]': props.size === 'xlarge' }, // Shape { - 'rounded-full': props.value.length == 1, - 'rounded-[0.71rem]': props.value.length !== 1 + 'rounded-full': props.value?.length === 1, + 'rounded-[0.71rem]': props.value?.length !== 1 }, // Color - 'text-white dark:text-surface-900', + 'text-primary-contrast', { - 'bg-primary-500 dark:bg-primary-400': props.severity == null || props.severity == 'primary', - 'bg-surface-500 dark:bg-surface-400': props.severity == 'secondary', - 'bg-green-500 dark:bg-green-400': props.severity == 'success', - 'bg-blue-500 dark:bg-blue-400': props.severity == 'info', - 'bg-orange-500 dark:bg-orange-400': props.severity == 'warning', - 'bg-purple-500 dark:bg-purple-400': props.severity == 'help', - 'bg-red-500 dark:bg-red-400': props.severity == 'danger' + 'bg-primary': props.severity === null || props.severity === 'primary', + 'bg-surface-500 dark:bg-surface-400': props.severity === 'secondary', + 'bg-green-500 dark:bg-green-400': props.severity === 'success', + 'bg-blue-500 dark:bg-blue-400': props.severity === 'info', + 'bg-orange-500 dark:bg-orange-400': props.severity === 'warn', + 'bg-purple-500 dark:bg-purple-400': props.severity === 'help', + 'bg-red-500 dark:bg-red-400': props.severity === 'danger', + 'text-surface-0 dark:text-surface-900 bg-surface-900 dark:bg-surface-0': props.severity === 'contrast' } ] }) diff --git a/frontend/packages/kwai-ui/src/presets/kwai/blockui/index.js b/frontend/packages/kwai-ui/src/presets/kwai/blockui/index.js index 0c81a0c9..928257a2 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/blockui/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/blockui/index.js @@ -1,8 +1,4 @@ export default { - root: { - class: 'relative' - }, - mask: { - class: 'bg-black/40' - } + root: 'relative', + mask: 'bg-black/40 rounded-md' }; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/breadcrumb/index.js b/frontend/packages/kwai-ui/src/presets/kwai/breadcrumb/index.js index 81b23fd0..9941833a 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/breadcrumb/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/breadcrumb/index.js @@ -15,7 +15,7 @@ export default { 'overflow-x-auto' ] }, - menu: { + list: { class: [ // Flex & Alignment 'flex items-center flex-nowrap', @@ -24,10 +24,10 @@ export default { 'm-0 p-0 list-none leading-none' ] }, - action: { + itemLink: { class: [ // Flex & Alignment - 'flex items-center', + 'flex items-center gap-2', // Shape 'rounded-md', @@ -46,7 +46,7 @@ export default { 'text-decoration-none' ] }, - icon: { + itemIcon: { class: 'text-surface-600 dark:text-white/70' }, separator: { diff --git a/frontend/packages/kwai-ui/src/presets/kwai/button/index.js b/frontend/packages/kwai-ui/src/presets/kwai/button/index.js index 9fbb0d90..cdc5241f 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/button/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/button/index.js @@ -1,220 +1,238 @@ export default { - root: ({ props, context, parent }) => ({ - class: [ - 'relative', - - // Alignments - 'items-center inline-flex text-center align-bottom justify-center', - - // Sizes & Spacing - 'leading-[normal]', - { - 'px-4 py-3': props.size === null, - 'text-sm py-2 px-3': props.size === 'small', - 'text-xl py-3 px-4': props.size === 'large', - }, - { - 'w-12 p-0 py-3': props.label == null && props.icon !== null, - }, - - // Shapes - { 'shadow-lg': props.raised }, - { 'rounded-md': !props.rounded, 'rounded-full': props.rounded }, - { 'rounded-none first:rounded-l-md last:rounded-r-md': parent.instance.$name === 'ButtonGroup' }, - - // Link Button - { 'text-primary-600 bg-transparent border-transparent': props.link }, - - // Plain Button - { 'text-white bg-gray-500 border border-gray-500': props.plain && !props.outlined && !props.text }, - // Plain Text Button - { 'text-surface-500': props.plain && props.text }, - // Plain Outlined Button - { 'text-surface-500 border border-gray-500': props.plain && props.outlined }, - - // Text Button - { 'bg-transparent border-transparent': props.text && !props.plain }, - - // Outlined Button - { 'bg-transparent border': props.outlined && !props.plain }, - - // --- Severity Buttons --- - - // Primary Button - { - 'text-white dark:text-surface-900': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain, - 'bg-primary-500 dark:bg-primary-400': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain, - 'border border-primary-500 dark:border-primary-400': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain, - }, - // Primary Text Button - { 'text-primary-500 dark:text-primary-400': props.text && props.severity === null && !props.plain }, - // Primary Outlined Button - { 'text-primary-500 border border-primary-500 hover:bg-primary-300/20': props.outlined && props.severity === null && !props.plain }, - - // Secondary Button - { - 'text-white dark:text-surface-900': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain, - 'bg-surface-500 dark:bg-surface-400': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain, - 'border border-surface-500 dark:border-surface-400': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain, - }, - // Secondary Text Button - { 'text-surface-500 dark:text-surface-300': props.text && props.severity === 'secondary' && !props.plain }, - // Secondary Outlined Button - { 'text-surface-500 dark:text-surface-300 border border-surface-500 hover:bg-surface-300/20': props.outlined && props.severity === 'secondary' && !props.plain }, - - // Success Button - { - 'text-white dark:text-green-900': props.severity === 'success' && !props.text && !props.outlined && !props.plain, - 'bg-green-500 dark:bg-green-400': props.severity === 'success' && !props.text && !props.outlined && !props.plain, - 'border border-green-500 dark:border-green-400': props.severity === 'success' && !props.text && !props.outlined && !props.plain, - }, - // Success Text Button - { 'text-green-500 dark:text-green-400': props.text && props.severity === 'success' && !props.plain }, - // Success Outlined Button - { 'text-green-500 border border-green-500 hover:bg-green-300/20': props.outlined && props.severity === 'success' && !props.plain }, - - // Info Button - { - 'text-white dark:text-surface-900': props.severity === 'info' && !props.text && !props.outlined && !props.plain, - 'bg-blue-500 dark:bg-blue-400': props.severity === 'info' && !props.text && !props.outlined && !props.plain, - 'border border-blue-500 dark:border-blue-400': props.severity === 'info' && !props.text && !props.outlined && !props.plain, - }, - // Info Text Button - { 'text-blue-500 dark:text-blue-400': props.text && props.severity === 'info' && !props.plain }, - // Info Outlined Button - { 'text-blue-500 border border-blue-500 hover:bg-blue-300/20 ': props.outlined && props.severity === 'info' && !props.plain }, - - // Warning Button - { - 'text-white dark:text-surface-900': props.severity === 'warning' && !props.text && !props.outlined && !props.plain, - 'bg-orange-500 dark:bg-orange-400': props.severity === 'warning' && !props.text && !props.outlined && !props.plain, - 'border border-orange-500 dark:border-orange-400': props.severity === 'warning' && !props.text && !props.outlined && !props.plain, - }, - // Warning Text Button - { 'text-orange-500 dark:text-orange-400': props.text && props.severity === 'warning' && !props.plain }, - // Warning Outlined Button - { 'text-orange-500 border border-orange-500 hover:bg-orange-300/20': props.outlined && props.severity === 'warning' && !props.plain }, - - // Help Button - { - 'text-white dark:text-surface-900': props.severity === 'help' && !props.text && !props.outlined && !props.plain, - 'bg-purple-500 dark:bg-purple-400': props.severity === 'help' && !props.text && !props.outlined && !props.plain, - 'border border-purple-500 dark:border-purple-400': props.severity === 'help' && !props.text && !props.outlined && !props.plain, - }, - // Help Text Button - { 'text-purple-500 dark:text-purple-400': props.text && props.severity === 'help' && !props.plain }, - // Help Outlined Button - { 'text-purple-500 border border-purple-500 hover:bg-purple-300/20': props.outlined && props.severity === 'help' && !props.plain }, - - // Danger Button - { - 'text-white dark:text-surface-900': props.severity === 'danger' && !props.text && !props.outlined && !props.plain, - 'bg-red-500 dark:bg-red-400': props.severity === 'danger' && !props.text && !props.outlined && !props.plain, - 'border border-red-500 dark:border-red-400': props.severity === 'danger' && !props.text && !props.outlined && !props.plain, - }, - // Danger Text Button - { 'text-red-500 dark:text-red-400': props.text && props.severity === 'danger' && !props.plain }, - // Danger Outlined Button - { 'text-red-500 border border-red-500 hover:bg-red-300/20': props.outlined && props.severity === 'danger' && !props.plain }, - - // --- Severity Button States --- - 'focus:outline-none focus:outline-offset-0 focus:ring', - - // Link - { 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50': props.link }, - - // Plain - { 'hover:bg-gray-600 hover:border-gray-600': props.plain && !props.outlined && !props.text }, - // Text & Outlined Button - { 'hover:bg-surface-300/20': props.plain && (props.text || props.outlined) }, - - // Primary - { 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50': props.severity === null }, - // Text & Outlined Button - { 'hover:bg-primary-300/20': (props.text || props.outlined) && props.severity === null && !props.plain }, - - // Secondary - { 'hover:bg-surface-600 dark:hover:bg-surface-300 hover:border-surface-600 dark:hover:border-surface-300': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-surface-400/50 dark:focus:ring-surface-300/50': props.severity === 'secondary' }, - // Text & Outlined Button - { 'hover:bg-surface-300/20': (props.text || props.outlined) && props.severity === 'secondary' && !props.plain }, - - // Success - { 'hover:bg-green-600 dark:hover:bg-green-300 hover:border-green-600 dark:hover:border-green-300': props.severity === 'success' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-green-400/50 dark:focus:ring-green-300/50': props.severity === 'success' }, - // Text & Outlined Button - { 'hover:bg-green-300/20': (props.text || props.outlined) && props.severity === 'success' && !props.plain }, - - // Info - { 'hover:bg-blue-600 dark:hover:bg-blue-300 hover:border-blue-600 dark:hover:border-blue-300': props.severity === 'info' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-blue-400/50 dark:focus:ring-blue-300/50': props.severity === 'info' }, - // Text & Outlined Button - { 'hover:bg-blue-300/20': (props.text || props.outlined) && props.severity === 'info' && !props.plain }, - - // Warning - { 'hover:bg-orange-600 dark:hover:bg-orange-300 hover:border-orange-600 dark:hover:border-orange-300': props.severity === 'warning' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-orange-400/50 dark:focus:ring-orange-300/50': props.severity === 'warning' }, - // Text & Outlined Button - { 'hover:bg-orange-300/20': (props.text || props.outlined) && props.severity === 'warning' && !props.plain }, - - // Help - { 'hover:bg-purple-600 dark:hover:bg-purple-300 hover:border-purple-600 dark:hover:border-purple-300': props.severity === 'help' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-purple-400/50 dark:focus:ring-purple-300/50': props.severity === 'help' }, - // Text & Outlined Button - { 'hover:bg-purple-300/20': (props.text || props.outlined) && props.severity === 'help' && !props.plain }, - - // Danger - { 'hover:bg-red-600 dark:hover:bg-red-300 hover:border-red-600 dark:hover:border-red-300': props.severity === 'danger' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-red-400/50 dark:focus:ring-red-300/50': props.severity === 'danger' }, - // Text & Outlined Button - { 'hover:bg-red-300/20': (props.text || props.outlined) && props.severity === 'danger' && !props.plain }, - - // Disabled - { 'opacity-60 pointer-events-none cursor-default': context.disabled }, - - // Transitions - 'transition duration-200 ease-in-out', - - // Misc - 'cursor-pointer overflow-hidden select-none', - ], - }), - label: ({ props }) => ({ - class: [ - 'duration-200', - 'font-bold', - { - 'hover:underline': props.link, - }, - { 'flex-1': props.label !== null, 'invisible w-0': props.label == null }, - ], - }), - icon: ({ props }) => ({ - class: [ - 'mx-0', - { - 'mr-2': props.iconPos == 'left' && props.label != null, - 'ml-2 order-1': props.iconPos == 'right' && props.label != null, - 'mb-2': props.iconPos == 'top' && props.label != null, - 'mt-2': props.iconPos == 'bottom' && props.label != null, - }, - ], - }), - loadingicon: ({ props }) => ({ - class: [ - 'h-4 w-4', - 'mx-0', - { - 'mr-2': props.iconPos == 'left' && props.label != null, - 'ml-2 order-1': props.iconPos == 'right' && props.label != null, - 'mb-2': props.iconPos == 'top' && props.label != null, - 'mt-2': props.iconPos == 'bottom' && props.label != null, - }, - 'animate-spin', - ], - }), - badge: ({ props }) => ({ - class: [{ 'ml-2 w-4 h-4 leading-none flex items-center justify-center': props.badge }], - }), + root: ({ props, context, parent }) => ({ + class: [ + 'relative', + + // Alignments + 'items-center inline-flex text-center align-bottom justify-center', + { 'flex-col': (props.iconPos === 'top' || props.iconPos === 'bottom') && props.label }, + + // Sizes & Spacing + 'leading-[normal]', + { + 'px-4 py-[0.625rem]': props.size === null, + 'text-sm py-2 px-3': props.size === 'small', + 'text-xl py-3 px-4': props.size === 'large' + }, + { 'gap-2': props.label !== null }, + { + 'w-12 px-0 py-3': props.label == null && props.icon !== null + }, + + // Shapes + { 'shadow-lg': props.raised }, + { 'rounded-md': !props.rounded, 'rounded-full': props.rounded }, + { 'rounded-none first:rounded-l-md last:rounded-r-md': parent.instance.$name == 'InputGroup' }, + + // Link Button + { 'text-primary-600 bg-transparent border-transparent': props.link }, + + // Plain Button + { 'text-white bg-gray-500 border border-gray-500': props.plain && !props.outlined && !props.text }, + // Plain Text Button + { 'text-surface-500': props.plain && props.text }, + // Plain Outlined Button + { 'text-surface-500 border border-gray-500': props.plain && props.outlined }, + + // Text Button + { 'bg-transparent border-transparent': props.text && !props.plain }, + + // Outlined Button + { 'bg-transparent border': props.outlined && !props.plain }, + + // --- Severity Buttons --- + + // Primary Button + { + 'text-primary-contrast': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain, + 'bg-primary': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain, + 'border border-primary': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain + }, + // Primary Text Button + { 'text-primary': props.text && props.severity === null && !props.plain }, + // Primary Outlined Button + { 'text-primary border border-primary': props.outlined && props.severity === null && !props.plain }, + + // Secondary Button + { + 'text-white dark:text-surface-900': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain, + 'bg-surface-500 dark:bg-surface-400': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain, + 'border border-surface-500 dark:border-surface-400': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain + }, + // Secondary Text Button + { 'text-surface-500 dark:text-surface-300': props.text && props.severity === 'secondary' && !props.plain }, + // Secondary Outlined Button + { 'text-surface-500 dark:text-surface-300 border border-surface-500 hover:bg-surface-300/20': props.outlined && props.severity === 'secondary' && !props.plain }, + + // Success Button + { + 'text-white dark:text-green-900': props.severity === 'success' && !props.text && !props.outlined && !props.plain, + 'bg-green-500 dark:bg-green-400': props.severity === 'success' && !props.text && !props.outlined && !props.plain, + 'border border-green-500 dark:border-green-400': props.severity === 'success' && !props.text && !props.outlined && !props.plain + }, + // Success Text Button + { 'text-green-500 dark:text-green-400': props.text && props.severity === 'success' && !props.plain }, + // Success Outlined Button + { 'text-green-500 border border-green-500 hover:bg-green-300/20': props.outlined && props.severity === 'success' && !props.plain }, + + // Info Button + { + 'text-white dark:text-surface-900': props.severity === 'info' && !props.text && !props.outlined && !props.plain, + 'bg-blue-500 dark:bg-blue-400': props.severity === 'info' && !props.text && !props.outlined && !props.plain, + 'border border-blue-500 dark:border-blue-400': props.severity === 'info' && !props.text && !props.outlined && !props.plain + }, + // Info Text Button + { 'text-blue-500 dark:text-blue-400': props.text && props.severity === 'info' && !props.plain }, + // Info Outlined Button + { 'text-blue-500 border border-blue-500 hover:bg-blue-300/20 ': props.outlined && props.severity === 'info' && !props.plain }, + + // Warning Button + { + 'text-white dark:text-surface-900': props.severity === 'warn' && !props.text && !props.outlined && !props.plain, + 'bg-orange-500 dark:bg-orange-400': props.severity === 'warn' && !props.text && !props.outlined && !props.plain, + 'border border-orange-500 dark:border-orange-400': props.severity === 'warn' && !props.text && !props.outlined && !props.plain + }, + // Warning Text Button + { 'text-orange-500 dark:text-orange-400': props.text && props.severity === 'warn' && !props.plain }, + // Warning Outlined Button + { 'text-orange-500 border border-orange-500 hover:bg-orange-300/20': props.outlined && props.severity === 'warn' && !props.plain }, + + // Help Button + { + 'text-white dark:text-surface-900': props.severity === 'help' && !props.text && !props.outlined && !props.plain, + 'bg-purple-500 dark:bg-purple-400': props.severity === 'help' && !props.text && !props.outlined && !props.plain, + 'border border-purple-500 dark:border-purple-400': props.severity === 'help' && !props.text && !props.outlined && !props.plain + }, + // Help Text Button + { 'text-purple-500 dark:text-purple-400': props.text && props.severity === 'help' && !props.plain }, + // Help Outlined Button + { 'text-purple-500 border border-purple-500 hover:bg-purple-300/20': props.outlined && props.severity === 'help' && !props.plain }, + + // Danger Button + { + 'text-white dark:text-surface-900': props.severity === 'danger' && !props.text && !props.outlined && !props.plain, + 'bg-red-500 dark:bg-red-400': props.severity === 'danger' && !props.text && !props.outlined && !props.plain, + 'border border-red-500 dark:border-red-400': props.severity === 'danger' && !props.text && !props.outlined && !props.plain + }, + // Danger Text Button + { 'text-red-500 dark:text-red-400': props.text && props.severity === 'danger' && !props.plain }, + // Danger Outlined Button + { 'text-red-500 border border-red-500 hover:bg-red-300/20': props.outlined && props.severity === 'danger' && !props.plain }, + // Contrast Button + { + 'text-white dark:text-surface-900': props.severity === 'contrast' && !props.text && !props.outlined && !props.plain, + 'bg-surface-900 dark:bg-surface-0': props.severity === 'contrast' && !props.text && !props.outlined && !props.plain, + 'border border-surface-900 dark:border-surface-0': props.severity === 'contrast' && !props.text && !props.outlined && !props.plain + }, + // Contrast Text Button + { 'text-surface-900 dark:text-surface-0': props.text && props.severity === 'contrast' && !props.plain }, + // Contrast Outlined Button + { 'text-surface-900 dark:text-surface-0 border border-surface-900 dark:border-surface-0': props.outlined && props.severity === 'contrast' && !props.plain }, + + // --- Severity Button States --- + 'focus:outline-none focus:outline-offset-0 focus:ring', + + // Link + { 'focus:ring-primary': props.link }, + + // Plain + { 'hover:bg-gray-600 hover:border-gray-600': props.plain && !props.outlined && !props.text }, + // Text & Outlined Button + { 'hover:bg-surface-300/20': props.plain && (props.text || props.outlined) }, + + // Primary + { 'hover:bg-primary-emphasis hover:border-primary-emphasis': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain }, + { 'focus:ring-primary': props.severity === null }, + // Text & Outlined Button + { 'hover:bg-primary-300/20': (props.text || props.outlined) && props.severity === null && !props.plain }, + + // Secondary + { 'hover:bg-surface-600 dark:hover:bg-surface-300 hover:border-surface-600 dark:hover:border-surface-300': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain }, + { 'focus:ring-surface-400/50 dark:focus:ring-surface-300/50': props.severity === 'secondary' }, + // Text & Outlined Button + { 'hover:bg-surface-300/20': (props.text || props.outlined) && props.severity === 'secondary' && !props.plain }, + + // Success + { 'hover:bg-green-600 dark:hover:bg-green-300 hover:border-green-600 dark:hover:border-green-300': props.severity === 'success' && !props.text && !props.outlined && !props.plain }, + { 'focus:ring-green-400/50 dark:focus:ring-green-300/50': props.severity === 'success' }, + // Text & Outlined Button + { 'hover:bg-green-300/20': (props.text || props.outlined) && props.severity === 'success' && !props.plain }, + + // Info + { 'hover:bg-blue-600 dark:hover:bg-blue-300 hover:border-blue-600 dark:hover:border-blue-300': props.severity === 'info' && !props.text && !props.outlined && !props.plain }, + { 'focus:ring-blue-400/50 dark:focus:ring-blue-300/50': props.severity === 'info' }, + // Text & Outlined Button + { 'hover:bg-blue-300/20': (props.text || props.outlined) && props.severity === 'info' && !props.plain }, + + // Warning + { 'hover:bg-orange-600 dark:hover:bg-orange-300 hover:border-orange-600 dark:hover:border-orange-300': props.severity === 'warn' && !props.text && !props.outlined && !props.plain }, + { 'focus:ring-orange-400/50 dark:focus:ring-orange-300/50': props.severity === 'warn' }, + // Text & Outlined Button + { 'hover:bg-orange-300/20': (props.text || props.outlined) && props.severity === 'warn' && !props.plain }, + + // Help + { 'hover:bg-purple-600 dark:hover:bg-purple-300 hover:border-purple-600 dark:hover:border-purple-300': props.severity === 'help' && !props.text && !props.outlined && !props.plain }, + { 'focus:ring-purple-400/50 dark:focus:ring-purple-300/50': props.severity === 'help' }, + // Text & Outlined Button + { 'hover:bg-purple-300/20': (props.text || props.outlined) && props.severity === 'help' && !props.plain }, + + // Danger + { 'hover:bg-red-600 dark:hover:bg-red-300 hover:border-red-600 dark:hover:border-red-300': props.severity === 'danger' && !props.text && !props.outlined && !props.plain }, + { 'focus:ring-red-400/50 dark:focus:ring-red-300/50': props.severity === 'danger' }, + // Text & Outlined Button + { 'hover:bg-red-300/20': (props.text || props.outlined) && props.severity === 'danger' && !props.plain }, + // Contrast + { 'hover:bg-surface-800 dark:hover:bg-surface-100 hover:border-surface-800 dark:hover:border-surface-100': props.severity === 'contrast' && !props.text && !props.outlined && !props.plain }, + { 'focus:ring-surface-500 dark:focus:ring-surface-400': props.severity === 'contrast' }, + // Text & Outlined Button + { 'hover:bg-surface-900/10 dark:hover:bg-[rgba(255,255,255,0.03)]': (props.text || props.outlined) && props.severity === 'contrast' && !props.plain }, + // Disabled + { 'opacity-60 pointer-events-none cursor-default': context.disabled }, + + // Transitions + 'transition duration-200 ease-in-out', + + // Misc + 'cursor-pointer overflow-hidden select-none', + + // Badge + '[&>[data-pc-name=badge]]:min-w-4 [&>[data-pc-name=badge]]:h-4 [&>[data-pc-name=badge]]:leading-4' + ] + }), + label: ({ props }) => ({ + class: [ + 'duration-200', + 'font-bold', + { + 'hover:underline': props.link + }, + { 'flex-1': props.label !== null, 'invisible w-0': props.label == null } + ] + }), + icon: ({ props }) => ({ + class: [ + 'mx-0', + { + 'mr-2': props.iconPos == 'left' && props.label != null, + 'ml-2 order-1': props.iconPos == 'right' && props.label != null, + 'order-2': props.iconPos == 'bottom' && props.label != null + } + ] + }), + loadingIcon: ({ props }) => ({ + class: [ + 'h-4 w-4', + 'mx-0', + { + 'mr-2': props.iconPos == 'left' && props.label != null, + 'ml-2 order-1': props.iconPos == 'right' && props.label != null, + 'mb-2': props.iconPos == 'top' && props.label != null, + 'mt-2': props.iconPos == 'bottom' && props.label != null + }, + 'animate-spin' + ] + }), + badge: ({ props }) => ({ + class: [{ 'ml-2 w-4 h-4 leading-none flex items-center justify-center': props.badge }] + }) }; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/carousel/index.js b/frontend/packages/kwai-ui/src/presets/kwai/carousel/index.js index e0386283..9fc3396d 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/carousel/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/carousel/index.js @@ -5,13 +5,13 @@ export default { 'flex flex-col' ] }, - content: { + contentContainer: { class: [ // Flexbox & Overflow 'flex flex-col overflow-auto' ] }, - container: ({ props }) => ({ + content: ({ props }) => ({ class: [ // Flexbox 'flex', @@ -20,64 +20,18 @@ export default { { 'flex-row': props.orientation !== 'vertical', 'flex-col': props.orientation == 'vertical' - } + }, + , + '[&>[data-pc-extend=button]]:self-center' ] }), - previousbutton: { - class: [ - // Flexbox & Alignment - 'flex justify-center items-center self-center', - - // Sizing & Overflow - 'overflow-hidden w-8 h-8', - - // Spacing - 'mx-2', - - // Shape - 'rounded-full', - - // Border & Background - 'border-0 bg-transparent', - - // Color - 'text-surface-600', - - // Transitions - 'transition duration-200 ease-in-out' - ] - }, - nextbutton: { - class: [ - // Flexbox & Alignment - 'flex justify-center items-center self-center', - - // Sizing & Overflow - 'overflow-hidden w-8 h-8', - - // Spacing - 'mx-2', - - // Shape - 'rounded-full', - - // Border & Background - 'border-0 bg-transparent', - - // Color - 'text-surface-600', - - // Transitions - 'transition duration-200 ease-in-out' - ] - }, - itemscontent: { + viewport: { class: [ // Overflow & Width 'overflow-hidden w-full' ] }, - itemscontainer: ({ props }) => ({ + itemList: ({ props }) => ({ class: [ // Flexbox 'flex', @@ -102,7 +56,7 @@ export default { } ] }), - itemcloned: ({ props }) => ({ + itemClone: ({ props }) => ({ class: [ // Flexbox 'flex shrink-0 grow', @@ -116,7 +70,7 @@ export default { } ] }), - indicators: { + indicatorList: { class: [ // Flexbox & Alignment 'flex flex-row justify-center flex-wrap' @@ -128,7 +82,7 @@ export default { 'mr-2 mb-2' ] }, - indicatorbutton: ({ context }) => ({ + indicatorButton: ({ context }) => ({ class: [ // Sizing & Shape 'w-8 h-2 rounded-0', @@ -142,7 +96,7 @@ export default { // Color & Background { 'bg-surface-200 hover:bg-surface-300 dark:bg-surface-700 dark:hover:bg-surface-600': !context.highlighted, - 'bg-primary-500 hover:bg-primary-600': context.highlighted + 'bg-primary hover:bg-primary-emphasis': context.highlighted } ] }) diff --git a/frontend/packages/kwai-ui/src/presets/kwai/cascadeselect/index.js b/frontend/packages/kwai-ui/src/presets/kwai/cascadeselect/index.js index e51adb2b..97fc8e4a 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/cascadeselect/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/cascadeselect/index.js @@ -1,10 +1,14 @@ export default { root: ({ props, state }) => ({ class: [ - // Display and Position - 'inline-flex', 'relative', + // Flex + { + flex: props.fluid, + 'inline-flex': !props.fluid + }, + // Shape 'rounded-md', @@ -21,7 +25,7 @@ export default { 'duration-200', // States - { 'hover:border-primary-500 dark:hover:border-primary-300': !props.invalid }, + { 'hover:border-primary': !props.invalid }, { 'outline-none outline-offset-0 ring ring-primary-400/50 dark:ring-primary-300/50': state.focused }, // Misc @@ -33,8 +37,7 @@ export default { label: ({ props }) => ({ class: [ //Font - 'font-sans', - 'leading-none', + 'leading-[normal]', // Flex & Alignment ' flex flex-auto', @@ -67,7 +70,7 @@ export default { 'appearance-none' ] }), - dropdownbutton: { + dropdown: { class: [ // Flexbox 'flex items-center justify-center', @@ -85,7 +88,7 @@ export default { 'rounded-br-md' ] }, - panel: { + overlay: { class: [ // Position 'absolute top-0 left-0', @@ -101,19 +104,10 @@ export default { 'dark:border-surface-700' ] }, - wrapper: { - class: [ - // Sizing - 'max-h-[200px]', - - // Misc - 'overflow-auto' - ] - }, list: { - class: 'py-3 list-none m-0' + class: 'flex flex-col list-none p-0 m-0 gap-[2px] min-w-full' }, - item: ({ context }) => ({ + option: ({ context }) => ({ class: [ // Font 'font-normal', @@ -130,14 +124,13 @@ export default { { 'text-surface-500 dark:text-white/70': !context.focused && !context.active, 'text-surface-500 dark:text-white/70 bg-surface-200 dark:bg-surface-600/90': context.focused && !context.active, - 'text-primary-700 dark:text-surface-0/80 bg-primary-50 dark:bg-primary-400/30': context.focused && context.active, - 'text-primary-700 dark:text-surface-0/80 bg-primary-50 dark:bg-primary-400/30': !context.focused && context.active + 'bg-highlight': (context.focused && context.active) || context.active || (!context.focused && context.active) }, // Hover States { 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context.active, - 'hover:bg-primary-500/50 dark:hover:bg-primary-300/30 text-primary-700 dark:text-surface-0/80': context.active + 'hover:bg-highlight-emphasis': context.active }, // Transitions @@ -150,7 +143,7 @@ export default { 'whitespace-nowrap' ] }), - content: { + optionContent: { class: [ 'relative', @@ -169,16 +162,16 @@ export default { 'select-none' ] }, - groupicon: { + groupIcon: { class: [ // Alignment 'ml-auto' ] }, - sublist: { + optionList: { class: [ // Size - 'w-full', + 'min-w-full', // Spacing 'py-1', @@ -197,9 +190,6 @@ export default { 'bg-surface-0 dark:bg-surface-700' ] }, - separator: { - class: 'border-t border-surface-200 dark:border-surface-600 my-1' - }, transition: { enterFromClass: 'opacity-0 scale-y-[0.8]', enterActiveClass: 'transition-[transform,opacity] duration-[120ms] ease-[cubic-bezier(0,0,0.2,1)]', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/checkbox/index.js b/frontend/packages/kwai-ui/src/presets/kwai/checkbox/index.js index 58f52949..bc30fd06 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/checkbox/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/checkbox/index.js @@ -34,7 +34,7 @@ export default { // Colors { 'border-surface-200 bg-surface-0 dark:border-surface-700 dark:bg-surface-900': !context.checked && !props.invalid, - 'border-primary-500 bg-primary-500 dark:border-primary-400 dark:bg-primary-400': context.checked + 'border-primary bg-primary': context.checked }, // Invalid State @@ -42,8 +42,8 @@ export default { // States { - 'peer-hover:border-primary-500 dark:peer-hover:border-primary-400': !props.disabled && !context.checked && !props.invalid, - 'peer-hover:bg-primary-600 dark:peer-hover:bg-primary-300 peer-hover:border-primary-700 dark:peer-hover:border-primary-300': !props.disabled && context.checked, + 'peer-hover:border-primary': !props.disabled && !context.checked && !props.invalid, + 'peer-hover:bg-primary-emphasis peer-hover:border-primary-emphasis': !props.disabled && context.checked, 'peer-focus-visible:border-primary-500 dark:peer-focus-visible:border-primary-400 peer-focus-visible:ring-2 peer-focus-visible:ring-primary-400/20 dark:peer-focus-visible:ring-primary-300/20': !props.disabled, 'cursor-default opacity-60': props.disabled }, @@ -81,7 +81,7 @@ export default { 'cursor-pointer' ] }, - icon: { + icon: ({ state, context }) => ({ class: [ // Font 'text-base leading-none', @@ -91,11 +91,14 @@ export default { 'h-4', // Colors - 'text-white dark:text-surface-900', + { + 'text-white dark:text-surface-900': context.checked, + 'text-primary': state.d_indeterminate + }, // Transitions 'transition-all', 'duration-200' ] - } + }) }; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/chip/index.js b/frontend/packages/kwai-ui/src/presets/kwai/chip/index.js index c6ff8795..769c7f3c 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/chip/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/chip/index.js @@ -5,10 +5,10 @@ export default { 'inline-flex items-center', // Spacing - 'px-3', + 'px-3 gap-2', // Shape - 'rounded-[1.14rem]', + 'rounded-[16px]', // Colors 'text-surface-700 dark:text-white/70', @@ -29,9 +29,6 @@ export default { // Shape 'rounded-md leading-6', - // Spacing - 'ml-2', - // Size 'w-4 h-4', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/colorpicker/index.js b/frontend/packages/kwai-ui/src/presets/kwai/colorpicker/index.js index 4b22e21c..b31bb8b0 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/colorpicker/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/colorpicker/index.js @@ -8,10 +8,10 @@ export default { { 'opacity-60 select-none pointer-events-none cursor-default': props.disabled } ] }), - input: { + preview: { class: [ // Font - 'font-sans text-base ', + 'text-base ', // Spacing 'm-0', @@ -25,7 +25,7 @@ export default { 'border border-surface-300 dark:border-surface-700', // States - 'hover:border-primary-500 dark:hover:border-primary-400', + 'hover:border-primary', 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50', // Transition @@ -50,7 +50,7 @@ export default { 'bg-surface-800 border-surface-900 dark:border-surface-600' ] }), - selector: { + colorSelector: { class: [ // Position 'absolute top-[8px] left-[8px]', @@ -66,7 +66,7 @@ export default { ], style: 'background: linear-gradient(to top, #000 0%, rgb(0 0 0 / 0) 100%), linear-gradient(to right, #fff 0%, rgb(255 255 255 / 0) 100%)' }, - colorhandle: { + colorHandle: { class: [ 'absolute', @@ -99,7 +99,7 @@ export default { ], style: 'background: linear-gradient(0deg, red 0, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, red)' }, - huehandle: { + hueHandle: { class: [ // Position 'absolute left-0 -ml-[2px] -mt-[5px]', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/confirmpopup/index.js b/frontend/packages/kwai-ui/src/presets/kwai/confirmpopup/index.js index cef7ad32..0ab049cc 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/confirmpopup/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/confirmpopup/index.js @@ -47,56 +47,6 @@ export default { 'text-surface-700 dark:text-surface-0/80' ] }, - rejectbutton: { - root: { - class: [ - 'relative', - - // Alignments - 'items-center inline-flex text-center align-bottom justify-center', - - // Sizes & Spacing - 'px-4 py-3 leading-none', - - // Shape - 'rounded-md', - - // Color - 'text-primary-500 dark:text-primary-400', - - // States - 'hover:bg-primary-300/20', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50' - ] - } - }, - acceptbutton: { - root: { - class: [ - 'relative', - - // Alignments - 'items-center inline-flex text-center align-bottom justify-center', - - // Sizes & Spacing - 'px-4 py-3 leading-none', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // States - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50' - ] - } - }, transition: { enterFromClass: 'opacity-0 scale-y-[0.8]', enterActiveClass: 'transition-[transform,opacity] duration-[120ms] ease-[cubic-bezier(0,0,0.2,1)]', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/contextmenu/index.js b/frontend/packages/kwai-ui/src/presets/kwai/contextmenu/index.js index 2e7ae274..1c8c27f7 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/contextmenu/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/contextmenu/index.js @@ -15,19 +15,20 @@ export default { 'dark:border dark:border-surface-700' ] }, - menu: { + rootList: { class: [ // Spacings and Shape + 'flex flex-col', 'list-none', 'm-0', 'p-0', 'outline-none' ] }, - menuitem: { + item: { class: 'relative' }, - content: ({ context }) => ({ + itemContent: ({ context }) => ({ class: [ //Shape 'rounded-none', @@ -36,8 +37,7 @@ export default { { 'text-surface-500 dark:text-white/70': !context.focused && !context.active, 'text-surface-500 dark:text-white/70 bg-surface-200 dark:bg-surface-600/90': context.focused && !context.active, - 'text-primary-700 dark:text-surface-0/80 bg-primary-50 dark:bg-primary-400/30': context.focused && context.active, - 'text-primary-700 dark:text-surface-0/80 bg-primary-50 dark:bg-primary-400/30': !context.focused && context.active + 'bg-highlight': (context.focused && context.active) || context.active || (!context.focused && context.active) }, // Transitions @@ -47,14 +47,14 @@ export default { // States { 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context.active, - 'hover:bg-primary-400/30 dark:hover:bg-primary-300/30 text-primary-700 dark:text-surface-0/80': context.active + 'hover:bg-highlight-emphasis': context.active }, // Disabled { 'opacity-60 pointer-events-none cursor-default': context.disabled } ] }), - action: { + itemLink: { class: [ 'relative', // Flexbox @@ -76,7 +76,7 @@ export default { 'select-none' ] }, - icon: { + itemIcon: { class: [ // Spacing 'mr-2', @@ -85,11 +85,12 @@ export default { 'text-surface-600 dark:text-white/70' ] }, - label: { + itemLabel: { class: ['leading-none'] }, submenu: ({ props }) => ({ class: [ + 'flex flex-col', // Size 'w-full sm:w-48', @@ -112,7 +113,7 @@ export default { 'bg-surface-0 dark:bg-surface-700' ] }), - submenuicon: { + submenuIcon: { class: ['ml-auto'] }, separator: { diff --git a/frontend/packages/kwai-ui/src/presets/kwai/datatable/index.js b/frontend/packages/kwai-ui/src/presets/kwai/datatable/index.js index 2c2860f0..9bb574f6 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/datatable/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/datatable/index.js @@ -10,7 +10,7 @@ export default { { 'h-full': props.scrollable && props.scrollHeight === 'flex' } ] }), - loadingoverlay: { + mask: { class: [ // Position 'absolute', @@ -30,10 +30,10 @@ export default { 'transition duration-200' ] }, - loadingicon: { + loadingIcon: { class: 'w-8 h-8 animate-spin' }, - wrapper: ({ props }) => ({ + tableContainer: ({ props }) => ({ class: [ { relative: props.scrollable, 'flex flex-col grow': props.scrollable && props.scrollHeight === 'flex' }, @@ -63,7 +63,7 @@ export default { thead: ({ context }) => ({ class: [ { - 'bg-surface-50 top-0 z-40 sticky': context.scrollable + 'bg-surface-50 dark:bg-surface-800 top-0 z-40 sticky': context.scrollable } ] }), @@ -71,7 +71,8 @@ export default { class: [ { 'sticky z-20': instance.frozenRow && context.scrollable - } + }, + 'bg-surface-50 dark:bg-surface-800' ] }), tfoot: ({ context }) => ({ @@ -98,7 +99,7 @@ export default { ] }, column: { - headercell: ({ context, props }) => ({ + headerCell: ({ context, props }) => ({ class: [ 'font-bold', @@ -118,8 +119,7 @@ export default { context?.size === 'small' ? 'p-2' : context?.size === 'large' ? 'p-5' : 'p-4', // Color - (props.sortable === '' || props.sortable) && context.sorted ? 'bg-primary-50 text-primary-700' : 'bg-surface-50 text-surface-700', - (props.sortable === '' || props.sortable) && context.sorted ? 'dark:text-white dark:bg-primary-400/30' : 'dark:text-white/80 dark:bg-surface-800', + (props.sortable === '' || props.sortable) && context.sorted ? 'bg-highlight' : 'bg-surface-50 text-surface-700 dark:text-white/80 dark:bg-surface-800', 'border-surface-200 dark:border-surface-700 ', // States @@ -136,17 +136,17 @@ export default { } ] }), - headercontent: { + columnHeaderContent: { class: 'flex items-center' }, sort: ({ context }) => ({ class: [context.sorted ? 'text-primary-500' : 'text-surface-700', context.sorted ? 'dark:text-primary-400' : 'dark:text-white/80'] }), - bodycell: ({ props, context, state, parent }) => ({ + bodyCell: ({ props, context, state, parent }) => ({ class: [ //Position { 'sticky box-border border-b': parent.instance.frozenRow }, - { 'sticky box-border border-b': props.frozen || props.frozen === '' }, + { 'sticky box-border border-b z-20': props.frozen || props.frozen === '' }, // Alignment 'text-left', @@ -163,10 +163,14 @@ export default { { 'py-[0.6rem] px-2': state['d_editing'] }, // Color - 'border-surface-200 dark:border-surface-700' + 'border-surface-200 dark:border-surface-700', + + { + 'overflow-hidden whitespace-nowrap border-y bg-clip-padding': parent.instance?.$parentInstance?.$parentInstance?.resizableColumns // Resizable + } ] }), - footercell: ({ context }) => ({ + footerCell: ({ context }) => ({ class: [ // Font 'font-bold', @@ -187,32 +191,13 @@ export default { 'bg-surface-50 dark:bg-surface-800' ] }), - sorticon: ({ context }) => ({ - class: ['ml-2', context.sorted ? 'text-primary-700 dark:text-white/80' : 'text-surface-700 dark:text-white/70'] + sortIcon: ({ context }) => ({ + class: ['ml-2', context.sorted ? 'text-inherit' : 'text-surface-700 dark:text-white/70'] }), - sortbadge: { - class: [ - // Flex & Alignment - 'flex items-center justify-center align-middle', - - // Shape - 'rounded-full', - - // Size - 'w-[1.143rem] leading-[1.143rem]', - - // Spacing - 'ml-2', - - // Color - 'text-primary-700 dark:text-white', - 'bg-primary-50 dark:bg-primary-400/30' - ] - }, - columnfilter: { + columnFilter: { class: 'inline-flex items-center ml-auto' }, - filteroverlay: { + filterOverlay: { class: [ // Position 'absolute top-0 left-0', @@ -231,44 +216,10 @@ export default { 'dark:border-surface-700' ] }, - filtermatchmodedropdown: { - root: ({ state }) => ({ - class: [ - // Display and Position - 'flex', - 'relative', - - // Spacing - 'my-2', - - // Shape - 'w-full', - 'rounded-md', - - // Color and Background - 'bg-surface-0 dark:bg-surface-900', - 'border border-surface-300 dark:border-surface-700', - 'text-surface-800 dark:text-white/80', - 'placeholder:text-surface-400 dark:placeholder:text-surface-500', - - // Transitions - 'transition-all', - 'duration-200', - - // States - 'hover:border-primary-500 dark:hover:border-primary-300', - { 'outline-none outline-offset-0 ring ring-primary-400/50 dark:ring-primary-300/50': state.focused }, - - // Misc - 'cursor-pointer', - 'select-none' - ] - }) - }, - filterrowitems: { + filterConstraintList: { class: 'm-0 p-0 py-3 list-none' }, - filterrowitem: ({ context }) => ({ + filterConstraint: ({ context }) => ({ class: [ // Font 'font-normal', @@ -286,10 +237,8 @@ export default { 'py-3 px-5', // Color - { 'text-surface-700 dark:text-white/80': !context?.highlighted }, { 'bg-surface-0 dark:bg-surface-800 text-surface-700 dark:text-white/80': !context?.highlighted }, - { 'bg-primary-100 dark:bg-primary-400/40 text-primary-700 dark:text-white/80': context?.highlighted }, - { 'bg-primary-50 dark:bg-primary-400/40 text-primary-700 dark:text-white/80': context?.highlighted }, + { 'bg-highlight': context?.highlighted }, //States { 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context?.highlighted }, @@ -306,11 +255,8 @@ export default { 'whitespace-nowrap' ] }), - filteroperator: { + filterOperator: { class: [ - // Spacing - 'px-5 py-3', - // Shape 'border-b border-solid', 'rounded-t-md', @@ -318,341 +264,18 @@ export default { // Color 'text-surface-700 dark:text-white/80', 'border-surface-200 dark:border-surface-800', - 'bg-surface-0 dark:bg-surface-700' - ] - }, - filteroperatordropdown: { - root: ({ state }) => ({ - class: [ - // Display and Position - 'inline-flex', - 'relative', - - // Shape - 'w-full', - 'rounded-md', - - // Color and Background - 'bg-surface-0 dark:bg-surface-900', - 'border border-surface-300 dark:border-surface-700', - - // Transitions - 'transition-all', - 'duration-200', - - // States - 'hover:border-primary-500 dark:hover:border-primary-300', - { 'outline-none outline-offset-0 ring ring-primary-400/50 dark:ring-primary-300/50': state.focused }, - - // Misc - 'cursor-pointer', - 'select-none' - ] - }), - input: ({ props }) => ({ - class: [ - //Font - 'font-sans', - 'leading-none', - - // Display - 'block', - 'flex-auto', - - // Color and Background - 'bg-transparent', - 'border-0', - { 'text-surface-800 dark:text-white/80': props.modelValue, 'text-surface-400 dark:text-surface-500': !props.modelValue }, - 'placeholder:text-surface-400 dark:placeholder:text-surface-500', - - // Sizing and Spacing - 'w-[1%]', - 'p-3', - - //Shape - 'rounded-none', - - // Transitions - 'transition', - 'duration-200', - - // States - 'focus:outline-none focus:shadow-none', - - // Misc - 'relative', - 'cursor-pointer', - 'overflow-hidden overflow-ellipsis', - 'whitespace-nowrap', - 'appearance-none' - ] - }), - trigger: { - class: [ - // Flexbox - 'flex items-center justify-center', - 'shrink-0', - - // Color and Background - 'bg-transparent', - 'text-surface-500', - - // Size - 'w-12', - - // Shape - 'rounded-tr-md', - 'rounded-br-md' - ] - }, - panel: { - class: [ - // Position - 'absolute top-0 left-0', - - // Shape - 'border-0 dark:border', - 'rounded-md', - 'shadow-md', - - // Color - 'bg-surface-0 dark:bg-surface-800', - 'text-surface-800 dark:text-white/80', - 'dark:border-surface-700' - ] - }, - item: ({ context }) => ({ - class: [ - // Font - 'font-normal', - 'leading-none', - - // Position - 'relative', - - // Shape - 'border-0', - 'rounded-none', - - // Spacing - 'm-0', - 'py-3 px-5', - - // Color - { 'text-surface-700 dark:text-white/80': !context.focused && !context.selected }, - { 'bg-surface-50 dark:bg-surface-600/60 text-surface-700 dark:text-white/80': context.focused && !context.selected }, - { 'bg-primary-100 dark:bg-primary-400/40 text-primary-700 dark:text-white/80': context.focused && context.selected }, - { 'bg-primary-50 dark:bg-primary-400/40 text-primary-700 dark:text-white/80': !context.focused && context.selected }, - - //States - { 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context.focused && !context.selected }, - { 'hover:text-surface-700 hover:bg-surface-100 dark:hover:text-white dark:hover:bg-surface-600/80': context.focused && !context.selected }, - - // Transitions - 'transition-shadow', - 'duration-200', - - // Misc - 'cursor-pointer', - 'overflow-hidden', - 'whitespace-nowrap' - ] - }) - }, - filterconstraint: { - class: [ - // Spacing - 'py-3 px-5', - - // Shape - 'border-b border-solid', - - // Color - 'border-surface-200 dark:border-surface-700' - ] - }, - filteraddrule: { - class: 'py-3 px-5' - }, - filteraddrulebutton: { - root: { - class: [ - 'relative', - - // Alignments - 'items-center inline-flex text-center align-bottom justify-center', - - // Sizes & Spacing - 'text-sm py-2 px-3 w-full', - - // Shape - 'rounded-md', - - 'bg-transparent border-transparent', - 'text-primary-500 dark:text-primary-400', - 'hover:bg-primary-300/20', - - // Transitions - 'transition duration-200 ease-in-out', - - // Misc - 'cursor-pointer overflow-hidden select-none' - ] - }, - label: { - class: 'flex-auto grow-0' - }, - icon: { - class: 'mr-2' - } - }, - filterremovebutton: { - root: { - class: [ - 'relative', - - // Alignments - 'items-center inline-flex text-center align-bottom justify-center', - - // Sizes & Spacing - 'text-sm py-2 px-3 w-full mt-2', - - // Shape - 'rounded-md', - - 'bg-transparent border-transparent', - 'text-red-500 dark:text-red-400', - 'hover:bg-red-300/20', - - // Transitions - 'transition duration-200 ease-in-out', - - // Misc - 'cursor-pointer overflow-hidden select-none' - ] - }, - label: { - class: 'flex-auto grow-0' - }, - icon: { - class: 'mr-2' - } - }, - filterbuttonbar: { - class: [ - // Flex & Alignment - 'flex items-center justify-between', - - // Space - 'py-3 px-5' + 'bg-surface-0 dark:bg-surface-700', + '[&>[data-pc-name=pcfilteroperatordropdown]]:w-full' ] }, - filterclearbutton: { - root: { - class: [ - 'relative', - - // Alignments - 'items-center inline-flex text-center align-bottom justify-center', - - // Sizes & Spacing - 'text-sm py-2 px-3', - - // Shape - 'rounded-md', - - 'text-primary-500 border border-primary-500', - 'hover:bg-primary-300/20', - - // Transitions - 'transition duration-200 ease-in-out', - - // Misc - 'cursor-pointer overflow-hidden select-none' - ] - } - }, - filterapplybutton: { - root: { - class: [ - 'relative', - - // Alignments - 'items-center inline-flex text-center align-bottom justify-center', - - // Sizes & Spacing - 'text-sm py-2 px-3', - - // Shape - 'rounded-md', - - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - - // Transitions - 'transition duration-200 ease-in-out', - - // Misc - 'cursor-pointer overflow-hidden select-none' - ] - } - }, - filtermenubutton: ({ context }) => ({ - class: [ - 'relative', - // Flex & Alignment - 'inline-flex items-center justify-center', - - // Size - 'w-8 h-8', - - // Spacing - 'ml-2', - - // Shape - 'rounded-full', - - // Color - { 'bg-primary-50 text-primary-700': context.active }, - 'dark:text-white/70 dark:hover:text-white/80 dark:bg-surface-800', - - // States - 'hover:text-surface-700 hover:bg-surface-300/20', - 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - - // Transition - 'transition duration-200', - - // Misc - 'cursor-pointer no-underline overflow-hidden' - ] - }), - headerfilterclearbutton: ({ context }) => ({ - class: [ - 'relative', - - // Flex & Alignment - 'inline-flex items-center justify-center', - 'text-left', - - // Shape - 'border-none', - - // Spacing - 'm-0 p-0 ml-2', - - // Color - 'bg-transparent', - - // Misc - 'cursor-pointer no-underline overflow-hidden select-none', - { - invisible: !context.hidden - } - ] + filter: ({ instance }) => ({ + class: [{ 'flex items-center w-full gap-2': instance.display === 'row', 'inline-flex ml-auto': instance.display === 'menu' }] }), - rowtoggler: { + filterRuleList: 'flex flex-col gap-2', + filterRule: 'flex flex-col gap-2', + filterButtonbar: 'flex items-center justify-between p-0', + filterAddButtonContainer: '[&>[data-pc-name=pcfilteraddrulebutton]]:w-full', + rowToggleButton: { class: [ 'relative', @@ -683,7 +306,7 @@ export default { 'cursor-pointer select-none' ] }, - columnresizer: { + columnResizer: { class: [ 'block', @@ -703,411 +326,21 @@ export default { 'cursor-col-resize' ] }, - rowreordericon: { - class: 'cursor-move' - }, - roweditorinitbutton: { - class: [ - 'relative', - - // Flex & Alignment - 'inline-flex items-center justify-center', - 'text-left', - - // Size - 'w-8 h-8', - - // Shape - 'border-0 rounded-full', - - // Color - 'text-surface-700 dark:text-white/70', - 'border-transparent', - - // States - 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - 'hover:text-surface-700 hover:bg-surface-300/20', - - // Transition - 'transition duration-200', - - // Misc - 'overflow-hidden', - 'cursor-pointer select-none' - ] - }, - roweditorsavebutton: { - class: [ - 'relative', - - // Flex & Alignment - 'inline-flex items-center justify-center', - 'text-left', - - // Size - 'w-8 h-8', - - // Shape - 'border-0 rounded-full', - - // Color - 'text-surface-700 dark:text-white/70', - 'border-transparent', - - // States - 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - 'hover:text-surface-700 hover:bg-surface-300/20', - - // Transition - 'transition duration-200', - - // Misc - 'overflow-hidden', - 'cursor-pointer select-none' - ] - }, - roweditorcancelbutton: { - class: [ - 'relative', - - // Flex & Alignment - 'inline-flex items-center justify-center', - 'text-left', - - // Size - 'w-8 h-8', - - // Shape - 'border-0 rounded-full', - - // Color - 'text-surface-700 dark:text-white/70', - 'border-transparent', - - // States - 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - 'hover:text-surface-700 hover:bg-surface-300/20', - - // Transition - 'transition duration-200', - - // Misc - 'overflow-hidden', - 'cursor-pointer select-none' - ] - }, - rowRadiobutton: { - root: { - class: [ - 'relative', - - // Flexbox & Alignment - 'inline-flex', - 'align-bottom', - - // Size - 'w-[1.571rem] h-[1.571rem]', - - // Misc - 'cursor-pointer', - 'select-none' - ] - }, - box: ({ props }) => ({ - class: [ - // Flexbox - 'flex justify-center items-center', - - // Size - 'w-[1.571rem] h-[1.571rem]', - - // Shape - 'border-2', - 'rounded-full', - - // Transition - 'transition duration-200 ease-in-out', - - // Colors - { - 'text-surface-700 dark:text-white/80': !props.modelValue, - 'bg-surface-0 dark:bg-surface-900': !props.modelValue, - 'border-surface-300 dark:border-surface-700': !props.modelValue, - 'border-primary-500 dark:border-primary-400': props.modelValue, - 'bg-primary-500 dark:bg-primary-400': props.modelValue - }, - - // States - { - 'peer-hover:border-primary-500 dark:peer-hover:border-primary-400': !props.disabled, - 'peer-hover:border-primary-600 dark:peer-hover:border-primary-300 peer-hover:bg-primary-600 dark:peer-hover:bg-primary-300': !props.disabled && props.modelValue, - 'peer-focus-visible:border-primary-500 dark:peer-focus-visible:border-primary-400 peer-focus-visible:ring-2 peer-focus-visible:ring-primary-400/20 dark:peer-focus-visible:ring-primary-300/20': !props.disabled, - 'opacity-60 cursor-default': props.disabled - } - ] - }), - input: { - class: [ - 'peer', - - // Size - 'w-full ', - 'h-full', - - // Position - 'absolute', - 'top-0 left-0', - 'z-10', - - // Spacing - 'p-0', - 'm-0', - - // Shape - 'opacity-0', - 'rounded-md', - 'outline-none', - 'border-2 border-surface-200 dark:border-surface-700', - - // Misc - 'appearance-none', - 'cursor-pointer' - ] - }, - icon: ({ props }) => ({ - class: [ - 'block', - - // Shape - 'rounded-full', - - // Size - 'w-[0.857rem] h-[0.857rem]', - - // Colors - 'bg-surface-0 dark:bg-surface-900', - - // Conditions - { - 'backface-hidden scale-10 invisible': !props.modelValue, - 'transform visible scale-[1.1]': props.modelValue - }, - - // Transition - 'transition duration-200' - ] - }) - }, - headercheckbox: { - root: { - class: [ - 'relative', - - // Alignment - 'inline-flex', - 'align-bottom', - - // Size - 'w-6', - 'h-6', - - // Misc - 'cursor-pointer', - 'select-none' - ] - }, - box: ({ props, context }) => ({ - class: [ - // Alignment - 'flex', - 'items-center', - 'justify-center', - - // Size - 'w-6', - 'h-6', - - // Shape - 'rounded-md', - 'border-2', - - // Colors - { - 'border-surface-200 bg-surface-0 dark:border-surface-700 dark:bg-surface-900': !context.checked, - 'border-primary-500 bg-primary-500 dark:border-primary-400 dark:bg-primary-400': context.checked - }, - - // States - { - 'peer-hover:border-primary-500 dark:peer-hover:border-primary-400': !props.disabled && !context.checked, - 'peer-hover:bg-primary-600 dark:peer-hover:bg-primary-300 peer-hover:border-primary-700 dark:peer-hover:border-primary-300': !props.disabled && context.checked, - 'peer-focus-visible:border-primary-500 dark:peer-focus-visible:border-primary-400 peer-focus-visible:ring-2 peer-focus-visible:ring-primary-400/20 dark:peer-focus-visible:ring-primary-300/20': !props.disabled, - 'cursor-default opacity-60': props.disabled - }, - - // Transitions - 'transition-colors', - 'duration-200' - ] - }), - input: { - class: [ - 'peer', - - // Size - 'w-full ', - 'h-full', - - // Position - 'absolute', - 'top-0 left-0', - 'z-10', - - // Spacing - 'p-0', - 'm-0', - - // Shape - 'opacity-0', - 'rounded-md', - 'outline-none', - 'border-2 border-surface-200 dark:border-surface-700', - - // Misc - 'appearance-none', - 'cursor-pointer' - ] - }, - icon: { - class: [ - // Font - 'text-base leading-none', - - // Size - 'w-4', - 'h-4', - - // Colors - 'text-white dark:text-surface-900', - - // Transitions - 'transition-all', - 'duration-200' - ] - } - }, - rowCheckbox: { - root: { - class: [ - 'relative', - - // Alignment - 'inline-flex', - 'align-bottom', - - // Size - 'w-6', - 'h-6', - - // Misc - 'cursor-pointer', - 'select-none' - ] - }, - box: ({ props, context }) => ({ - class: [ - // Alignment - 'flex', - 'items-center', - 'justify-center', - - // Size - 'w-6', - 'h-6', - - // Shape - 'rounded-md', - 'border-2', - - // Colors - { - 'border-surface-200 bg-surface-0 dark:border-surface-700 dark:bg-surface-900': !context.checked, - 'border-primary-500 bg-primary-500 dark:border-primary-400 dark:bg-primary-400': context.checked - }, - - // States - { - 'peer-hover:border-primary-500 dark:peer-hover:border-primary-400': !props.disabled && !context.checked, - 'peer-hover:bg-primary-600 dark:peer-hover:bg-primary-300 peer-hover:border-primary-700 dark:peer-hover:border-primary-300': !props.disabled && context.checked, - 'peer-focus-visible:border-primary-500 dark:peer-focus-visible:border-primary-400 peer-focus-visible:ring-2 peer-focus-visible:ring-primary-400/20 dark:peer-focus-visible:ring-primary-300/20': !props.disabled, - 'cursor-default opacity-60': props.disabled - }, - - // Transitions - 'transition-colors', - 'duration-200' - ] - }), - input: { - class: [ - 'peer', - - // Size - 'w-full ', - 'h-full', - - // Position - 'absolute', - 'top-0 left-0', - 'z-10', - - // Spacing - 'p-0', - 'm-0', - - // Shape - 'opacity-0', - 'rounded-md', - 'outline-none', - 'border-2 border-surface-200 dark:border-surface-700', - - // Misc - 'appearance-none', - 'cursor-pointer' - ] - }, - icon: { - class: [ - // Font - 'text-base leading-none', - - // Size - 'w-4', - 'h-4', - - // Colors - 'text-white dark:text-surface-900', - - // Transitions - 'transition-all', - 'duration-200' - ] - } - }, transition: { + class: 'p-4 flex flex-col gap-2', enterFromClass: 'opacity-0 scale-y-[0.8]', enterActiveClass: 'transition-[transform,opacity] duration-[120ms] ease-[cubic-bezier(0,0,0.2,1)]', leaveActiveClass: 'transition-opacity duration-100 ease-linear', leaveToClass: 'opacity-0' } }, - bodyrow: ({ context, props }) => ({ + bodyRow: ({ context, props }) => ({ class: [ // Color 'dark:text-white/80', - { 'bg-primary-50 text-primary-700 dark:bg-primary-400/30': context.selected }, + { 'bg-highlight': context.selected }, { 'bg-surface-0 text-surface-600 dark:bg-surface-800': !context.selected }, - { 'font-bold bg-surface-0 dark:bg-surface-800': props.frozenRow }, + { 'font-bold bg-surface-0 dark:bg-surface-800 z-20': props.frozenRow }, { 'odd:bg-surface-0 odd:text-surface-600 dark:odd:bg-surface-800 even:bg-surface-50 even:text-surface-600 dark:even:bg-surface-900/50': context.stripedRows }, // State @@ -1121,16 +354,16 @@ export default { { 'cursor-pointer': props.selectionMode } ] }), - rowexpansion: { + rowExpansion: { class: 'bg-surface-0 dark:bg-surface-800 text-surface-600 dark:text-white/80' }, - rowgroupheader: { + rowGroupHeader: { class: ['sticky z-20', 'bg-surface-0 text-surface-600 dark:text-white/70', 'dark:bg-surface-800'] }, - rowgroupfooter: { + rowGroupFooter: { class: ['sticky z-20', 'bg-surface-0 text-surface-600 dark:text-white/70', 'dark:bg-surface-800'] }, - rowgrouptoggler: { + rowToggleButton: { class: [ 'relative', @@ -1161,10 +394,10 @@ export default { 'cursor-pointer select-none' ] }, - rowgrouptogglericon: { + rowToggleIcon: { class: 'inline-block w-4 h-4' }, - resizehelper: { - class: 'absolute hidden w-[2px] z-20 bg-primary-500 dark:bg-primary-400' + columnResizeIndicator: { + class: 'absolute hidden w-[2px] z-20 bg-primary' } }; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/dataview/index.js b/frontend/packages/kwai-ui/src/presets/kwai/dataview/index.js index 2eed11b0..c029bb9c 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/dataview/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/dataview/index.js @@ -12,18 +12,6 @@ export default { 'bg-surface-0 dark:bg-surface-800' ] }, - grid: { - class: [ - // flex - 'flex flex-wrap', - - // Spacing - 'ml-0 mr-0 mt-0', - - // Color - 'bg-surface-0 dark:bg-surface-800' - ] - }, header: { class: [ 'font-bold', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/dialog/index.js b/frontend/packages/kwai-ui/src/presets/kwai/dialog/index.js index adb8f1e6..6cca050c 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/dialog/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/dialog/index.js @@ -8,7 +8,6 @@ export default { // Size 'max-h-[90vh]', - 'w-[50vw]', 'm-0', // Color @@ -53,95 +52,9 @@ export default { title: { class: ['font-bold text-lg'] }, - icons: { + headerActions: { class: ['flex items-center'] }, - closeButton: { - class: [ - 'relative', - - // Flexbox and Alignment - 'flex items-center justify-center', - - // Size and Spacing - 'mr-2', - 'last:mr-0', - 'w-8 h-8', - - // Shape - 'border-0', - 'rounded-full', - - // Colors - 'text-surface-500', - 'bg-transparent', - - // Transitions - 'transition duration-200 ease-in-out', - - // States - 'hover:text-surface-700 dark:hover:text-white/80', - 'hover:bg-surface-100 dark:hover:bg-surface-800/80', - 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-inset', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - - // Misc - 'overflow-hidden' - ] - }, - maximizablebutton: { - class: [ - 'relative', - - // Flexbox and Alignment - 'flex items-center justify-center', - - // Size and Spacing - 'mr-2', - 'last:mr-0', - 'w-8 h-8', - - // Shape - 'border-0', - 'rounded-full', - - // Colors - 'text-surface-500', - 'bg-transparent', - - // Transitions - 'transition duration-200 ease-in-out', - - // States - 'hover:text-surface-700 dark:hover:text-white/80', - 'hover:bg-surface-100 dark:hover:bg-surface-800/80', - 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-inset', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - - // Misc - 'overflow-hidden' - ] - }, - closeButtonIcon: { - class: [ - // Display - 'inline-block', - - // Size - 'w-4', - 'h-4' - ] - }, - maximizableicon: { - class: [ - // Display - 'inline-block', - - // Size - 'w-4', - 'h-4' - ] - }, content: ({ state, instance }) => ({ class: [ // Spacing diff --git a/frontend/packages/kwai-ui/src/presets/kwai/dock/index.js b/frontend/packages/kwai-ui/src/presets/kwai/dock/index.js index 5a33aded..b9332a8b 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/dock/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/dock/index.js @@ -17,7 +17,7 @@ export default { 'pointer-events-none' ] }), - container: { + listContainer: { class: [ // Flexbox 'flex', @@ -36,7 +36,7 @@ export default { 'pointer-events-auto' ] }, - menu: ({ props }) => ({ + list: ({ props }) => ({ class: [ // Flexbox & Alignment 'flex items-center justify-center', @@ -51,31 +51,24 @@ export default { 'outline-none' ] }), - menuitem: ({ props, context, instance }) => ({ + item: ({ props, context, instance }) => ({ class: [ // Spacing & Shape 'p-2 rounded-md', - // Conditional Scaling - { - 'hover:scale-150': instance.currentIndex === context.index, - 'scale-125': instance.currentIndex - 1 === context.index || instance.currentIndex + 1 === context.index, - 'scale-110': instance.currentIndex - 2 === context.index || instance.currentIndex + 2 === context.index - }, - // Positioning & Hover States { - 'origin-bottom hover:mx-6': props.position == 'bottom', - 'origin-top hover:mx-6': props.position == 'top', - 'origin-left hover:my-6': props.position == 'left', - 'origin-right hover:my-6': props.position == 'right' + 'origin-bottom': props.position == 'bottom', + 'origin-top': props.position == 'top', + 'origin-left': props.position == 'left', + 'origin-right': props.position == 'right' }, // Transitions & Transform 'transition-all duration-200 ease-cubic-bezier-will-change-transform transform' ] }), - action: { + itemLink: { class: [ // Flexbox & Alignment 'flex flex-col items-center justify-center', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/fieldset/index.js b/frontend/packages/kwai-ui/src/presets/kwai/fieldset/index.js index 3b70c804..b769298c 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/fieldset/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/fieldset/index.js @@ -39,7 +39,7 @@ export default { { 'hover:bg-surface-100 hover:border-surface-200 hover:text-surface-900 dark:hover:text-surface-0/80 dark:hover:bg-surface-800/80': props.toggleable } ] }), - toggler: ({ props }) => ({ + toggleButton: ({ props }) => ({ class: [ // Alignments 'flex items-center justify-center', @@ -64,10 +64,10 @@ export default { } ] }), - togglerIcon: { + toggleIcon: { class: 'mr-2 inline-block' }, - legendTitle: { + legendLabel: { class: 'flex items-center justify-center leading-none' }, content: { diff --git a/frontend/packages/kwai-ui/src/presets/kwai/fileupload/index.js b/frontend/packages/kwai-ui/src/presets/kwai/fileupload/index.js index 1e17c706..e6a9a979 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/fileupload/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/fileupload/index.js @@ -1,8 +1,15 @@ export default { + root: ({ props }) => ({ + class: [ + { + 'flex flex-wrap items-center justify-center gap-2': props.mode === 'basic' + } + ] + }), input: { class: 'hidden' }, - buttonbar: { + header: { class: [ // Flexbox 'flex', @@ -30,52 +37,6 @@ export default { 'rounded-tl-lg' ] }, - chooseButton: { - class: [ - 'relative', - - // Alignments - 'items-center inline-flex text-center align-bottom justify-center', - - // Spacing - 'px-4 py-3', - - // Shape - 'rounded-md', - - // Font - 'leading-[normal]', - 'font-bold', - - // Colors - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border-primary-500 dark:border-primary-400', - - // States - 'hover:bg-primary-600 dark:hover:bg-primary-300', - - // Misc - 'overflow-hidden', - 'cursor-pointer' - ] - }, - chooseIcon: { - class: ['mr-2', 'inline-block'] - }, - chooseButtonLabel: { - class: ['flex-1', 'font-bold'] - }, - uploadbutton: { - icon: { - class: 'mr-2' - } - }, - cancelbutton: { - icon: { - class: 'mr-2' - } - }, content: { class: [ // Position @@ -96,7 +57,14 @@ export default { 'dark:border-surface-700', // Shape - 'rounded-b-lg' + 'rounded-b-lg', + + //ProgressBar + '[&>[data-pc-name=pcprogressbar]]:absolute', + '[&>[data-pc-name=pcprogressbar]]:w-full', + '[&>[data-pc-name=pcprogressbar]]:top-0', + '[&>[data-pc-name=pcprogressbar]]:left-0', + '[&>[data-pc-name=pcprogressbar]]:h-1' ] }, file: { @@ -121,53 +89,7 @@ export default { 'rounded' ] }, - thumbnail: { - class: 'shrink-0' - }, - fileName: { - class: 'mb-2 break-all' - }, - fileSize: { - class: 'mr-2' - }, - uploadicon: { - class: 'mr-2' - }, - progressbar: { - root: { - class: [ - // Position and Overflow - 'overflow-hidden', - 'absolute top-0 left-0', - - // Shape and Size - 'border-0', - 'h-2', - 'rounded-md', - 'w-full', - - // Colors - 'bg-surface-100 dark:bg-surface-700' - ] - }, - value: { - class: [ - // Flexbox & Overflow & Position - 'absolute flex items-center justify-center overflow-hidden', - - // Colors - 'bg-primary-500 dark:bg-primary-400', - - // Spacing & Sizing - 'm-0', - 'h-full w-0', - - // Shape - 'border-0', - - // Transitions - 'transition-width duration-1000 ease-in-out' - ] - } - } + fileThumbnail: 'shrink-0', + fileName: 'mb-2 break-all', + fileSize: 'mr-2' }; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/galleria/index.js b/frontend/packages/kwai-ui/src/presets/kwai/galleria/index.js index 96e026ac..c318c1ad 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/galleria/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/galleria/index.js @@ -11,7 +11,7 @@ export default { } ] }), - itemwrapper: ({ parent, props }) => ({ + itemsContainer: ({ parent, props }) => ({ class: [ 'group', 'flex relative', @@ -29,7 +29,7 @@ export default { ] }), - itemcontainer: ({ parent }) => ({ + items: ({ parent }) => ({ class: [ 'flex h-full relative', { @@ -47,7 +47,7 @@ export default { 'h-full w-full' ] }, - thumbnailwrapper: ({ parent }) => ({ + thumbnails: ({ parent }) => ({ class: [ // Flex 'flex flex-col shrink-0', @@ -60,7 +60,7 @@ export default { 'overflow-auto' ] }), - thumbnailcontainer: ({ parent }) => ({ + thumbnailContent: ({ parent }) => ({ class: [ // Flex 'flex', @@ -77,7 +77,7 @@ export default { } ] }), - previousthumbnailbutton: { + thumbnailPrevButton: { class: [ // Positioning 'self-center relative', @@ -98,10 +98,10 @@ export default { 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50' ] }, - thumbnailitemscontainer: { + thumbnailsViewport: { class: 'overflow-hidden w-full' }, - thumbnailitems: ({ parent }) => ({ + thumbnailItems: ({ parent }) => ({ class: [ 'flex', { @@ -109,7 +109,7 @@ export default { } ] }), - thumbnailitem: ({ parent }) => ({ + thumbnailItem: ({ parent }) => ({ class: [ // Flexbox 'flex items-center justify-center', @@ -126,12 +126,14 @@ export default { 'opacity-50', // States + '[&[data-p-active="true"]]:opacity-100', 'hover:opacity-100', - 'hover:transition-opacity', - 'hover:duration-300' + + // Transitions + 'transition-opacity duration-300' ] }), - nextthumbnailbutton: { + thumbnailNextButton: { class: [ // Positioning 'self-center relative', @@ -152,7 +154,7 @@ export default { 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50' ] }, - indicators: ({ parent }) => ({ + indicatorList: ({ parent }) => ({ class: [ // flex 'flex items-center justify-center', @@ -187,7 +189,7 @@ export default { } ] }), - indicatorbutton: ({ context }) => ({ + indicatorButton: ({ context }) => ({ class: [ // Size 'w-4 h-4', @@ -202,13 +204,13 @@ export default { { 'bg-surface-200 hover:bg-surface-300 dark:bg-surface-700 dark:hover:bg-surface-600': !context.highlighted }, // Conditional Appearance: Highlighted - { 'bg-primary-500 hover:bg-primary-600': context.highlighted } + { 'bg-primary hover:bg-primary-emphasis': context.highlighted } ] }), mask: { class: ['fixed top-0 left-0 w-full h-full', 'flex items-center justify-center', 'bg-black/90'] }, - closebutton: { + closeButton: { class: [ // Positioning '!absolute top-0 right-0', @@ -229,10 +231,10 @@ export default { 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50' ] }, - closeicon: { + closeIcon: { class: 'w-6 h-6' }, - previousitembutton: ({ parent }) => ({ + prevButton: ({ parent }) => ({ class: [ // Display & Flexbox 'inline-flex justify-center items-center overflow-hidden', @@ -249,8 +251,8 @@ export default { // Positioning 'top-1/2 mt-[-0.5rem] left-0', { - '!absolute': parent.props.showItemNavigators, - '!fixed': !parent.props.showItemNavigators + '!absolute': !parent.state.containerVisible && parent.props.showItemNavigators, + '!fixed': parent.state.containerVisible }, // Hover Effect @@ -260,7 +262,7 @@ export default { 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50' ] }), - nextitembutton: ({ parent }) => ({ + nextButton: ({ parent }) => ({ class: [ // Display & Flexbox 'inline-flex justify-center items-center overflow-hidden', @@ -277,8 +279,8 @@ export default { // Positioning 'top-1/2 mt-[-0.5rem] right-0', { - '!absolute': parent.props.showItemNavigators, - '!fixed': !parent.props.showItemNavigators + '!absolute': !parent.state.containerVisible && parent.props.showItemNavigators, + '!fixed': parent.state.containerVisible }, // Hover Effect diff --git a/frontend/packages/kwai-ui/src/presets/kwai/iconfield/index.js b/frontend/packages/kwai-ui/src/presets/kwai/iconfield/index.js index 108735b0..28e6ae53 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/iconfield/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/iconfield/index.js @@ -1,22 +1,27 @@ export default { - root: ({ props }) => ({ + root: { class: [ 'relative', - '[&>input]:w-full', - '[&>*:first-child]:absolute', - '[&>*:first-child]:top-1/2', - '[&>*:first-child]:-mt-2', - '[&>*:first-child]:leading-none', - '[&>*:first-child]:text-surface-900/60 dark:[&>*:first-child]:text-white/60', - { - '[&>*:first-child]:right-3': props.iconPosition === 'right', - '[&>*:first-child]:left-3': props.iconPosition === 'left' - }, - { - '[&>*:last-child]:pr-10': props.iconPosition === 'right', - '[&>*:last-child]:pl-10': props.iconPosition === 'left' - } + '[&>[data-pc-name=inputicon]]:absolute', + '[&>[data-pc-name=inputicon]]:top-1/2', + '[&>[data-pc-name=inputicon]]:-mt-2', + '[&>[data-pc-name=inputicon]]:text-surface-900/60 dark:[&>[data-pc-name=inputicon]]:text-white/60', + + '[&>[data-pc-name=inputicon]:first-child]:left-3', + '[&>[data-pc-name=inputicon]:last-child]:right-3', + + '[&>[data-pc-name=inputtext]:first-child]:pr-10', + '[&>[data-pc-name=inputtext]:last-child]:pl-10', + + // filter + '[&>[data-pc-extend=inputicon]]:absolute', + '[&>[data-pc-extend=inputicon]]:top-1/2', + '[&>[data-pc-extend=inputicon]]:-mt-2', + '[&>[data-pc-extend=inputicon]]:text-surface-900/60 dark:[&>[data-pc-extend=inputicon]]:text-white/60', + + '[&>[data-pc-extend=inputicon]:first-child]:left-3', + '[&>[data-pc-extend=inputicon]:last-child]:right-3' ] - }) + } }; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/image/index.js b/frontend/packages/kwai-ui/src/presets/kwai/image/index.js index e6d6f9fe..ea1e553c 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/image/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/image/index.js @@ -2,7 +2,7 @@ export default { root: { class: 'relative inline-block' }, - button: { + previewMask: { class: [ // Flexbox & Alignment 'flex items-center justify-center', @@ -47,7 +47,7 @@ export default { 'p-4' ] }, - rotaterightbutton: { + rotateRightButton: { class: [ 'z-20', @@ -74,10 +74,10 @@ export default { 'transition duration-200 ease-in-out' ] }, - rotaterighticon: { + rotateRightIcon: { class: 'w-6 h-6' }, - rotateleftbutton: { + rotateLeftButton: { class: [ 'z-20', @@ -104,10 +104,10 @@ export default { 'transition duration-200 ease-in-out' ] }, - rotatelefticon: { + rotateLeftIcon: { class: 'w-6 h-6' }, - zoomoutbutton: { + zoomOutButton: { class: [ 'z-20', @@ -134,10 +134,10 @@ export default { 'transition duration-200 ease-in-out' ] }, - zoomouticon: { + zoomOutIcon: { class: 'w-6 h-6' }, - zoominbutton: { + zoomInButton: { class: [ 'z-20', @@ -164,10 +164,10 @@ export default { 'transition duration-200 ease-in-out' ] }, - zoominicon: { + zoomInIcon: { class: 'w-6 h-6' }, - closebutton: { + closeButton: { class: [ 'z-20', @@ -194,7 +194,7 @@ export default { 'transition duration-200 ease-in-out' ] }, - closeicon: { + closeIcon: { class: 'w-6 h-6' }, transition: { diff --git a/frontend/packages/kwai-ui/src/presets/kwai/index.js b/frontend/packages/kwai-ui/src/presets/kwai/index.js index d0984c4a..0f667db0 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/index.js @@ -1,11 +1,9 @@ import global from './global.js'; import autocomplete from './autocomplete'; -import calendar from './calendar'; import cascadeselect from './cascadeselect'; import checkbox from './checkbox'; -import chips from './chips'; import colorpicker from './colorpicker'; -import dropdown from './dropdown'; +import datepicker from './datepicker'; import floatlabel from './floatlabel'; import iconfield from './iconfield'; import inputgroup from './inputgroup'; @@ -13,7 +11,6 @@ import inputotp from './inputotp'; import inputgroupaddon from './inputgroupaddon'; import inputmask from './inputmask'; import inputnumber from './inputnumber'; -import inputswitch from './inputswitch'; import inputtext from './inputtext'; import knob from './knob'; import listbox from './listbox'; @@ -21,15 +18,25 @@ import multiselect from './multiselect'; import password from './password'; import radiobutton from './radiobutton'; import rating from './rating'; +import select from './select'; import selectbutton from './selectbutton'; import slider from './slider'; import textarea from './textarea'; import togglebutton from './togglebutton'; +import toggleswitch from './toggleswitch'; import treeselect from './treeselect'; -import tristatecheckbox from './tristatecheckbox'; import button from './button'; import speeddial from './speeddial'; import splitbutton from './splitbutton'; +import datatable from './datatable'; +import dataview from './dataview'; +import orderlist from './orderlist'; +import organizationchart from './organizationchart'; +import paginator from './paginator'; +import picklist from './picklist'; +import tree from './tree'; +import treetable from './treetable'; +import timeline from './timeline'; import accordion from './accordion'; import card from './card'; import deferred from './deferred'; @@ -39,17 +46,15 @@ import panel from './panel'; import scrollpanel from './scrollpanel'; import splitter from './splitter'; import stepper from './stepper'; -import tabview from './tabview'; +import tabs from './tabs'; import toolbar from './toolbar'; -import datatable from './datatable'; -import dataview from './dataview'; -import orderlist from './orderlist'; -import organizationchart from './organizationchart'; -import paginator from './paginator'; -import picklist from './picklist'; -import tree from './tree'; -import treetable from './treetable'; -import timeline from './timeline'; +import confirmpopup from './confirmpopup'; +import confirmdialog from './confirmdialog'; +import dialog from './dialog'; +import drawer from './drawer'; +import popover from './popover'; +import tooltip from './tooltip'; +import fileupload from './fileupload'; import breadcrumb from './breadcrumb'; import contextmenu from './contextmenu'; import dock from './dock'; @@ -57,24 +62,15 @@ import menu from './menu'; import menubar from './menubar'; import megamenu from './megamenu'; import panelmenu from './panelmenu'; -import steps from './steps'; import tabmenu from './tabmenu'; import tieredmenu from './tieredmenu'; -import confirmpopup from './confirmpopup'; -import dialog from './dialog'; -import overlaypanel from './overlaypanel'; -import sidebar from './sidebar'; -import tooltip from './tooltip'; -import fileupload from './fileupload'; import message from './message'; -import inlinemessage from './inlinemessage'; import toast from './toast'; import carousel from './carousel'; import galleria from './galleria'; import image from './image'; import avatar from './avatar'; import badge from './badge'; -import badgedirective from './badgedirective'; import blockui from './blockui'; import chip from './chip'; import inplace from './inplace'; @@ -91,16 +87,13 @@ export default { global, directives: { tooltip, - badgedirective, ripple }, autocomplete, - calendar, cascadeselect, checkbox, - chips, colorpicker, - dropdown, + datepicker, floatlabel, iconfield, inputgroup, @@ -108,7 +101,6 @@ export default { inputgroupaddon, inputmask, inputnumber, - inputswitch, inputtext, knob, listbox, @@ -116,15 +108,25 @@ export default { password, radiobutton, rating, + select, selectbutton, slider, textarea, togglebutton, + toggleswitch, treeselect, - tristatecheckbox, button, speeddial, splitbutton, + datatable, + dataview, + orderlist, + organizationchart, + paginator, + picklist, + tree, + treetable, + timeline, accordion, card, deferred, @@ -134,17 +136,14 @@ export default { scrollpanel, splitter, stepper, - tabview, + tabs, toolbar, - datatable, - dataview, - orderlist, - organizationchart, - paginator, - picklist, - tree, - treetable, - timeline, + confirmpopup, + confirmdialog, + dialog, + drawer, + popover, + fileupload, breadcrumb, contextmenu, dock, @@ -152,16 +151,9 @@ export default { menubar, megamenu, panelmenu, - steps, tabmenu, tieredmenu, - confirmpopup, - dialog, - overlaypanel, - sidebar, - fileupload, message, - inlinemessage, toast, carousel, galleria, diff --git a/frontend/packages/kwai-ui/src/presets/kwai/inputmask/index.js b/frontend/packages/kwai-ui/src/presets/kwai/inputmask/index.js index b2b1da70..f94f9ecc 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/inputmask/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/inputmask/index.js @@ -1,8 +1,8 @@ export default { - root: ({ context, props }) => ({ + root: ({ context, props, parent }) => ({ class: [ // Font - 'font-sans leading-none', + 'leading-[normal]', // Spacing 'm-0 p-3', @@ -16,15 +16,20 @@ export default { { 'border-surface-300 dark:border-surface-600': !props.invalid }, // Invalid State + 'invalid:focus:ring-red-200', + 'invalid:hover:border-red-500', { 'border-red-500 dark:border-red-400': props.invalid }, // States { - 'hover:border-primary-500 dark:hover:border-primary-400': !context.disabled && !props.invalid, + 'hover:border-primary': !context.disabled && !props.invalid, 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-500/50 dark:focus:ring-primary-400/50': !context.disabled, 'opacity-60 select-none pointer-events-none cursor-default': context.disabled }, + // Filled State *for FloatLabel + { filled: parent.instance?.$name == 'FloatLabel' && props.modelValue !== null && props.modelValue?.length !== 0 }, + // Misc 'rounded-md', 'appearance-none', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/inputnumber/index.js b/frontend/packages/kwai-ui/src/presets/kwai/inputnumber/index.js index bf5f406d..e36aaf43 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/inputnumber/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/inputnumber/index.js @@ -3,8 +3,10 @@ export default { class: [ // Flex 'inline-flex', + 'relative', { 'flex-col': props.showButtons && props.buttonLayout == 'vertical' }, { 'flex-1 w-[1%]': parent.instance.$name == 'InputGroup' }, + { 'w-full': props.fluid }, // Shape { 'first:rounded-l-md rounded-none last:rounded-r-md': parent.instance.$name == 'InputGroup' && !props.showButtons }, @@ -15,150 +17,151 @@ export default { { '!w-16': props.showButtons && props.buttonLayout == 'vertical' } ] }), - input: { + pcInput: { root: ({ parent, context }) => ({ class: [ - // Display - 'flex flex-auto', - // Font - 'font-sans leading-none', + // 'text-base leading-none', + // 'leading-[normal]', + + // Display + 'flex-auto', + { 'w-[1%]': parent.props.fluid }, //Text { 'text-center': parent.props.showButtons && parent.props.buttonLayout == 'vertical' }, // Spacing - 'p-3', + 'py-2 px-3', 'm-0', // Shape - 'rounded-lg', - { 'rounded-tr-none rounded-br-none': parent.props.showButtons }, - { 'rounded-tl-none rounded-bl-none': parent.props.showButtons && parent.props.buttonLayout == 'horizontal' }, + 'rounded-md', + { 'rounded-l-none rounded-r-none': parent.props.showButtons && parent.props.buttonLayout == 'horizontal' }, { 'rounded-none': parent.props.showButtons && parent.props.buttonLayout == 'vertical' }, - { '!rounded-none': parent.instance.$parentInstance?.$name == 'InputGroup' && !parent.props.showButtons }, { 'border-0': parent.instance.$parentInstance?.$name == 'InputGroup' && !parent.props.showButtons }, // Colors - 'text-surface-600 dark:text-surface-200', + 'text-surface-800 dark:text-white/80', 'placeholder:text-surface-400 dark:placeholder:text-surface-500', - 'bg-surface-0 dark:bg-surface-900', + { 'bg-surface-0 dark:bg-surface-900': !context.disabled }, 'border', - { 'border-surface-300 dark:border-surface-600': !parent.props.invalid }, + { 'border-surface-300 dark:border-surface-700': !parent.props.invalid }, // Invalid State + 'invalid:focus:ring-red-200', + 'invalid:hover:border-red-500', { 'border-red-500 dark:border-red-400': parent.props.invalid }, // States - { 'hover:border-primary-500 dark:hover:border-primary-400': !parent.props.invalid }, - 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-500/50 dark:focus:ring-primary-400/50 focus:z-10', + { 'hover:border-primary': !parent.props.invalid }, + 'focus:outline-none focus:outline-offset-0 focus:ring-1 focus:ring-primary-500/50 dark:focus:ring-primary-400/50 focus:z-10', { 'opacity-60 select-none pointer-events-none cursor-default': context.disabled }, // Filled State *for FloatLabel - { filled: parent.instance?.$name == 'FloatLabel' && context.filled }, + { filled: parent.instance?.$parentInstance?.$name == 'FloatLabel' && parent.state.d_modelValue !== null }, //Position { 'order-2': parent.props.buttonLayout == 'horizontal' || parent.props.buttonLayout == 'vertical' } ] }) }, - buttongroup: ({ props }) => ({ + buttonGroup: ({ props }) => ({ class: [ + 'absolute', + // Flex 'flex', - 'flex-col' - ] - }), - - incrementbutton: { - root: ({ parent }) => ({ - class: [ - // Display - 'flex flex-auto', - - // Alignment - 'items-center', - 'justify-center', - 'text-center align-bottom', - - //Position - 'relative', - { 'order-3': parent.props.showButtons && parent.props.buttonLayout == 'horizontal' }, - { 'order-1': parent.props.showButtons && parent.props.buttonLayout == 'vertical' }, - - //Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Sizing - 'w-[3rem]', - { 'px-4 py-3': parent.props.showButtons && parent.props.buttonLayout !== 'stacked' }, - { 'p-0': parent.props.showButtons && parent.props.buttonLayout == 'stacked' }, - { 'w-full': parent.props.showButtons && parent.props.buttonLayout == 'vertical' }, - - // Shape - 'rounded-md', - { 'rounded-tl-none rounded-br-none rounded-bl-none': parent.props.showButtons && parent.props.buttonLayout == 'stacked' }, - { 'rounded-bl-none rounded-tl-none': parent.props.showButtons && parent.props.buttonLayout == 'horizontal' }, - { 'rounded-bl-none rounded-br-none': parent.props.showButtons && parent.props.buttonLayout == 'vertical' }, + 'flex-col', - //States - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', + 'top-px right-px', - //Misc - 'cursor-pointer overflow-hidden select-none' - ] - }), - label: { - class: 'h-0 w-0' - } - }, - decrementbutton: { - root: ({ parent }) => ({ - class: [ - // Display - 'flex flex-auto', - - // Alignment - 'items-center', - 'justify-center', - 'text-center align-bottom', + { 'h-[calc(100%-2px)]': props.showButtons && props.buttonLayout === 'stacked' } + ] + }), + incrementButton: ({ props }) => ({ + class: [ + // Display + { 'flex flex-initial shrink-0': props.showButtons && props.buttonLayout === 'horizontal' }, + { 'flex flex-auto': props.showButtons && props.buttonLayout === 'stacked' }, + + // Alignment + 'items-center', + 'justify-center', + 'text-center align-bottom', + + //Position + 'relative', + { 'order-3': props.showButtons && props.buttonLayout === 'horizontal' }, + { 'order-1': props.showButtons && props.buttonLayout === 'vertical' }, + + //Color + 'text-primary-contrast', + 'bg-primary', + 'border-primary', + + // Sizing + 'w-[3rem]', + { 'px-4 py-3': props.showButtons && props.buttonLayout !== 'stacked' }, + { 'p-0': props.showButtons && props.buttonLayout === 'stacked' }, + { 'w-full': props.showButtons && props.buttonLayout === 'vertical' }, - //Position - 'relative', - { 'order-1': parent.props.showButtons && parent.props.buttonLayout == 'horizontal' }, - { 'order-3': parent.props.showButtons && parent.props.buttonLayout == 'vertical' }, + // Shape + 'rounded-md', + { 'rounded-tl-none rounded-br-none rounded-bl-none': props.showButtons && props.buttonLayout == 'stacked' }, + { 'rounded-bl-none rounded-tl-none': props.showButtons && props.buttonLayout == 'horizontal' }, + { 'rounded-bl-none rounded-br-none': props.showButtons && props.buttonLayout == 'vertical' }, - //Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', + //States + 'focus:outline-none focus:outline-offset-0 focus:ring', + 'hover:bg-primary-emphasis hover:border-primary-emphasis', - // Sizing - 'w-[3rem]', - { 'px-4 py-3': parent.props.showButtons && parent.props.buttonLayout !== 'stacked' }, - { 'p-0': parent.props.showButtons && parent.props.buttonLayout == 'stacked' }, - { 'w-full': parent.props.showButtons && parent.props.buttonLayout == 'vertical' }, + //Misc + 'cursor-pointer overflow-hidden select-none' + ] + }), + incrementIcon: 'inline-block w-4 h-4', + decrementButton: ({ props }) => ({ + class: [ + // Display + { 'flex flex-initial shrink-0': props.showButtons && props.buttonLayout === 'horizontal' }, + { 'flex flex-auto': props.showButtons && props.buttonLayout === 'stacked' }, + + // Alignment + 'items-center', + 'justify-center', + 'text-center align-bottom', + + //Position + 'relative', + { 'order-1': props.showButtons && props.buttonLayout == 'horizontal' }, + { 'order-3': props.showButtons && props.buttonLayout == 'vertical' }, + + //Color + 'text-primary-contrast', + 'bg-primary', + 'border-primary', + + // Sizing + 'w-[3rem]', + { 'px-4 py-3': props.showButtons && props.buttonLayout !== 'stacked' }, + { 'p-0': props.showButtons && props.buttonLayout == 'stacked' }, + { 'w-full': props.showButtons && props.buttonLayout == 'vertical' }, - // Shape - 'rounded-md', - { 'rounded-tr-none rounded-tl-none rounded-bl-none': parent.props.showButtons && parent.props.buttonLayout == 'stacked' }, - { 'rounded-tr-none rounded-br-none ': parent.props.showButtons && parent.props.buttonLayout == 'horizontal' }, - { 'rounded-tr-none rounded-tl-none ': parent.props.showButtons && parent.props.buttonLayout == 'vertical' }, + // Shape + 'rounded-md', + { 'rounded-tr-none rounded-tl-none rounded-bl-none': props.showButtons && props.buttonLayout == 'stacked' }, + { 'rounded-tr-none rounded-br-none ': props.showButtons && props.buttonLayout == 'horizontal' }, + { 'rounded-tr-none rounded-tl-none ': props.showButtons && props.buttonLayout == 'vertical' }, - //States - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', + //States + 'focus:outline-none focus:outline-offset-0 focus:ring', + 'hover:bg-primary-emphasis hover:border-primary-emphasis', - //Misc - 'cursor-pointer overflow-hidden select-none' - ] - }), - label: { - class: 'h-0 w-0' - } - } + //Misc + 'cursor-pointer overflow-hidden select-none' + ] + }), + decrementIcon: 'inline-block w-4 h-4' }; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/inputotp/index.js b/frontend/packages/kwai-ui/src/presets/kwai/inputotp/index.js index 33858726..b14ce4b9 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/inputotp/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/inputotp/index.js @@ -3,58 +3,8 @@ export default { class: [ // Alignment 'flex items-center', - 'gap-2' + 'gap-2', + '[&_[data-pc-name=pcinput]]:w-10' ] - }, - input: { - root: ({ props, context, parent }) => ({ - class: [ - // Font - 'font-sans leading-none', - - // Flex & Alignment - { 'flex-1 w-[1%]': parent.instance.$name == 'InputGroup' }, - 'text-center', - - // Spacing - 'm-0', - { - 'p-3': props.size == null - }, - - // Size - 'w-10', - - // Shape - { 'rounded-md': parent.instance.$name !== 'InputGroup' }, - { 'first:rounded-l-md rounded-none last:rounded-r-md': parent.instance.$name == 'InputGroup' }, - { 'border-0 border-y border-l last:border-r': parent.instance.$name == 'InputGroup' }, - { 'first:ml-0 ml-[-1px]': parent.instance.$name == 'InputGroup' && !props.showButtons }, - - // Colors - 'text-surface-600 dark:text-surface-200', - 'placeholder:text-surface-400 dark:placeholder:text-surface-500', - 'bg-surface-0 dark:bg-surface-900', - 'border', - { 'border-surface-300 dark:border-surface-600': !props.invalid }, - - // Invalid State - { 'border-red-500 dark:border-red-400': props.invalid }, - - // States - { - 'hover:border-primary-500 dark:hover:border-primary-400': !context.disabled && !props.invalid, - 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-500/50 dark:focus:ring-primary-400/50 focus:z-10': !context.disabled, - 'opacity-60 select-none pointer-events-none cursor-default': context.disabled - }, - - // Filled State *for FloatLabel - { filled: parent.instance?.$name == 'FloatLabel' && context.filled }, - - // Misc - 'appearance-none', - 'transition-colors duration-200' - ] - }) } }; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/inputtext/index.js b/frontend/packages/kwai-ui/src/presets/kwai/inputtext/index.js index de9b0dce..119a6242 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/inputtext/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/inputtext/index.js @@ -2,13 +2,16 @@ export default { root: ({ props, context, parent }) => ({ class: [ // Font - 'font-sans leading-none', + 'leading-[normal]', // Flex { 'flex-1 w-[1%]': parent.instance.$name == 'InputGroup' }, // Spacing 'm-0', + { 'w-full': props.fluid }, + + // Size { 'px-4 py-4': props.size == 'large', 'px-2 py-2': props.size == 'small', @@ -22,18 +25,20 @@ export default { { 'first:ml-0 -ml-px': parent.instance.$name == 'InputGroup' && !props.showButtons }, // Colors - 'text-surface-600 dark:text-surface-200', + 'text-surface-800 dark:text-white/80', 'placeholder:text-surface-400 dark:placeholder:text-surface-500', 'bg-surface-0 dark:bg-surface-900', 'border', { 'border-surface-300 dark:border-surface-600': !props.invalid }, // Invalid State + 'invalid:focus:ring-red-200', + 'invalid:hover:border-red-500', { 'border-red-500 dark:border-red-400': props.invalid }, // States { - 'hover:border-primary-500 dark:hover:border-primary-400': !context.disabled && !props.invalid, + 'hover:border-primary': !context.disabled && !props.invalid, 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-500/50 dark:focus:ring-primary-400/50 focus:z-10': !context.disabled, 'opacity-60 select-none pointer-events-none cursor-default': context.disabled }, diff --git a/frontend/packages/kwai-ui/src/presets/kwai/knob/index.js b/frontend/packages/kwai-ui/src/presets/kwai/knob/index.js index dc11d37f..be6d8e5a 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/knob/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/knob/index.js @@ -26,13 +26,13 @@ export default { 'animate-dash-frame', // Color - 'stroke-primary-500 dark:stroke-primary-400', + 'stroke-primary', // Fill 'fill-none' ] }, - label: { + text: { class: [ // Text Style 'text-center text-xl', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/listbox/index.js b/frontend/packages/kwai-ui/src/presets/kwai/listbox/index.js index 02bf2b8d..cf7d73f6 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/listbox/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/listbox/index.js @@ -15,21 +15,21 @@ export default { { 'border-red-500 dark:border-red-400': props.invalid } ] }), - wrapper: { - class: [ - // Overflow - 'overflow-auto' - ] - }, + listContainer: 'overflow-auto', list: { - class: 'py-3 list-none m-0' + class: 'py-3 list-none m-0 outline-none' }, - item: ({ context }) => ({ + option: ({ context }) => ({ class: [ + 'relative', + // Font 'font-normal', 'leading-none', + // Flex + 'flex items-center', + // Position 'relative', @@ -41,15 +41,17 @@ export default { 'm-0', 'py-3 px-5', - // Color - { 'text-surface-700 dark:text-white/80': !context.focused && !context.selected }, - { 'bg-surface-200 dark:bg-surface-600/60 text-surface-700 dark:text-white/80': context.focused && !context.selected }, - { 'bg-primary-100 dark:bg-primary-400/40 text-primary-700 dark:text-white/80': context.focused && context.selected }, - { 'bg-primary-50 dark:bg-primary-400/40 text-primary-700 dark:text-white/80': !context.focused && context.selected }, + // Colors + { + 'text-surface-700 dark:text-white/80': !context.focused && !context.selected, + 'bg-surface-200 dark:bg-surface-600/60': context.focused && !context.selected, + 'text-surface-700 dark:text-white/80': context.focused && !context.selected, + 'bg-highlight': context.selected + }, //States { 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context.focused && !context.selected }, - { 'hover:text-surface-700 hover:bg-surface-100 dark:hover:text-white dark:hover:bg-surface-600/80': context.focused && !context.selected }, + { 'hover:bg-highlight-emphasis': context.selected }, 'focus-visible:outline-none focus-visible:outline-offset-0 focus-visible:ring focus-visible:ring-inset focus-visible:ring-primary-400/50 dark:focus-visible:ring-primary-300/50', // Transitions @@ -62,7 +64,7 @@ export default { 'whitespace-nowrap' ] }), - itemgroup: { + optionGroup: { class: [ //Font 'font-bold', @@ -79,6 +81,7 @@ export default { 'cursor-auto' ] }, + optionCheckIcon: 'relative -ms-1.5 me-1.5 text-surface-700 dark:text-white/80 w-4 h-4', header: { class: [ // Spacing @@ -93,50 +96,12 @@ export default { // Color 'text-surface-700 dark:text-white/80', 'bg-surface-100 dark:bg-surface-800', - 'border-surface-300 dark:border-surface-600' - ] - }, - filtercontainer: { - class: 'relative' - }, - filterinput: { - class: [ - // Font - 'font-sans', - 'leading-none', - - // Sizing - 'pr-7 py-3 px-3', - '-mr-7', - 'w-full', - - //Color - 'text-surface-700 dark:text-white/80', - 'bg-surface-0 dark:bg-surface-900', - 'border-surface-200 dark:border-surface-700', - - // Shape - 'border', - 'rounded-lg', - 'appearance-none', + 'border-surface-300 dark:border-surface-600', - // Transitions - 'transition', - 'duration-200', - - // States - 'hover:border-primary-500 dark:hover:border-primary-300', - 'focus:ring focus:outline-none focus:outline-offset-0', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - - // Misc - 'appearance-none' + '[&_[data-pc-name=pcfilter]]:w-full' ] }, - filtericon: { - class: ['absolute', 'top-1/2 right-3', '-mt-2'] - }, - emptymessage: { + emptyMessage: { class: [ // Font 'leading-none', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/megamenu/index.js b/frontend/packages/kwai-ui/src/presets/kwai/megamenu/index.js index 45de85ac..47241d05 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/megamenu/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/megamenu/index.js @@ -15,7 +15,7 @@ export default { { 'p-2 items-center': props.orientation == 'horizontal', 'flex-col sm:w-48 p-0 py-1': props.orientation !== 'horizontal' } ] }), - menu: ({ props }) => ({ + rootList: ({ props }) => ({ class: [ // Flexbox 'sm:flex', @@ -48,7 +48,7 @@ export default { 'outline-none' ] }), - menuitem: ({ props }) => ({ + item: ({ props }) => ({ class: [ 'sm:relative static', { @@ -57,7 +57,7 @@ export default { } ] }), - content: ({ props, context }) => ({ + itemContent: ({ props, context }) => ({ class: [ // Shape { 'rounded-md': props.level < 1 && props.horizontal }, @@ -66,14 +66,13 @@ export default { { 'text-surface-500 dark:text-white/70': !context.focused && !context.active, 'text-surface-500 dark:text-white/70 bg-surface-200 dark:bg-surface-600/90': context.focused && !context.active, - 'text-primary-700 dark:text-surface-0/80 bg-primary-50 dark:bg-primary-400/30': context.focused && context.active, - 'text-primary-700 dark:text-surface-0/80 bg-primary-50 dark:bg-primary-400/30': !context.focused && context.active + 'bg-highlight': (context.focused && context.active) || context.active || (!context.focused && context.active) }, // Hover States { 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context.active, - 'hover:bg-primary-500/50 dark:hover:bg-primary-300/30 text-primary-700 dark:text-surface-0/80': context.active + 'hover:bg-highlight-emphasis': context.active }, // Transitions @@ -81,7 +80,7 @@ export default { 'duration-200' ] }), - action: { + itemLink: { class: [ 'relative', @@ -104,10 +103,10 @@ export default { 'overflow-hidden' ] }, - icon: { + itemIcon: { class: 'mr-2' }, - submenuicon: ({ props }) => ({ + submenuIcon: ({ props }) => ({ class: [ { 'ml-auto sm:ml-2': props.horizontal, @@ -115,7 +114,7 @@ export default { } ] }), - panel: ({ props }) => ({ + overlay: ({ props }) => ({ class: [ // Size 'w-auto', @@ -148,7 +147,7 @@ export default { submenu: { class: ['m-0 list-none', 'py-1 px-2 w-full sm:min-w-[14rem]'] }, - submenuheader: { + submenuLabel: { class: [ 'font-semibold', @@ -164,7 +163,7 @@ export default { separator: { class: 'border-t border-surface-200 dark:border-surface-600 my-1' }, - menubutton: { + button: { class: [ // Flexbox 'flex sm:hidden', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/menu/index.js b/frontend/packages/kwai-ui/src/presets/kwai/menu/index.js index fc971da9..acf6b8cf 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/menu/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/menu/index.js @@ -12,7 +12,7 @@ export default { 'border border-surface-200 dark:border-surface-700' ] }, - menu: { + list: { class: [ // Spacings and Shape 'list-none', @@ -21,7 +21,7 @@ export default { 'outline-none' ] }, - content: ({ context }) => ({ + itemContent: ({ context }) => ({ class: [ //Shape 'rounded-none', @@ -38,7 +38,7 @@ export default { 'hover:bg-surface-100 dark:bg-surface-700 dark:hover:bg-surface-400/10' ] }), - action: { + itemLink: { class: [ 'relative', // Flexbox @@ -60,7 +60,7 @@ export default { 'select-none' ] }, - icon: { + itemIcon: { class: [ // Spacing 'mr-2', @@ -69,10 +69,10 @@ export default { 'text-surface-600 dark:text-white/70' ] }, - label: { + itemLabel: { class: ['leading-none'] }, - submenuheader: { + submenuLabel: { class: [ // Font 'font-bold', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/menubar/index.js b/frontend/packages/kwai-ui/src/presets/kwai/menubar/index.js index 8c3fec0a..1c8f7755 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/menubar/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/menubar/index.js @@ -18,7 +18,7 @@ export default { 'border border-surface-200 dark:border-surface-700' ] }, - menu: ({ props }) => ({ + rootList: ({ props }) => ({ class: [ // Flexbox 'sm:flex', @@ -51,10 +51,10 @@ export default { 'outline-none' ] }), - menuitem: { + item: { class: 'sm:relative sm:w-auto w-full static' }, - content: ({ props, context }) => ({ + itemContent: ({ props, context }) => ({ class: [ // Shape { 'rounded-md': props.root }, @@ -63,14 +63,13 @@ export default { { 'text-surface-500 dark:text-white/70': !context.focused && !context.active, 'text-surface-500 dark:text-white/70 bg-surface-200 dark:bg-surface-600/90': context.focused && !context.active, - 'text-primary-700 dark:text-surface-0/80 bg-primary-50 dark:bg-primary-400/30': context.focused && context.active, - 'text-primary-700 dark:text-surface-0/80 bg-primary-50 dark:bg-primary-400/30': !context.focused && context.active + 'bg-highlight': (context.focused && context.active) || context.active || (!context.focused && context.active) }, // Hover States { 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context.active, - 'hover:bg-primary-500/50 dark:hover:bg-primary-300/30 text-primary-700 dark:text-surface-0/80': context.active + 'hover:bg-highlight-emphasis': context.active }, // Transitions @@ -78,7 +77,7 @@ export default { 'duration-200' ] }), - action: ({ context }) => ({ + itemLink: ({ context }) => ({ class: [ 'relative', @@ -104,10 +103,10 @@ export default { 'overflow-hidden' ] }), - icon: { + itemIcon: { class: 'mr-2' }, - submenuicon: ({ props }) => ({ + submenuIcon: ({ props }) => ({ class: [ { 'ml-auto sm:ml-2': props.root, @@ -117,6 +116,7 @@ export default { }), submenu: ({ props }) => ({ class: [ + 'flex flex-col', // Size 'w-full sm:w-48', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/message/index.js b/frontend/packages/kwai-ui/src/presets/kwai/message/index.js index 18bef54b..62e271db 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/message/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/message/index.js @@ -2,45 +2,50 @@ export default { root: ({ props }) => ({ class: [ // Spacing and Shape - 'my-4 mx-0', 'rounded-md', - 'border-solid border-0 border-l-[6px]', + 'outline-solid outline-0 outline-l-[6px]', // Colors { 'bg-blue-100/70 dark:bg-blue-500/20': props.severity == 'info', 'bg-green-100/70 dark:bg-green-500/20': props.severity == 'success', + 'bg-surface-100/70 dark:bg-surface-500/20': props.severity == 'secondary', 'bg-orange-100/70 dark:bg-orange-500/20': props.severity == 'warn', - 'bg-red-100/70 dark:bg-red-500/20': props.severity == 'error' + 'bg-red-100/70 dark:bg-red-500/20': props.severity == 'error', + 'bg-surface-950 dark:bg-surface-0': props.severity == 'contrast' }, { - 'border-blue-500 dark:border-blue-400': props.severity == 'info', - 'border-green-500 dark:border-green-400': props.severity == 'success', - 'border-orange-500 dark:border-orange-400': props.severity == 'warn', - 'border-red-500 dark:border-red-400': props.severity == 'error' + 'outline-blue-500 dark:outline-blue-400': props.severity == 'info', + 'outline-green-500 dark:outline-green-400': props.severity == 'success', + 'outline-surface-500 dark:outline-surface-400': props.severity == 'secondary', + 'outline-orange-500 dark:outline-orange-400': props.severity == 'warn', + 'outline-red-500 dark:outline-red-400': props.severity == 'error', + 'outline-surface-950 dark:outline-surface-0': props.severity == 'contrast' }, { 'text-blue-700 dark:text-blue-300': props.severity == 'info', 'text-green-700 dark:text-green-300': props.severity == 'success', + 'text-surface-700 dark:text-surface-300': props.severity == 'secondary', 'text-orange-700 dark:text-orange-300': props.severity == 'warn', - 'text-red-700 dark:text-red-300': props.severity == 'error' + 'text-red-700 dark:text-red-300': props.severity == 'error', + 'text-surface-0 dark:text-surface-950': props.severity == 'contrast' } ] }), - wrapper: { + content: { class: [ // Flexbox - 'flex items-center', + 'flex items-center h-full', // Spacing - 'py-5 px-7' + 'py-3 px-5 gap-2' ] }, icon: { class: [ // Sizing and Spacing 'w-6 h-6', - 'text-lg leading-none mr-2 shrink-0' + 'text-lg leading-none shrink-0' ] }, text: { @@ -50,7 +55,7 @@ export default { 'font-medium' ] }, - button: { + closeButton: { class: [ // Flexbox 'flex items-center justify-center', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/metergroup/index.js b/frontend/packages/kwai-ui/src/presets/kwai/metergroup/index.js index a820d8fe..1defe092 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/metergroup/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/metergroup/index.js @@ -7,7 +7,7 @@ export default { { 'flex-col': props.orientation == 'horizontal', 'flex-row': props.orientation == 'vertical' } ] }), - metercontainer: ({ props }) => ({ + meters: ({ props }) => ({ class: [ // Flexbox 'flex', @@ -41,10 +41,10 @@ export default { }, // Colors - 'bg-primary-500 dark:bg-primary-400' + 'bg-primary' ] }), - labellist: ({ props }) => ({ + labelList: ({ props }) => ({ class: [ // Display & Flexbox 'flex flex-wrap', @@ -63,7 +63,6 @@ export default { // Conditional Alignment - Vertical { - 'justify-end': props.labelOrientation === 'vertical' && props.labelPosition === 'end', 'justify-start': props.labelOrientation === 'vertical' && props.labelPosition === 'start' }, @@ -71,7 +70,7 @@ export default { 'm-0 p-0 list-none' ] }), - labellistitem: { + label: { class: [ // Flexbox 'inline-flex', @@ -79,13 +78,13 @@ export default { 'gap-2' ] }, - labellisttype: { + labelMarker: { class: [ // Display 'inline-flex', // Background Color - 'bg-primary-500 dark:bg-primary-400', + 'bg-primary', // Size 'w-2 h-2', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/multiselect/index.js b/frontend/packages/kwai-ui/src/presets/kwai/multiselect/index.js index b2cc2358..515bc434 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/multiselect/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/multiselect/index.js @@ -21,7 +21,7 @@ export default { 'duration-200', // States - { 'hover:border-primary-500 dark:hover:border-primary-300': !props.invalid }, + { 'hover:border-primary': !props.invalid }, { 'outline-none outline-offset-0 ring ring-primary-400/50 dark:ring-primary-300/50': state.focused }, // Misc @@ -30,19 +30,17 @@ export default { { 'opacity-60': props.disabled, 'pointer-events-none': props.disabled, 'cursor-default': props.disabled } ] }), - labelContainer: { - class: 'overflow-hidden flex flex-auto cursor-pointer ' - }, + labelContainer: 'overflow-hidden flex flex-auto cursor-pointer', label: ({ props }) => ({ class: [ - 'leading-none', + 'leading-[normal]', 'block ', // Spacing { 'p-3': props.display !== 'chip', 'py-3 px-3': props.display === 'chip' && !props?.modelValue?.length, - 'py-1.5 px-3': props.display === 'chip' && props?.modelValue?.length > 0 + 'py-[0.375rem] px-3': props.display === 'chip' && props?.modelValue?.length > 0 }, // Color @@ -56,44 +54,7 @@ export default { 'overflow-hidden whitespace-nowrap cursor-pointer overflow-ellipsis' ] }), - token: { - class: [ - // Flex - 'inline-flex items-center', - - // Spacings - 'py-1.5 px-3 mr-2', - - // Shape - 'rounded-[1.14rem]', - - // Colors - 'bg-surface-200 dark:bg-surface-700', - 'text-surface-700 dark:text-white/70', - - // Misc - 'cursor-default' - ] - }, - removeTokenIcon: { - class: [ - // Shape - 'rounded-md leading-6', - - // Spacing - 'ml-2', - - // Size - 'w-4 h-4', - - // Transition - 'transition duration-200 ease-in-out', - - // Misc - 'cursor-pointer' - ] - }, - trigger: { + dropdown: { class: [ // Flexbox 'flex items-center justify-center', @@ -111,10 +72,9 @@ export default { 'rounded-br-md' ] }, - panel: { + overlay: { class: [ // Position - 'absolute top-0 left-0', // Shape 'border-0 dark:border', @@ -131,7 +91,7 @@ export default { class: [ 'flex items-center justify-between', // Spacing - 'py-3 px-5', + 'py-3 px-5 gap-2', 'm-0', //Shape @@ -142,265 +102,13 @@ export default { // Color 'text-surface-700 dark:text-white/80', 'bg-surface-100 dark:bg-surface-800', - 'border-surface-300 dark:border-surface-700' - ] - }, - headerCheckboxContainer: { - class: [ - 'relative', - - // Alignment - 'inline-flex', - 'align-bottom', + 'border-surface-300 dark:border-surface-700', - // Size - 'w-6', - 'h-6', - - // Misc - 'cursor-pointer', - 'select-none' + '[&_[data-pc-name=pcfiltercontainer]]:!flex-auto', + '[&_[data-pc-name=pcfilter]]:w-full' ] }, - headerCheckbox: { - root: { - class: [ - 'relative', - - // Alignment - 'inline-flex', - 'align-bottom', - - // Size - 'w-6', - 'h-6', - - // Spacing - 'mr-2', - - // Misc - 'cursor-pointer', - 'select-none' - ] - }, - box: ({ props, context }) => ({ - class: [ - // Alignment - 'flex', - 'items-center', - 'justify-center', - - // Size - 'w-6', - 'h-6', - - // Shape - 'rounded-md', - 'border-2', - - // Colors - { - 'border-surface-200 bg-surface-0 dark:border-surface-700 dark:bg-surface-900': !context.checked, - 'border-primary-500 bg-primary-500 dark:border-primary-400 dark:bg-primary-400': context.checked - }, - - // States - { - 'peer-hover:border-primary-500 dark:peer-hover:border-primary-400': !props.disabled && !context.checked, - 'peer-hover:bg-primary-600 dark:peer-hover:bg-primary-300 peer-hover:border-primary-700 dark:peer-hover:border-primary-300': !props.disabled && context.checked, - 'peer-focus-visible:border-primary-500 dark:peer-focus-visible:border-primary-400 peer-focus-visible:ring-2 peer-focus-visible:ring-primary-400/20 dark:peer-focus-visible:ring-primary-300/20': !props.disabled, - 'cursor-default opacity-60': props.disabled - }, - - // Transitions - 'transition-colors', - 'duration-200' - ] - }), - input: { - class: [ - 'peer', - - // Size - 'w-full ', - 'h-full', - - // Position - 'absolute', - 'top-0 left-0', - 'z-10', - - // Spacing - 'p-0', - 'm-0', - - // Shape - 'opacity-0', - 'rounded-md', - 'outline-none', - 'border-2 border-surface-200 dark:border-surface-700', - - // Misc - 'appearance-none', - 'cursor-pointer' - ] - }, - icon: { - class: [ - // Font - 'text-base leading-none', - - // Size - 'w-4', - 'h-4', - - // Colors - 'text-white dark:text-surface-900', - - // Transitions - 'transition-all', - 'duration-200' - ] - } - }, - itemCheckbox: { - root: { - class: [ - 'relative', - - // Alignment - 'inline-flex', - 'align-bottom', - - // Size - 'w-6', - 'h-6', - - // Spacing - 'mr-2', - - // Misc - 'cursor-pointer', - 'select-none' - ] - }, - box: ({ props, context }) => ({ - class: [ - // Alignment - 'flex', - 'items-center', - 'justify-center', - - // Size - 'w-6', - 'h-6', - - // Shape - 'rounded-md', - 'border-2', - - // Colors - { - 'border-surface-200 bg-surface-0 dark:border-surface-700 dark:bg-surface-900': !context.checked, - 'border-primary-500 bg-primary-500 dark:border-primary-400 dark:bg-primary-400': context.checked - }, - - // States - { - 'peer-hover:border-primary-500 dark:peer-hover:border-primary-400': !props.disabled && !context.checked, - 'peer-hover:bg-primary-600 dark:peer-hover:bg-primary-300 peer-hover:border-primary-700 dark:peer-hover:border-primary-300': !props.disabled && context.checked, - 'peer-focus-visible:border-primary-500 dark:peer-focus-visible:border-primary-400 peer-focus-visible:ring-2 peer-focus-visible:ring-primary-400/20 dark:peer-focus-visible:ring-primary-300/20': !props.disabled, - 'cursor-default opacity-60': props.disabled - }, - - // Transitions - 'transition-colors', - 'duration-200' - ] - }), - input: { - class: [ - 'peer', - - // Size - 'w-full ', - 'h-full', - - // Position - 'absolute', - 'top-0 left-0', - 'z-10', - - // Spacing - 'p-0', - 'm-0', - - // Shape - 'opacity-0', - 'rounded-md', - 'outline-none', - 'border-2 border-surface-200 dark:border-surface-700', - - // Misc - 'appearance-none', - 'cursor-pointer' - ] - }, - icon: { - class: [ - // Font - 'text-base leading-none', - - // Size - 'w-4', - 'h-4', - - // Colors - 'text-white dark:text-surface-900', - - // Transitions - 'transition-all', - 'duration-200' - ] - } - }, - closeButton: { - class: [ - 'relative', - - // Flexbox and Alignment - 'flex items-center justify-center', - - // Size and Spacing - 'mr-2', - 'last:mr-0', - 'w-8 h-8', - - // Shape - 'border-0', - 'rounded-full', - - // Colors - 'text-surface-500', - 'bg-transparent', - - // Transitions - 'transition duration-200 ease-in-out', - - // States - 'hover:text-surface-700 dark:hover:text-white/80', - 'hover:bg-surface-100 dark:hover:bg-surface-800/80', - 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-inset', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - - // Misc - 'overflow-hidden' - ] - }, - closeButtonIcon: { - class: 'w-4 h-4 inline-block' - }, - wrapper: { + listContainer: { class: [ // Sizing 'max-h-[200px]', @@ -412,7 +120,7 @@ export default { list: { class: 'py-3 list-none m-0' }, - item: ({ context }) => ({ + option: ({ context }) => ({ class: [ // Font 'font-normal', @@ -430,13 +138,12 @@ export default { // Spacing 'm-0', - 'py-3 px-5', + 'py-3 px-5 gap-2', // Color { 'text-surface-700 dark:text-white/80': !context.focused && !context.selected }, { 'bg-surface-200 dark:bg-surface-600/60 text-surface-700 dark:text-white/80': context.focused && !context.selected }, - { 'bg-primary-100 dark:bg-primary-400/40 text-primary-700 dark:text-white/80': context.focused && context.selected }, - { 'bg-primary-50 dark:bg-primary-400/40 text-primary-700 dark:text-white/80': !context.focused && context.selected }, + { 'bg-highlight': context.selected }, //States { 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context.focused && !context.selected }, @@ -452,7 +159,7 @@ export default { 'whitespace-nowrap' ] }), - itemgroup: { + optionGroup: { class: [ //Font 'font-bold', @@ -469,62 +176,7 @@ export default { 'cursor-auto' ] }, - filtercontainer: { - class: 'relative w-full mx-2' - }, - filterinput: { - class: [ - // Font - 'font-sans', - 'leading-none', - - // Sizing - 'pr-7 py-3 px-3', - '-mr-7', - 'w-full', - - //Color - 'text-surface-700 dark:text-white/80', - 'bg-surface-0 dark:bg-surface-900', - 'border-surface-200 dark:border-surface-700', - 'placeholder:text-surface-400 dark:placeholder:text-surface-500', - - // Shape - 'border', - 'rounded-lg', - 'appearance-none', - - // Transitions - 'transition', - 'duration-200', - - // States - 'hover:border-primary-500 dark:hover:border-primary-300', - 'focus:ring focus:outline-none focus:outline-offset-0', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - - // Misc - 'appearance-none' - ] - }, - filtericon: { - class: ['absolute', 'top-1/2 right-3', '-mt-2'] - }, - clearicon: { - class: [ - // Color - 'text-surface-500', - - // Position - 'absolute', - 'top-1/2', - 'right-12', - - // Spacing - '-mt-2' - ] - }, - emptymessage: { + emptyMessage: { class: [ // Font 'leading-none', @@ -537,6 +189,9 @@ export default { 'bg-transparent' ] }, + loadingIcon: { + class: 'text-surface-400 dark:text-surface-500 animate-spin' + }, transition: { enterFromClass: 'opacity-0 scale-y-[0.8]', enterActiveClass: 'transition-[transform,opacity] duration-[120ms] ease-[cubic-bezier(0,0,0.2,1)]', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/orderlist/index.js b/frontend/packages/kwai-ui/src/presets/kwai/orderlist/index.js index c05d631f..2c1d112f 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/orderlist/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/orderlist/index.js @@ -1,10 +1,5 @@ export default { - root: { - class: [ - // Flexbox - 'flex' - ] - }, + root: 'flex', controls: { class: [ // Flexbox & Alignment @@ -14,244 +9,5 @@ export default { 'p-5' ] }, - moveupbutton: { - root: ({ context }) => ({ - class: [ - // Flexbox & Alignment - 'relative inline-flex items-center justify-center', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Spacing & Size - 'w-12', - 'm-0', - 'px-0 py-3', - - // Transitions - 'transition duration-200 ease-in-out', - - // State - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - { 'cursor-default pointer-events-none opacity-60': context.disabled }, - - // Interactivity - 'cursor-pointer user-select-none' - ] - }), - label: { - class: [ - // Flexbox - 'flex-initial', - - // Size - 'w-0' - ] - } - }, - movedownbutton: { - root: ({ context }) => ({ - class: [ - // Flexbox & Alignment - 'relative inline-flex items-center justify-center', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Spacing & Size - 'w-12', - 'm-0', - 'px-0 py-3', - - // Transitions - 'transition duration-200 ease-in-out', - - // State - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - { 'cursor-default pointer-events-none opacity-60': context.disabled }, - - // Interactivity - 'cursor-pointer user-select-none' - ] - }), - label: { - class: [ - // Flexbox - 'flex-initial', - - // Size - 'w-0' - ] - } - }, - movetopbutton: { - root: ({ context }) => ({ - class: [ - // Flexbox & Alignment - 'relative inline-flex items-center justify-center', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Spacing & Size - 'w-12', - 'm-0', - 'px-0 py-3', - - // Transitions - 'transition duration-200 ease-in-out', - - // State - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - { 'cursor-default pointer-events-none opacity-60': context.disabled }, - - // Interactivity - 'cursor-pointer user-select-none' - ] - }), - label: { - class: [ - // Flexbox - 'flex-initial', - - // Size - 'w-0' - ] - } - }, - movebottombutton: { - root: ({ context }) => ({ - class: [ - // Flexbox & Alignment - 'relative inline-flex items-center justify-center', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Spacing & Size - 'w-12', - 'm-0', - 'px-0 py-3', - - // Transitions - 'transition duration-200 ease-in-out', - - // State - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - { 'cursor-default pointer-events-none opacity-60': context.disabled }, - - // Interactivity - 'cursor-pointer user-select-none' - ] - }), - label: { - class: [ - // Flexbox - 'flex-initial', - - // Size - 'w-0' - ] - } - }, - container: { - class: ['flex-auto'] - }, - header: { - class: [ - 'font-bold', - - // Shape - 'border-b-0 rounded-t-md', - - // Spacing - 'p-5', - - // Color - 'text-surface-700 dark:text-white/80', - 'bg-surface-50 dark:bg-surface-800', - 'border border-surface-200 dark:border-surface-700' - ] - }, - list: { - class: [ - // Spacing - 'list-none m-0 p-0', - - // Size - 'min-h-[12rem] max-h-[24rem]', - - // Shape - 'rounded-b-md', - - // Color - 'text-surface-600 dark:text-white/80', - 'bg-surface-0 dark:bg-surface-800', - 'border border-surface-200 dark:border-surface-700', - - // Spacing - 'py-3 px-0', - - // Focus & Outline - 'outline-none', - - // Misc - 'overflow-auto' - ] - }, - item: ({ context }) => ({ - class: [ - // Position - 'relative', - - // Spacing - 'py-3 px-5 m-0', - - // Shape - 'border-none', - - // Transition - 'transition duration-200', - - // Color - 'text-surface-700 dark:text-white/80', - { 'bg-primary-500/20 dark:bg-primary-300/20': context.active && !context.focused }, - { 'bg-primary-500/30 dark:bg-primary-400/30': context.active && context.focused }, - { 'bg-surface-100 dark:bg-surface-700/70': !context.active && context.focused }, - - // State - 'hover:bg-surface-100 dark:hover:bg-surface-700', - - // Misc - 'cursor-pointer overflow-hidden' - ] - }) + container: 'flex-auto' }; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/organizationchart/index.js b/frontend/packages/kwai-ui/src/presets/kwai/organizationchart/index.js index e0cc87a8..703b3bf3 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/organizationchart/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/organizationchart/index.js @@ -17,7 +17,7 @@ export default { 'py-0 px-3' ] }, - node: ({ props, context }) => ({ + node: ({ context }) => ({ class: [ 'relative inline-block', @@ -32,21 +32,20 @@ export default { 'text-surface-600 dark:text-white/80': !context?.selected, 'bg-surface-0 dark:bg-surface-800': !context?.selected, 'border-surface-200 dark:border-surface-700': !context?.selected, - 'text-primary-700 dark:text-surface-0': context?.selected, - 'bg-primary-50 dark:bg-primary-400/30': context?.selected, + 'bg-highlight': context?.selected, 'border-primary-200 dark:border-primary-600': context?.selected }, // States { 'hover:bg-surface-100 dark:hover:bg-surface-700': context?.selectable && !context?.selected, - 'hover:bg-primary-100 dark:hover:bg-primary-300/30': context?.selectable && context?.selected + 'hover:bg-highlight-emphasis': context?.selectable && context?.selected }, { 'cursor-pointer': context?.selectable } ] }), - linecell: { + lineCell: { class: [ // Alignment 'text-center align-top', @@ -55,7 +54,7 @@ export default { 'py-0 px-3' ] }, - linedown: { + connectorDown: { class: [ // Spacing 'mx-auto my-0', @@ -67,7 +66,7 @@ export default { 'bg-surface-200 dark:bg-surface-700' ] }, - lineleft: ({ context }) => ({ + connectorLeft: ({ context }) => ({ class: [ // Alignment 'text-center align-top', @@ -83,7 +82,7 @@ export default { 'border-surface-200 dark:border-surface-700' ] }), - lineright: ({ context }) => ({ + connectorRight: ({ context }) => ({ class: [ // Alignment 'text-center align-top', @@ -98,10 +97,10 @@ export default { { 'border-t border-surface-200 dark:border-surface-700': context.lineTop } ] }), - nodecell: { + nodeCell: { class: 'text-center align-top py-0 px-3' }, - nodetoggler: { + nodeToggleButton: { class: [ // Position 'absolute bottom-[-0.75rem] left-2/4 -ml-3', @@ -126,7 +125,7 @@ export default { 'cursor-pointer no-underline select-none' ] }, - nodetogglericon: { + nodeToggleButtonIcon: { class: [ // Position 'relative inline-block', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/paginator/index.js b/frontend/packages/kwai-ui/src/presets/kwai/paginator/index.js index 035907bf..c5b79fa3 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/paginator/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/paginator/index.js @@ -15,7 +15,7 @@ export default { 'text-surface-500 dark:text-white/60' ] }, - firstpagebutton: ({ context }) => ({ + first: ({ context }) => ({ class: [ 'relative', @@ -46,7 +46,7 @@ export default { { 'cursor-default pointer-events-none opacity-60': context.disabled } ] }), - previouspagebutton: ({ context }) => ({ + prev: ({ context }) => ({ class: [ 'relative', @@ -77,7 +77,7 @@ export default { { 'cursor-default pointer-events-none opacity-60': context.disabled } ] }), - nextpagebutton: ({ context }) => ({ + next: ({ context }) => ({ class: [ 'relative', @@ -108,7 +108,7 @@ export default { { 'cursor-default pointer-events-none opacity-60': context.disabled } ] }), - lastpagebutton: ({ context }) => ({ + last: ({ context }) => ({ class: [ 'relative', @@ -139,7 +139,7 @@ export default { { 'cursor-default pointer-events-none opacity-60': context.disabled } ] }), - pagebutton: ({ context }) => ({ + page: ({ context }) => ({ class: [ 'relative', @@ -156,7 +156,7 @@ export default { // Color 'text-surface-500 dark:text-white/80', { - 'bg-primary-50 border-primary-50 dark:border-transparent text-primary-700 dark:text-surface-0 dark:bg-primary-400/30': context.active + 'bg-highlight': context.active }, // State @@ -173,361 +173,6 @@ export default { { 'cursor-default pointer-events-none opacity-60': context.disabled } ] }), - rowperpagedropdown: { - root: ({ props, state }) => ({ - class: [ - // Display and Position - 'inline-flex', - 'relative', - - // Shape - 'h-12', - 'rounded-md', - - // Spacing - 'mx-2', - - // Color and Background - 'bg-surface-0 dark:bg-surface-900', - 'border border-surface-300 dark:border-surface-700', - - // Transitions - 'transition-all', - 'duration-200', - - // States - 'hover:border-primary-500 dark:hover:border-primary-300', - { 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50': !state.focused }, - - // Misc - 'cursor-pointer', - 'select-none', - { 'opacity-60': props.disabled, 'pointer-events-none': props.disabled, 'cursor-default': props.disabled } - ] - }), - input: { - class: [ - //Font - 'font-sans', - 'leading-5', - - // Display - 'block', - 'flex-auto', - - // Color and Background - 'bg-transparent', - 'border-0', - 'text-surface-800 dark:text-white/80', - - // Sizing and Spacing - 'w-[1%]', - 'p-3 pr-0', - - //Shape - 'rounded-none', - - // Transitions - 'transition', - 'duration-200', - - // States - 'focus:outline-none focus:shadow-none', - - // Misc - 'relative', - 'cursor-pointer', - 'overflow-hidden overflow-ellipsis', - 'whitespace-nowrap', - 'appearance-none' - ] - }, - trigger: { - class: [ - // Flexbox - 'flex items-center justify-center', - 'shrink-0', - - // Color and Background - 'bg-transparent', - 'text-surface-500', - - // Size - 'w-12', - - // Shape - 'rounded-tr-md', - 'rounded-br-md' - ] - }, - panel: { - class: [ - // Position - 'absolute top-0 left-0', - - // Shape - 'border-0 dark:border', - 'rounded-md', - 'shadow-md', - - // Color - 'bg-surface-0 dark:bg-surface-800', - 'text-surface-800 dark:text-white/80', - 'dark:border-surface-700' - ] - }, - wrapper: { - class: [ - // Sizing - 'max-h-[200px]', - - // Misc - 'overflow-auto' - ] - }, - list: { - class: 'py-3 list-none m-0' - }, - item: ({ context }) => ({ - class: [ - // Font - 'font-normal', - 'leading-none', - - // Position - 'relative', - - // Shape - 'border-0', - 'rounded-none', - - // Spacing - 'm-0', - 'py-3 px-5', - - // Color - { 'text-surface-700 dark:text-white/80': !context.focused && !context.selected }, - { 'bg-surface-50 dark:bg-surface-600/60 text-surface-700 dark:text-white/80': context.focused && !context.selected }, - { 'bg-primary-100 dark:bg-primary-400/40 text-primary-700 dark:text-white/80': context.focused && context.selected }, - { 'bg-primary-50 dark:bg-primary-400/40 text-primary-700 dark:text-white/80': !context.focused && context.selected }, - - //States - { 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context.focused && !context.selected }, - { 'hover:text-surface-700 hover:bg-surface-100 dark:hover:text-white dark:hover:bg-surface-600/80': context.focused && !context.selected }, - - // Transitions - 'transition-shadow', - 'duration-200', - - // Misc - 'cursor-pointer', - 'overflow-hidden', - 'whitespace-nowrap' - ] - }) - }, - jumptopageinput: { - root: { - class: 'inline-flex mx-2' - }, - input: { - root: { - class: [ - 'relative', - - //Font - 'font-sans', - 'leading-none', - - // Display - 'block', - 'flex-auto', - - // Colors - 'text-surface-600 dark:text-surface-200', - 'placeholder:text-surface-400 dark:placeholder:text-surface-500', - 'bg-surface-0 dark:bg-surface-900', - 'border border-surface-300 dark:border-surface-600', - - // Sizing and Spacing - 'w-[1%] max-w-[3rem]', - 'p-3 m-0', - - //Shape - 'rounded-md', - - // Transitions - 'transition', - 'duration-200', - - // States - 'hover:border-primary-500 dark:hover:border-primary-400', - 'focus:outline-none focus:shadow-none', - 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-500/50 dark:focus:ring-primary-400/50', - - // Misc - 'cursor-pointer', - 'overflow-hidden overflow-ellipsis', - 'whitespace-nowrap', - 'appearance-none' - ] - } - } - }, - jumptopagedropdown: { - root: ({ props, state }) => ({ - class: [ - // Display and Position - 'inline-flex', - 'relative', - - // Shape - 'h-12', - 'rounded-md', - - // Color and Background - 'bg-surface-0 dark:bg-surface-900', - 'border border-surface-300 dark:border-surface-700', - - // Transitions - 'transition-all', - 'duration-200', - - // States - 'hover:border-primary-500 dark:hover:border-primary-300', - { 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50': !state.focused }, - - // Misc - 'cursor-pointer', - 'select-none', - { 'opacity-60': props.disabled, 'pointer-events-none': props.disabled, 'cursor-default': props.disabled } - ] - }), - input: { - class: [ - //Font - 'font-sans', - 'leading-none', - - // Display - 'block', - 'flex-auto', - - // Color and Background - 'bg-transparent', - 'border-0', - 'text-surface-800 dark:text-white/80', - - // Sizing and Spacing - 'w-[1%]', - 'p-3', - - //Shape - 'rounded-none', - - // Transitions - 'transition', - 'duration-200', - - // States - 'focus:outline-none focus:shadow-none', - - // Misc - 'relative', - 'cursor-pointer', - 'overflow-hidden overflow-ellipsis', - 'whitespace-nowrap', - 'appearance-none' - ] - }, - trigger: { - class: [ - // Flexbox - 'flex items-center justify-center', - 'shrink-0', - - // Color and Background - 'bg-transparent', - 'text-surface-500', - - // Size - 'w-12', - - // Shape - 'rounded-tr-md', - 'rounded-br-md' - ] - }, - panel: { - class: [ - // Position - 'absolute top-0 left-0', - - // Shape - 'border-0 dark:border', - 'rounded-md', - 'shadow-md', - - // Color - 'bg-surface-0 dark:bg-surface-800', - 'text-surface-800 dark:text-white/80', - 'dark:border-surface-700' - ] - }, - wrapper: { - class: [ - // Sizing - 'max-h-[200px]', - - // Misc - 'overflow-auto' - ] - }, - list: { - class: 'py-3 list-none m-0' - }, - item: ({ context }) => ({ - class: [ - // Font - 'font-normal', - 'leading-none', - - // Position - 'relative', - - // Shape - 'border-0', - 'rounded-none', - - // Spacing - 'm-0', - 'py-3 px-5', - - // Color - { 'text-surface-700 dark:text-white/80': !context.focused && !context.selected }, - { 'bg-surface-50 dark:bg-surface-600/60 text-surface-700 dark:text-white/80': context.focused && !context.selected }, - { 'bg-primary-100 dark:bg-primary-400/40 text-primary-700 dark:text-white/80': context.focused && context.selected }, - { 'bg-primary-50 dark:bg-primary-400/40 text-primary-700 dark:text-white/80': !context.focused && context.selected }, - - //States - { 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context.focused && !context.selected }, - { 'hover:text-surface-700 hover:bg-surface-100 dark:hover:text-white dark:hover:bg-surface-600/80': context.focused && !context.selected }, - - // Transitions - 'transition-shadow', - 'duration-200', - - // Misc - 'cursor-pointer', - 'overflow-hidden', - 'whitespace-nowrap' - ] - }) - }, - start: { - class: 'mr-auto' - }, - end: { - class: 'ml-auto' - } + contentStart: 'mr-auto', + contentEnd: 'ml-auto' }; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/panelmenu/index.js b/frontend/packages/kwai-ui/src/presets/kwai/panelmenu/index.js index e6072e89..0c79117d 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/panelmenu/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/panelmenu/index.js @@ -5,7 +5,7 @@ export default { header: { class: ['rounded-md', 'outline-none', 'focus-visible:outline-none focus-visible:outline-offset-0 focus-visible:ring focus-visible:ring-primary-400/50 dark:focus-visible:ring-primary-300/50'] }, - headercontent: ({ context, instance }) => ({ + headerContent: ({ context, instance }) => ({ class: [ // Shape 'rounded-t-md', @@ -18,7 +18,7 @@ export default { { 'text-surface-900': context.active }, // States - 'hover:bg-surface-100 dark:hover:bg-surface-700/80', + 'hover:bg-surface-100 dark:hover:bg-surface-700', 'hover:text-surface-900', // Transition @@ -26,7 +26,7 @@ export default { 'transition-shadow duration-200' ] }), - headeraction: { + headerLink: { class: [ 'relative', @@ -44,16 +44,16 @@ export default { 'select-none cursor-pointer no-underline' ] }, - headerlabel: { + headerLabel: { class: 'leading-none' }, headerIcon: { class: 'mr-2' }, - submenuicon: { + submenuIcon: { class: 'mr-2' }, - menucontent: { + content: { class: [ // Spacing 'py-2', @@ -68,10 +68,10 @@ export default { 'border-surface-200 dark:border-surface-700' ] }, - menu: { + rootList: { class: ['outline-none', 'm-0 p-0 list-none'] }, - content: { + itemContent: { class: [ // Shape 'border-none rounded-none', @@ -83,7 +83,7 @@ export default { 'transition-shadow duration-200' ] }, - action: ({ context }) => ({ + itemLink: ({ context }) => ({ class: [ 'relative', @@ -110,7 +110,7 @@ export default { 'select-none overflow-hidden' ] }), - icon: { + itemIcon: { class: 'mr-2' }, submenu: { diff --git a/frontend/packages/kwai-ui/src/presets/kwai/password/index.js b/frontend/packages/kwai-ui/src/presets/kwai/password/index.js index 9d4606b8..f0fde2b6 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/password/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/password/index.js @@ -1,14 +1,15 @@ export default { root: ({ props }) => ({ class: [ - 'inline-flex relative', + 'relative', + { 'flex [&>input]:w-full': props.fluid, 'inline-flex': !props.fluid }, { 'opacity-60 select-none pointer-events-none cursor-default': props.disabled }, { '[&>input]:pr-10': props.toggleMask } ] }), - panel: { + overlay: { class: [ // Spacing 'p-5', @@ -40,7 +41,7 @@ export default { 'bg-surface-100 dark:bg-surface-700' ] }, - meterlabel: ({ instance }) => ({ + meterLabel: ({ instance }) => ({ class: [ // Size 'h-full', @@ -56,59 +57,12 @@ export default { 'transition-all duration-1000 ease-in-out' ] }), - showicon: { + maskIcon: { class: ['absolute top-1/2 right-3 -mt-2 z-10', 'text-surface-600 dark:text-white/70'] }, - hideicon: { + unmaskIcon: { class: ['absolute top-1/2 right-3 -mt-2 z-10', 'text-surface-600 dark:text-white/70'] }, - input: { - root: ({ props, context, parent }) => ({ - class: [ - // Font - 'font-sans leading-none', - - // Flex - { 'flex-1 w-[1%]': parent.instance.$name == 'InputGroup' }, - - // Spacing - 'm-0', - { - 'px-4 py-4': props.size == 'large', - 'px-2 py-2': props.size == 'small', - 'p-3': props.size == null - }, - 'w-full', - - // Shape - { 'rounded-md': parent.instance.$name !== 'InputGroup' }, - { 'first:rounded-l-md rounded-none last:rounded-r-md': parent.instance.$name == 'InputGroup' }, - { 'border-0 border-y border-l last:border-r': parent.instance.$name == 'InputGroup' }, - { 'first:ml-0 -ml-px': parent.instance.$name == 'InputGroup' && !props.showButtons }, - - // Colors - 'text-surface-600 dark:text-surface-200', - 'placeholder:text-surface-400 dark:placeholder:text-surface-500', - 'bg-surface-0 dark:bg-surface-900', - 'border', - { 'border-surface-300 dark:border-surface-600': !parent.props.invalid }, - - // Invalid State - { 'border-red-500 dark:border-red-400': parent.props.invalid }, - - // States - { - 'hover:border-primary-500 dark:hover:border-primary-400': !context.disabled && !parent.props.invalid, - 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-500/50 dark:focus:ring-primary-400/50 focus:z-10': !context.disabled, - 'opacity-60 select-none pointer-events-none cursor-default': context.disabled - }, - - // Misc - 'appearance-none', - 'transition-colors duration-200' - ] - }) - }, transition: { enterFromClass: 'opacity-0 scale-y-[0.8]', enterActiveClass: 'transition-[transform,opacity] duration-[120ms] ease-[cubic-bezier(0,0,0.2,1)]', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/picklist/index.js b/frontend/packages/kwai-ui/src/presets/kwai/picklist/index.js index dedbeb75..370e43b4 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/picklist/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/picklist/index.js @@ -1,11 +1,6 @@ export default { - root: { - class: [ - // Flexbox - 'flex lg:flex-row flex-col' - ] - }, - sourcecontrols: { + root: 'flex [&_[data-pc-name=pclist]]:h-full', + sourceControls: { class: [ // Flexbox & Alignment 'flex lg:flex-col justify-center gap-2', @@ -14,633 +9,40 @@ export default { 'p-5' ] }, - sourcemoveupbutton: { - root: ({ context }) => ({ - class: [ - // Flexbox & Alignment - 'relative inline-flex items-center justify-center', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Spacing & Size - 'w-12', - 'm-0', - 'px-0 py-3', - - // Transitions - 'transition duration-200 ease-in-out', - - // State - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - { 'cursor-default pointer-events-none opacity-60': context.disabled }, - - // Interactivity - 'cursor-pointer user-select-none' - ] - }), - label: { - class: [ - // Flexbox - 'flex-initial', - - // Size - 'w-0' - ] - } - }, - sourcemovetopbutton: { - root: ({ context }) => ({ - class: [ - // Flexbox & Alignment - 'relative inline-flex items-center justify-center', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Spacing & Size - 'w-12', - 'm-0', - 'px-0 py-3', - - // Transitions - 'transition duration-200 ease-in-out', - - // State - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - { 'cursor-default pointer-events-none opacity-60': context.disabled }, - - // Interactivity - 'cursor-pointer user-select-none' - ] - }), - label: { - class: [ - // Flexbox - 'flex-initial', - - // Size - 'w-0' - ] - } - }, - sourcemovedownbutton: { - root: ({ context }) => ({ - class: [ - // Flexbox & Alignment - 'relative inline-flex items-center justify-center', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Spacing & Size - 'w-12', - 'm-0', - 'px-0 py-3', - - // Transitions - 'transition duration-200 ease-in-out', - - // State - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - { 'cursor-default pointer-events-none opacity-60': context.disabled }, - - // Interactivity - 'cursor-pointer user-select-none' - ] - }), - label: { - class: [ - // Flexbox - 'flex-initial', - - // Size - 'w-0' - ] - } - }, - sourcemovebottombutton: { - root: ({ context }) => ({ - class: [ - // Flexbox & Alignment - 'relative inline-flex items-center justify-center', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Spacing & Size - 'w-12', - 'm-0', - 'px-0 py-3', - - // Transitions - 'transition duration-200 ease-in-out', - - // State - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - { 'cursor-default pointer-events-none opacity-60': context.disabled }, - - // Interactivity - 'cursor-pointer user-select-none' - ] - }), - label: { - class: [ - // Flexbox - 'flex-initial', - - // Size - 'w-0' - ] - } - }, - sourcewrapper: { - class: 'grow shrink basis-2/4' - }, - sourceheader: { + sourceListContainer: { class: [ - 'font-bold', - - // Shape - 'border-b-0 rounded-t-md', - - // Spacing - 'p-5', - - // Color - 'text-surface-700 dark:text-white/80', - 'bg-surface-50 dark:bg-surface-800', - 'border border-surface-200 dark:border-surface-700' - ] - }, - sourcelist: { - class: [ - // Spacing - 'list-none m-0 p-0', - - // Size - 'min-h-[12rem] max-h-[24rem]', + // Flexbox + 'grow shrink basis-2/4', // Shape - 'rounded-b-md', + 'rounded-md', // Color - 'text-surface-600 dark:text-white/80', - 'bg-surface-0 dark:bg-surface-800', + 'bg-surface-0 dark:bg-surface-900', 'border border-surface-200 dark:border-surface-700', - - // Spacing - 'py-3 px-0', - - // Focus & Outline - 'outline-none', - - // Misc - 'overflow-auto' + 'outline-none' ] }, - item: ({ context }) => ({ - class: [ - // Position - 'relative', - - // Spacing - 'py-3 px-5 m-0', - - // Shape - 'border-none', - - // Transition - 'transition duration-200', - - // Color - 'text-surface-700 dark:text-white/80', - { 'bg-primary-500/20 dark:bg-primary-300/20': context.active && !context.focused }, - { 'bg-primary-500/30 dark:bg-primary-400/30': context.active && context.focused }, - { 'bg-surface-100 dark:bg-surface-700/70': !context.active && context.focused }, - - // State - 'hover:bg-surface-100 dark:hover:bg-surface-700', - - // Misc - 'cursor-pointer overflow-hidden' - ] - }), - buttons: { + transferControls: { class: 'flex lg:flex-col justify-center gap-2 p-5' }, - movetotargetbutton: { - root: ({ context }) => ({ - class: [ - // Flexbox & Alignment - 'relative inline-flex items-center justify-center', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Spacing & Size - 'w-12', - 'm-0', - 'px-0 py-3', - - // Transitions - 'transition duration-200 ease-in-out', - - // State - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - { 'cursor-default pointer-events-none opacity-60': context.disabled }, - - // Interactivity - 'cursor-pointer user-select-none' - ] - }), - label: { - class: [ - // Flexbox - 'flex-initial', - - // Size - 'w-0' - ] - } - }, - movealltotargetbutton: { - root: ({ context }) => ({ - class: [ - // Flexbox & Alignment - 'relative inline-flex items-center justify-center', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Spacing & Size - 'w-12', - 'm-0', - 'px-0 py-3', - - // Transitions - 'transition duration-200 ease-in-out', - - // State - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - { 'cursor-default pointer-events-none opacity-60': context.disabled }, - - // Interactivity - 'cursor-pointer user-select-none' - ] - }), - label: { - class: [ - // Flexbox - 'flex-initial', - - // Size - 'w-0' - ] - } - }, - movetosourcebutton: { - root: ({ context }) => ({ - class: [ - // Flexbox & Alignment - 'relative inline-flex items-center justify-center', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Spacing & Size - 'w-12', - 'm-0', - 'px-0 py-3', - - // Transitions - 'transition duration-200 ease-in-out', - - // State - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - { 'cursor-default pointer-events-none opacity-60': context.disabled }, - - // Interactivity - 'cursor-pointer user-select-none' - ] - }), - label: { - class: [ - // Flexbox - 'flex-initial', - - // Size - 'w-0' - ] - } - }, - movealltosourcebutton: { - root: ({ context }) => ({ - class: [ - // Flexbox & Alignment - 'relative inline-flex items-center justify-center', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Spacing & Size - 'w-12', - 'm-0', - 'px-0 py-3', - - // Transitions - 'transition duration-200 ease-in-out', - - // State - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - { 'cursor-default pointer-events-none opacity-60': context.disabled }, - - // Interactivity - 'cursor-pointer user-select-none' - ] - }), - label: { - class: [ - // Flexbox - 'flex-initial', - - // Size - 'w-0' - ] - } - }, - targetcontrols: { - class: 'flex lg:flex-col justify-center gap-2 p-5' - }, - targetmoveupbutton: { - root: ({ context }) => ({ - class: [ - // Flexbox & Alignment - 'relative inline-flex items-center justify-center', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Spacing & Size - 'w-12', - 'm-0', - 'px-0 py-3', - - // Transitions - 'transition duration-200 ease-in-out', - - // State - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - { 'cursor-default pointer-events-none opacity-60': context.disabled }, - - // Interactivity - 'cursor-pointer user-select-none' - ] - }), - label: { - class: [ - // Flexbox - 'flex-initial', - - // Size - 'w-0' - ] - } - }, - targetmovetopbutton: { - root: ({ context }) => ({ - class: [ - // Flexbox & Alignment - 'relative inline-flex items-center justify-center', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Spacing & Size - 'w-12', - 'm-0', - 'px-0 py-3', - - // Transitions - 'transition duration-200 ease-in-out', - - // State - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - { 'cursor-default pointer-events-none opacity-60': context.disabled }, - - // Interactivity - 'cursor-pointer user-select-none' - ] - }), - label: { - class: [ - // Flexbox - 'flex-initial', - - // Size - 'w-0' - ] - } - }, - targetmovedownbutton: { - root: ({ context }) => ({ - class: [ - // Flexbox & Alignment - 'relative inline-flex items-center justify-center', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Spacing & Size - 'w-12', - 'm-0', - 'px-0 py-3', - - // Transitions - 'transition duration-200 ease-in-out', - - // State - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - { 'cursor-default pointer-events-none opacity-60': context.disabled }, - - // Interactivity - 'cursor-pointer user-select-none' - ] - }), - label: { - class: [ - // Flexbox - 'flex-initial', - - // Size - 'w-0' - ] - } - }, - targetmovebottombutton: { - root: ({ context }) => ({ - class: [ - // Flexbox & Alignment - 'relative inline-flex items-center justify-center', - - // Shape - 'rounded-md', - - // Color - 'text-white dark:text-surface-900', - 'bg-primary-500 dark:bg-primary-400', - 'border border-primary-500 dark:border-primary-400', - - // Spacing & Size - 'w-12', - 'm-0', - 'px-0 py-3', - - // Transitions - 'transition duration-200 ease-in-out', - - // State - 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300', - 'focus:outline-none focus:outline-offset-0 focus:ring', - 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - { 'cursor-default pointer-events-none opacity-60': context.disabled }, - - // Interactivity - 'cursor-pointer user-select-none' - ] - }), - label: { - class: [ - // Flexbox - 'flex-initial', - - // Size - 'w-0' - ] - } - }, - targetwrapper: { - class: 'grow shrink basis-2/4' - }, - targetheader: { + targetListContainer: { class: [ - 'font-bold', - - // Shape - 'border-b-0 rounded-t-md', - - // Spacing - 'p-5', - - // Color - 'text-surface-700 dark:text-white/80', - 'bg-surface-50 dark:bg-surface-800', - 'border border-surface-200 dark:border-surface-700' - ] - }, - targetlist: { - class: [ - // Spacing - 'list-none m-0 p-0', - - // Size - 'min-h-[12rem] max-h-[24rem]', + // Flexbox + 'grow shrink basis-2/4', // Shape - 'rounded-b-md', + 'rounded-md', // Color - 'text-surface-600 dark:text-white/80', - 'bg-surface-0 dark:bg-surface-800', + 'bg-surface-0 dark:bg-surface-900', 'border border-surface-200 dark:border-surface-700', - - // Spacing - 'py-3 px-0', - - // Focus & Outline - 'outline-none', - - // Misc - 'overflow-auto' + 'outline-none' ] }, + targetControls: { + class: 'flex lg:flex-col justify-center gap-2 p-5' + }, transition: { enterFromClass: '!transition-none', enterActiveClass: '!transition-none', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/progressbar/index.js b/frontend/packages/kwai-ui/src/presets/kwai/progressbar/index.js index 0ca7b9ff..bd0f701a 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/progressbar/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/progressbar/index.js @@ -20,7 +20,7 @@ export default { { 'absolute flex items-center justify-center overflow-hidden': props.mode !== 'indeterminate' }, // Colors - 'bg-primary-500 dark:bg-primary-400', + 'bg-primary', // Spacing & Sizing 'm-0', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/radiobutton/index.js b/frontend/packages/kwai-ui/src/presets/kwai/radiobutton/index.js index c80dbb2c..f304be53 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/radiobutton/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/radiobutton/index.js @@ -34,17 +34,17 @@ export default { { 'text-surface-700 dark:text-white/80': props.value !== props.modelValue && props.value !== undefined, 'bg-surface-0 dark:bg-surface-900': props.value !== props.modelValue && props.value !== undefined, - 'border-surface-300 dark:border-surface-700': props.value !== props.modelValue && props.value !== undefined && !props.invalid, - 'border-primary-500 dark:border-primary-400': props.value == props.modelValue && props.value !== undefined, - 'bg-primary-500 dark:bg-primary-400': props.value == props.modelValue && props.value !== undefined + 'border-surface-100 dark:border-surface-700': props.value !== props.modelValue && props.value !== undefined && !props.invalid, + 'border-primary': props.value == props.modelValue && props.value !== undefined, + 'bg-primary': props.value == props.modelValue && props.value !== undefined }, // Invalid State { 'border-red-500 dark:border-red-400': props.invalid }, // States { - 'peer-hover:border-primary-500 dark:peer-hover:border-primary-400': !props.disabled && !props.invalid, - 'peer-hover:border-primary-600 dark:peer-hover:border-primary-300 peer-hover:bg-primary-600 dark:peer-hover:bg-primary-300': !props.disabled && props.value == props.modelValue && props.value !== undefined, + 'peer-hover:border-primary dark:peer-hover:border-primary': !props.disabled && !props.invalid, + 'peer-hover:border-primary-emphasis peer-hover:bg-primary-emphasis': !props.disabled && props.value == props.modelValue && props.value !== undefined, 'peer-focus-visible:border-primary-500 dark:peer-focus-visible:border-primary-400 peer-focus-visible:ring-2 peer-focus-visible:ring-primary-400/20 dark:peer-focus-visible:ring-primary-300/20': !props.disabled, 'opacity-60 cursor-default': props.disabled } diff --git a/frontend/packages/kwai-ui/src/presets/kwai/rating/index.js b/frontend/packages/kwai-ui/src/presets/kwai/rating/index.js index db097f34..4d4e4993 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/rating/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/rating/index.js @@ -13,36 +13,7 @@ export default { } ] }), - cancelitem: ({ context }) => ({ - class: [ - // Flex & Alignment - 'inline-flex items-center', - - //State - { - 'outline-none ring ring-primary-500/50 dark:ring-primary-400/50': context.focused - }, - - // Misc - 'cursor-pointer' - ] - }), - cancelicon: { - class: [ - // Size - 'w-5 h-5', - - // Color - 'text-red-500 dark:text-red-400', - - // State - 'hover:text-red-600 dark:hover:text-red-300', - - // Transition - 'transition duration-200 ease-in' - ] - }, - item: ({ props, context }) => ({ + option: ({ props, context }) => ({ class: [ // Flex & Alignment 'inline-flex items-center', @@ -59,7 +30,7 @@ export default { } ] }), - officon: ({ props }) => ({ + offIcon: ({ props }) => ({ class: [ // Size 'w-5 h-5', @@ -74,13 +45,13 @@ export default { 'transition duration-200 ease-in' ] }), - onicon: ({ props }) => ({ + onIcon: ({ props }) => ({ class: [ // Size 'w-5 h-5', // Color - 'text-primary-500 dark:text-primary-400', + 'text-primary', // State { 'hover:text-primary-600 dark:hover:text-primary-300': !props.readonly }, diff --git a/frontend/packages/kwai-ui/src/presets/kwai/scrollpanel/index.js b/frontend/packages/kwai-ui/src/presets/kwai/scrollpanel/index.js index d41e690c..896fb143 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/scrollpanel/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/scrollpanel/index.js @@ -1,5 +1,5 @@ export default { - wrapper: { + contentContainer: { class: [ // Size & Position 'h-full w-full', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/scrolltop/index.js b/frontend/packages/kwai-ui/src/presets/kwai/scrolltop/index.js index 04f6324c..94c7450b 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/scrolltop/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/scrolltop/index.js @@ -1,36 +1,21 @@ export default { - root: ({ props }) => ({ - class: [ - // Flex & Alignment - 'flex items-center justify-center', + button: ({ props }) => ({ + root: { + class: [ + // Flex & Alignment + 'flex items-center justify-center', - // Positioning - { - sticky: props.target === 'parent', - fixed: props.target === 'window' - }, - 'bottom-[20px] right-[20px]', - 'ml-auto', - - // Shape & Size - { - 'rounded-md h-8 w-8': props.target === 'parent', - 'h-12 w-12 rounded-full shadow-md': props.target === 'window' - }, - - // Color - 'text-white dark:text-surface-900', - { - 'bg-primary-500 dark:bg-primary-400 hover:bg-primary-600 dark:hover:bg-primary-300': props.target === 'parent', - 'bg-surface-500 dark:bg-surface-400 hover:bg-surface-600 dark:hover:bg-surface-300': props.target === 'window' - }, - - // States - { - 'hover:bg-primary-600 dark:hover:bg-primary-300': props.target === 'parent', - 'hover:bg-surface-600 dark:hover:bg-surface-300': props.target === 'window' - } - ] + // Positioning + { + '!sticky flex ml-auto': props.target === 'parent', + '!fixed': props.target === 'window' + }, + 'bottom-[20px] right-[20px]', + 'h-12 w-12 rounded-full shadow-md', + 'text-white dark:text-surface-900 bg-surface-500 dark:bg-surface-400', + 'hover:bg-surface-600 dark:hover:bg-surface-300' + ] + } }), transition: { enterFromClass: 'opacity-0', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/selectbutton/index.js b/frontend/packages/kwai-ui/src/presets/kwai/selectbutton/index.js index b6fa797c..e698fa85 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/selectbutton/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/selectbutton/index.js @@ -1,49 +1,16 @@ export default { root: ({ props }) => ({ - class: [{ 'opacity-60 select-none pointer-events-none cursor-default': props.disabled }] - }), - button: ({ context, props }) => ({ class: [ - 'relative', - // Font - 'leading-none', + 'inline-flex select-none align-bottom outline-transparent', + 'border border-transparent rounded-md [&>button]:rounded-none', + '[&>button:first-child]:border-r-none [&>button:first-child]:rounded-r-none [&>button:first-child]:rounded-tl-md [&>button:first-child]:rounded-bl-md', + '[&>button:last-child]:border-l-none [&>button:first-child]:rounded-l-none [&>button:last-child]:rounded-tr-md [&>button:last-child]:rounded-br-md', - // Flex Alignment - 'inline-flex items-center align-bottom text-center', - - // Spacing - 'px-4 py-3', - - // Shape - 'border border-r-0', - 'first:rounded-l-md first:rounded-tr-none first:rounded-br-none', - 'last:border-r last:rounded-tl-none last:rounded-bl-none last:rounded-r-md', - - // Color - { - 'bg-surface-0 dark:bg-surface-900': !context.active, - 'text-surface-700 dark:text-white/80': !context.active, - 'border-surface-200 dark:border-surface-700': !context.active && !props.invalid, - 'bg-primary-500 dark:bg-primary-400 border-primary-500 dark:border-primary-400 text-white dark:text-surface-900': context.active - }, // Invalid State - { 'border-red-500 dark:border-red-400': props.invalid }, - - // States - 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50 focus:z-10', { - 'hover:bg-surface-50 dark:hover:bg-surface-800/80': !context.active && !props.invalid, - 'hover:bg-primary-600 dark:hover:bg-primary-300': context.active - }, - { 'opacity-60 select-none pointer-events-none cursor-default': context.disabled }, - // Transition - 'transition duration-200', - - // Misc - 'cursor-pointer select-none overflow-hidden' + 'border-red-500 dark:border-red-400': props.invalid, + 'border-surface-100 dark:border-surface-950': !props.invalid + } ] - }), - label: { - class: 'font-bold' - } + }) }; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/slider/index.js b/frontend/packages/kwai-ui/src/presets/kwai/slider/index.js index 18e3bbb0..0c918de8 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/slider/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/slider/index.js @@ -32,7 +32,7 @@ export default { }, // Colors - 'bg-primary-500 dark:bg-primary-400' + 'bg-primary' ] }), handle: ({ props }) => ({ @@ -53,10 +53,10 @@ export default { // Colors 'bg-surface-0 dark:bg-surface-600', - 'border-primary-500 dark:border-primary-400', + 'border-primary', // States - 'hover:bg-primary-500 hover:border-primary-500', + 'hover:bg-primary-emphasis', 'focus-visible:outline-none focus-visible:outline-offset-0 focus-visible:ring', 'ring-primary-400/50 dark:ring-primary-300/50', @@ -68,7 +68,7 @@ export default { 'touch-action-none' ] }), - starthandler: ({ props }) => ({ + startHandler: ({ props }) => ({ class: [ 'block', @@ -86,10 +86,10 @@ export default { // Colors 'bg-surface-0 dark:bg-surface-600', - 'border-primary-500 dark:border-primary-400', + 'border-primary', // States - 'hover:bg-primary-500 hover:border-primary-500', + 'hover:bg-primary-emphasis', 'focus-visible:outline-none focus-visible:outline-offset-0 focus-visible:ring', 'focus-visible:ring-primary-400/50 dark:focus-visible:ring-primary-300/50', @@ -101,7 +101,7 @@ export default { 'touch-action-none' ] }), - endhandler: ({ props }) => ({ + endHandler: ({ props }) => ({ class: [ 'block', @@ -119,10 +119,10 @@ export default { // Colors 'bg-surface-0 dark:bg-surface-600', - 'border-primary-500 dark:border-primary-400', + 'border-primary', // States - 'hover:bg-primary-500 hover:border-primary-500', + 'hover:bg-primary-emphasis', 'focus-visible:outline-none focus-visible:outline-offset-0 focus-visible:ring', 'focus-visible:ring-primary-400/50 dark:focus-visible:ring-primary-300/50', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/speeddial/index.js b/frontend/packages/kwai-ui/src/presets/kwai/speeddial/index.js index 7ecbbcf2..db9ea04d 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/speeddial/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/speeddial/index.js @@ -1,222 +1,14 @@ export default { - root: { - class: 'absolute flex' - }, - button: { - root: ({ props, context, parent }) => ({ - class: [ - 'relative', - 'z-20', - - // Alignments - 'items-center inline-flex text-center align-bottom justify-center', - - // Sizes & Spacing - 'leading-[normal]', - 'w-16 h-16 p-0 py-3', - - // Shapes - 'rounded-full', - 'shadow-md', - - // Link Button - { 'text-primary-600 bg-transparent border-transparent': props.link }, - - // Plain Button - { 'text-white bg-gray-500 border border-gray-500': props.plain && !props.outlined && !props.text }, - // Plain Text Button - { 'text-surface-500': props.plain && props.text }, - // Plain Outlined Button - { 'text-surface-500 border border-gray-500': props.plain && props.outlined }, - - // Text Button - { 'bg-transparent border-transparent': props.text && !props.plain }, - - // Outlined Button - { 'bg-transparent border': props.outlined && !props.plain }, - - // --- Severity Buttons --- - - // Primary Button - { - 'text-white dark:text-surface-900': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain, - 'bg-primary-500 dark:bg-primary-400': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain, - 'border border-primary-500 dark:border-primary-400': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain - }, - // Primary Text Button - { 'text-primary-500 dark:text-primary-400': props.text && props.severity === null && !props.plain }, - // Primary Outlined Button - { 'text-primary-500 border border-primary-500 hover:bg-primary-300/20': props.outlined && props.severity === null && !props.plain }, - - // Secondary Button - { - 'text-white dark:text-surface-900': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain, - 'bg-surface-500 dark:bg-surface-400': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain, - 'border border-surface-500 dark:border-surface-400': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain - }, - // Secondary Text Button - { 'text-surface-500 dark:text-surface-300': props.text && props.severity === 'secondary' && !props.plain }, - // Secondary Outlined Button - { 'text-surface-500 dark:text-surface-300 border border-surface-500 hover:bg-surface-300/20': props.outlined && props.severity === 'secondary' && !props.plain }, - - // Success Button - { - 'text-white dark:text-green-900': props.severity === 'success' && !props.text && !props.outlined && !props.plain, - 'bg-green-500 dark:bg-green-400': props.severity === 'success' && !props.text && !props.outlined && !props.plain, - 'border border-green-500 dark:border-green-400': props.severity === 'success' && !props.text && !props.outlined && !props.plain - }, - // Success Text Button - { 'text-green-500 dark:text-green-400': props.text && props.severity === 'success' && !props.plain }, - // Success Outlined Button - { 'text-green-500 border border-green-500 hover:bg-green-300/20': props.outlined && props.severity === 'success' && !props.plain }, - - // Info Button - { - 'text-white dark:text-surface-900': props.severity === 'info' && !props.text && !props.outlined && !props.plain, - 'bg-blue-500 dark:bg-blue-400': props.severity === 'info' && !props.text && !props.outlined && !props.plain, - 'border border-blue-500 dark:border-blue-400': props.severity === 'info' && !props.text && !props.outlined && !props.plain - }, - // Info Text Button - { 'text-blue-500 dark:text-blue-400': props.text && props.severity === 'info' && !props.plain }, - // Info Outlined Button - { 'text-blue-500 border border-blue-500 hover:bg-blue-300/20 ': props.outlined && props.severity === 'info' && !props.plain }, - - // Warning Button - { - 'text-white dark:text-surface-900': props.severity === 'warning' && !props.text && !props.outlined && !props.plain, - 'bg-orange-500 dark:bg-orange-400': props.severity === 'warning' && !props.text && !props.outlined && !props.plain, - 'border border-orange-500 dark:border-orange-400': props.severity === 'warning' && !props.text && !props.outlined && !props.plain - }, - // Warning Text Button - { 'text-orange-500 dark:text-orange-400': props.text && props.severity === 'warning' && !props.plain }, - // Warning Outlined Button - { 'text-orange-500 border border-orange-500 hover:bg-orange-300/20': props.outlined && props.severity === 'warning' && !props.plain }, - - // Help Button - { - 'text-white dark:text-surface-900': props.severity === 'help' && !props.text && !props.outlined && !props.plain, - 'bg-purple-500 dark:bg-purple-400': props.severity === 'help' && !props.text && !props.outlined && !props.plain, - 'border border-purple-500 dark:border-purple-400': props.severity === 'help' && !props.text && !props.outlined && !props.plain - }, - // Help Text Button - { 'text-purple-500 dark:text-purple-400': props.text && props.severity === 'help' && !props.plain }, - // Help Outlined Button - { 'text-purple-500 border border-purple-500 hover:bg-purple-300/20': props.outlined && props.severity === 'help' && !props.plain }, - - // Danger Button - { - 'text-white dark:text-surface-900': props.severity === 'danger' && !props.text && !props.outlined && !props.plain, - 'bg-red-500 dark:bg-red-400': props.severity === 'danger' && !props.text && !props.outlined && !props.plain, - 'border border-red-500 dark:border-red-400': props.severity === 'danger' && !props.text && !props.outlined && !props.plain - }, - // Danger Text Button - { 'text-red-500 dark:text-red-400': props.text && props.severity === 'danger' && !props.plain }, - // Danger Outlined Button - { 'text-red-500 border border-red-500 hover:bg-red-300/20': props.outlined && props.severity === 'danger' && !props.plain }, - - // --- Severity Button States --- - 'focus:outline-none focus:outline-offset-0 focus:ring', - - // Link - { 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50': props.link }, - - // Plain - { 'hover:bg-gray-600 hover:border-gray-600': props.plain && !props.outlined && !props.text }, - // Text & Outlined Button - { 'hover:bg-surface-300/20': props.plain && (props.text || props.outlined) }, - - // Primary - { 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50': props.severity === null }, - // Text & Outlined Button - { 'hover:bg-primary-300/20': (props.text || props.outlined) && props.severity === null && !props.plain }, - - // Secondary - { 'hover:bg-surface-600 dark:hover:bg-surface-300 hover:border-surface-600 dark:hover:border-surface-300': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-surface-400/50 dark:focus:ring-surface-300/50': props.severity === 'secondary' }, - // Text & Outlined Button - { 'hover:bg-surface-300/20': (props.text || props.outlined) && props.severity === 'secondary' && !props.plain }, - - // Success - { 'hover:bg-green-600 dark:hover:bg-green-300 hover:border-green-600 dark:hover:border-green-300': props.severity === 'success' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-green-400/50 dark:focus:ring-green-300/50': props.severity === 'success' }, - // Text & Outlined Button - { 'hover:bg-green-300/20': (props.text || props.outlined) && props.severity === 'success' && !props.plain }, - - // Info - { 'hover:bg-blue-600 dark:hover:bg-blue-300 hover:border-blue-600 dark:hover:border-blue-300': props.severity === 'info' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-blue-400/50 dark:focus:ring-blue-300/50': props.severity === 'info' }, - // Text & Outlined Button - { 'hover:bg-blue-300/20': (props.text || props.outlined) && props.severity === 'info' && !props.plain }, - - // Warning - { 'hover:bg-orange-600 dark:hover:bg-orange-300 hover:border-orange-600 dark:hover:border-orange-300': props.severity === 'warning' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-orange-400/50 dark:focus:ring-orange-300/50': props.severity === 'warning' }, - // Text & Outlined Button - { 'hover:bg-orange-300/20': (props.text || props.outlined) && props.severity === 'warning' && !props.plain }, - - // Help - { 'hover:bg-purple-600 dark:hover:bg-purple-300 hover:border-purple-600 dark:hover:border-purple-300': props.severity === 'help' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-purple-400/50 dark:focus:ring-purple-300/50': props.severity === 'help' }, - // Text & Outlined Button - { 'hover:bg-purple-300/20': (props.text || props.outlined) && props.severity === 'help' && !props.plain }, - - // Danger - { 'hover:bg-red-600 dark:hover:bg-red-300 hover:border-red-600 dark:hover:border-red-300': props.severity === 'danger' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-red-400/50 dark:focus:ring-red-300/50': props.severity === 'danger' }, - // Text & Outlined Button - { 'hover:bg-red-300/20': (props.text || props.outlined) && props.severity === 'danger' && !props.plain }, - - // Disabled - { 'opacity-60 pointer-events-none cursor-default': context.disabled }, - - // Transitions - 'transition duration-200 ease-in-out', - parent.state.d_visible ? 'rotate-45' : 'rotate-0', - - // Misc - 'cursor-pointer overflow-hidden select-none' - ] - }), - label: ({ props }) => ({ - class: [ - 'duration-200', - 'font-bold', - { - 'hover:underline': props.link - }, - { 'flex-1': props.label !== null, 'invisible w-0': props.label == null } - ] - }), - icon: ({ props }) => ({ - class: [ - 'mx-0', - { - 'mr-2': props.iconPos == 'left' && props.label != null, - 'ml-2 order-1': props.iconPos == 'right' && props.label != null, - 'mb-2': props.iconPos == 'top' && props.label != null, - 'mt-2': props.iconPos == 'bottom' && props.label != null - } - ] - }), - loadingicon: ({ props }) => ({ - class: [ - 'h-4 w-4', - 'mx-0', - { - 'mr-2': props.iconPos == 'left' && props.label != null, - 'ml-2 order-1': props.iconPos == 'right' && props.label != null, - 'mb-2': props.iconPos == 'top' && props.label != null, - 'mt-2': props.iconPos == 'bottom' && props.label != null - }, - 'animate-spin' - ] - }), - badge: ({ props }) => ({ - class: [{ 'ml-2 w-4 h-4 leading-none flex items-center justify-center': props.badge }] - }) - }, - menu: { + root: ({ state }) => ({ + class: [ + 'static flex gap-2', + { + '[&_[data-pc-name=pcbutton]]:rotate-45': state.d_visible, + '[&_[data-pc-name=pcbutton]]:rotate-0': !state.d_visible + } + ] + }), + list: { class: [ // Spacing 'm-0 p-0', @@ -231,7 +23,7 @@ export default { 'z-20' ] }, - menuitem: ({ props, context }) => ({ + item: ({ props, context }) => ({ class: [ 'transform transition-transform duration-200 ease-out transition-opacity duration-800', @@ -250,24 +42,6 @@ export default { { absolute: props.type !== 'linear' } ] }), - action: { - class: [ - // Flexbox & Alignment - 'flex items-center justify-center', - - // Size - 'w-12 h-12', - - // Shape - 'rounded-full relative overflow-hidden', - - // Appearance - 'bg-surface-600 dark:bg-surface-0/80 text-white dark:text-surface-900/80', - - // Hover Effects - 'hover:bg-surface-700 dark:hover:bg-surface-200/80' - ] - }, mask: ({ state }) => ({ class: [ // Base Styles diff --git a/frontend/packages/kwai-ui/src/presets/kwai/splitbutton/index.js b/frontend/packages/kwai-ui/src/presets/kwai/splitbutton/index.js index 61a42f57..cdb13d03 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/splitbutton/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/splitbutton/index.js @@ -7,496 +7,13 @@ export default { // Shape 'rounded-md', - { 'shadow-lg': props.raised } - ] - }), - button: { - root: ({ parent }) => ({ - class: [ - 'relative', - - // Alignments - 'items-center inline-flex text-center align-bottom justify-center', - - // Sizes & Spacing - 'leading-[normal]', - { - 'px-4 py-3': parent.props.size === null, - 'text-sm py-2 px-3': parent.props.size === 'small', - 'text-xl py-3 px-4': parent.props.size === 'large' - }, - { - 'min-w-12 p-0 py-3': parent.props.label == null && parent.props.icon !== null - }, - - // Shape - 'rounded-r-none', - 'border-r-0', - { 'rounded-l-full': parent.props.rounded }, - { 'rounded-md': !parent.props.rounded, 'rounded-full': parent.props.rounded }, - - // Link Button - { 'text-primary-600 bg-transparent border-transparent': parent.props.link }, - - // Plain Button - { 'text-white bg-gray-500 border border-gray-500': parent.props.plain && !parent.props.outlined && !parent.props.text }, - // Plain Text Button - { 'text-surface-500': parent.props.plain && parent.props.text }, - // Plain Outlined Button - { 'text-surface-500 border border-gray-500': parent.props.plain && parent.props.outlined }, - - // Text Button - { 'bg-transparent border-transparent': parent.props.text && !parent.props.plain }, - - // Outlined Button - { 'bg-transparent border': parent.props.outlined && !parent.props.plain }, - - // --- Severity Buttons --- - - // Primary Button - { - 'text-white dark:text-surface-900': !parent.props.link && parent.props.severity === null && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'bg-primary-500 dark:bg-primary-400': !parent.props.link && parent.props.severity === null && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'border border-primary-500 dark:border-primary-400': !parent.props.link && parent.props.severity === null && !parent.props.text && !parent.props.outlined && !parent.props.plain - }, - // Primary Text Button - { 'text-primary-500 dark:text-primary-400': parent.props.text && parent.props.severity === null && !parent.props.plain }, - // Primary Outlined Button - { 'text-primary-500 border border-primary-500 hover:bg-primary-300/20': parent.props.outlined && parent.props.severity === null && !parent.props.plain }, - - // Secondary Button - { - 'text-white dark:text-surface-900': parent.props.severity === 'secondary' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'bg-surface-500 dark:bg-surface-400': parent.props.severity === 'secondary' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'border border-surface-500 dark:border-surface-400': parent.props.severity === 'secondary' && !parent.props.text && !parent.props.outlined && !parent.props.plain - }, - // Secondary Text Button - { 'text-surface-500 dark:text-surface-400': parent.props.text && parent.props.severity === 'secondary' && !parent.props.plain }, - // Secondary Outlined Button - { 'text-surface-500 border border-surface-500 hover:bg-surface-300/20': parent.props.outlined && parent.props.severity === 'secondary' && !parent.props.plain }, - - // Success Button - { - 'text-white dark:text-surface-900': parent.props.severity === 'success' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'bg-green-500 dark:bg-green-400': parent.props.severity === 'success' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'border border-green-500 dark:border-green-400': parent.props.severity === 'success' && !parent.props.text && !parent.props.outlined && !parent.props.plain - }, - // Success Text Button - { 'text-surface-500 dark:text-surface-400': parent.props.text && parent.props.severity === 'secondary' && !parent.props.plain }, - // Success Outlined Button - { 'text-green-500 border border-green-500 hover:bg-green-300/20': parent.props.outlined && parent.props.severity === 'success' && !parent.props.plain }, - - // Info Button - { - 'text-white dark:text-surface-900': parent.props.severity === 'info' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'bg-blue-500 dark:bg-blue-400': parent.props.severity === 'info' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'border border-blue-500 dark:border-blue-400': parent.props.severity === 'info' && !parent.props.text && !parent.props.outlined && !parent.props.plain - }, - // Info Text Button - { 'text-blue-500 dark:text-blue-400': parent.props.text && parent.props.severity === 'info' && !parent.props.plain }, - // Info Outlined Button - { 'text-blue-500 border border-blue-500 hover:bg-blue-300/20 ': parent.props.outlined && parent.props.severity === 'info' && !parent.props.plain }, - - // Warning Button - { - 'text-white dark:text-surface-900': parent.props.severity === 'warning' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'bg-orange-500 dark:bg-orange-400': parent.props.severity === 'warning' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'border border-orange-500 dark:border-orange-400': parent.props.severity === 'warning' && !parent.props.text && !parent.props.outlined && !parent.props.plain - }, - // Warning Text Button - { 'text-orange-500 dark:text-orange-400': parent.props.text && parent.props.severity === 'warning' && !parent.props.plain }, - // Warning Outlined Button - { 'text-orange-500 border border-orange-500 hover:bg-orange-300/20': parent.props.outlined && parent.props.severity === 'warning' && !parent.props.plain }, - - // Help Button - { - 'text-white dark:text-surface-900': parent.props.severity === 'help' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'bg-purple-500 dark:bg-purple-400': parent.props.severity === 'help' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'border border-purple-500 dark:border-purple-400': parent.props.severity === 'help' && !parent.props.text && !parent.props.outlined && !parent.props.plain - }, - // Help Text Button - { 'text-purple-500 dark:text-purple-400': parent.props.text && parent.props.severity === 'help' && !parent.props.plain }, - // Help Outlined Button - { 'text-purple-500 border border-purple-500 hover:bg-purple-300/20': parent.props.outlined && parent.props.severity === 'help' && !parent.props.plain }, - - // Danger Button - { - 'text-white dark:text-surface-900': parent.props.severity === 'danger' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'bg-red-500 dark:bg-red-400': parent.props.severity === 'danger' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'border border-red-500 dark:border-red-400': parent.props.severity === 'danger' && !parent.props.text && !parent.props.outlined && !parent.props.plain - }, - // Danger Text Button - { 'text-red-500 dark:text-red-400': parent.props.text && parent.props.severity === 'danger' && !parent.props.plain }, - // Danger Outlined Button - { 'text-red-500 border border-red-500 hover:bg-red-300/20': parent.props.outlined && parent.props.severity === 'danger' && !parent.props.plain }, - - // --- Severity Button States --- - 'focus:outline-none focus:outline-offset-0 focus:ring', - - // Link - { 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50': parent.props.link }, - - // Plain - { 'hover:bg-gray-600 hover:border-gray-600': parent.props.plain && !parent.props.outlined && !parent.props.text }, - // Text & Outlined Button - { 'hover:bg-surface-300/20': parent.props.plain && (parent.props.text || parent.props.outlined) }, - - // Primary - { 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300': !parent.props.link && parent.props.severity === null && !parent.props.text && !parent.props.outlined && !parent.props.plain }, - { 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50': !parent.props.link && parent.props.severity === null && !parent.props.text && !parent.props.outlined && !parent.props.plain }, - // Text & Outlined Button - { 'hover:bg-primary-300/20': (parent.props.text || parent.props.outlined) && parent.props.severity === null && !parent.props.plain }, - - // Secondary - { 'hover:bg-surface-600 dark:hover:bg-surface-300 hover:border-surface-600 dark:hover:border-surface-300': parent.props.severity === 'secondary' && !parent.props.text && !parent.props.outlined && !parent.props.plain }, - { 'focus:ring-surface-400/50 dark:focus:ring-surface-300/50': parent.props.severity === 'secondary' }, - // Text & Outlined Button - { 'hover:bg-surface-300/20': (parent.props.text || parent.props.outlined) && parent.props.severity === 'secondary' && !parent.props.plain }, - - // Success - { 'hover:bg-green-600 dark:hover:bg-green-300 hover:border-green-600 dark:hover:border-green-300': parent.props.severity === 'success' && !parent.props.text && !parent.props.outlined && !parent.props.plain }, - { 'focus:ring-green-400/50 dark:focus:ring-green-300/50': parent.props.severity === 'success' }, - // Text & Outlined Button - { 'hover:bg-green-300/20': (parent.props.text || parent.props.outlined) && parent.props.severity === 'success' && !parent.props.plain }, - - // Info - { 'hover:bg-blue-600 dark:hover:bg-blue-300 hover:border-blue-600 dark:hover:border-blue-300': parent.props.severity === 'info' && !parent.props.text && !parent.props.outlined && !parent.props.plain }, - { 'focus:ring-blue-400/50 dark:focus:ring-blue-300/50': parent.props.severity === 'info' }, - // Text & Outlined Button - { 'hover:bg-blue-300/20': (parent.props.text || parent.props.outlined) && parent.props.severity === 'info' && !parent.props.plain }, - - // Warning - { 'hover:bg-orange-600 dark:hover:bg-orange-300 hover:border-orange-600 dark:hover:border-orange-300': parent.props.severity === 'warning' && !parent.props.text && !parent.props.outlined && !parent.props.plain }, - { 'focus:ring-orange-400/50 dark:focus:ring-orange-300/50': parent.props.severity === 'warning' }, - // Text & Outlined Button - { 'hover:bg-orange-300/20': (parent.props.text || parent.props.outlined) && parent.props.severity === 'warning' && !parent.props.plain }, - - // Help - { 'hover:bg-purple-600 dark:hover:bg-purple-300 hover:border-purple-600 dark:hover:border-purple-300': parent.props.severity === 'help' && !parent.props.text && !parent.props.outlined && !parent.props.plain }, - { 'focus:ring-purple-400/50 dark:focus:ring-purple-300/50': parent.props.severity === 'help' }, - // Text & Outlined Button - { 'hover:bg-purple-300/20': (parent.props.text || parent.props.outlined) && parent.props.severity === 'help' && !parent.props.plain }, - - // Warning - { 'hover:bg-red-600 dark:hover:bg-red-300 hover:border-red-600 dark:hover:border-red-300': parent.props.severity === 'danger' && !parent.props.text && !parent.props.outlined && !parent.props.plain }, - { 'focus:ring-red-400/50 dark:focus:ring-red-300/50': parent.props.severity === 'danger' }, - // Text & Outlined Button - { 'hover:bg-red-300/20': (parent.props.text || parent.props.outlined) && parent.props.severity === 'danger' && !parent.props.plain }, - - // Transitions - 'transition duration-200 ease-in-out', - - // Misc - 'cursor-pointer overflow-hidden select-none' - ] - }), - icon: { - class: [ - // Margins - 'mr-2' - ] - } - }, - menubutton: { - root: ({ parent }) => ({ - class: [ - 'relative', - // Alignments - 'items-center inline-flex text-center align-bottom justify-center', - - // Sizes & Spacing - 'leading-[normal]', - { - 'px-4 py-3': parent.props.size === null, - 'text-sm py-2 px-3': parent.props.size === 'small', - 'text-xl py-3 px-4': parent.props.size === 'large' - }, - { - 'min-w-12 p-0 py-3': parent.props.label == null && parent.props.icon !== null - }, - - // Shape - 'rounded-l-none', - { 'rounded-l-full': parent.props.rounded }, - { 'rounded-md': !parent.props.rounded, 'rounded-full': parent.props.rounded }, - - // Link Button - { 'text-primary-600 bg-transparent border-transparent': parent.props.link }, - - // Plain Button - { 'text-white bg-gray-500 border border-gray-500': parent.props.plain && !parent.props.outlined && !parent.props.text }, - // Plain Text Button - { 'text-surface-500': parent.props.plain && parent.props.text }, - // Plain Outlined Button - { 'text-surface-500 border border-gray-500': parent.props.plain && parent.props.outlined }, - - // Text Button - { 'bg-transparent border-transparent': parent.props.text && !parent.props.plain }, - - // Outlined Button - { 'bg-transparent border': parent.props.outlined && !parent.props.plain }, + { 'shadow-lg': props.raised }, - // --- Severity Buttons --- - - // Primary Button - { - 'text-white dark:text-surface-900': !parent.props.link && parent.props.severity === null && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'bg-primary-500 dark:bg-primary-400': !parent.props.link && parent.props.severity === null && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'border border-primary-500 dark:border-primary-400': !parent.props.link && parent.props.severity === null && !parent.props.text && !parent.props.outlined && !parent.props.plain - }, - // Primary Text Button - { 'text-primary-500 dark:text-primary-400': parent.props.text && parent.props.severity === null && !parent.props.plain }, - // Primary Outlined Button - { 'text-primary-500 border border-primary-500 hover:bg-primary-300/20': parent.props.outlined && parent.props.severity === null && !parent.props.plain }, - - // Secondary Button - { - 'text-white dark:text-surface-900': parent.props.severity === 'secondary' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'bg-surface-500 dark:bg-surface-400': parent.props.severity === 'secondary' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'border border-surface-500 dark:border-surface-400': parent.props.severity === 'secondary' && !parent.props.text && !parent.props.outlined && !parent.props.plain - }, - // Secondary Text Button - { 'text-surface-500 dark:text-surface-400': parent.props.text && parent.props.severity === 'secondary' && !parent.props.plain }, - // Secondary Outlined Button - { 'text-surface-500 border border-surface-500 hover:bg-surface-300/20': parent.props.outlined && parent.props.severity === 'secondary' && !parent.props.plain }, - - // Success Button - { - 'text-white dark:text-surface-900': parent.props.severity === 'success' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'bg-green-500 dark:bg-green-400': parent.props.severity === 'success' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'border border-green-500 dark:border-green-400': parent.props.severity === 'success' && !parent.props.text && !parent.props.outlined && !parent.props.plain - }, - // Success Text Button - { 'text-surface-500 dark:text-surface-400': parent.props.text && parent.props.severity === 'secondary' && !parent.props.plain }, - // Success Outlined Button - { 'text-green-500 border border-green-500 hover:bg-green-300/20': parent.props.outlined && parent.props.severity === 'success' && !parent.props.plain }, - - // Info Button - { - 'text-white dark:text-surface-900': parent.props.severity === 'info' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'bg-blue-500 dark:bg-blue-400': parent.props.severity === 'info' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'border border-blue-500 dark:border-blue-400': parent.props.severity === 'info' && !parent.props.text && !parent.props.outlined && !parent.props.plain - }, - // Info Text Button - { 'text-blue-500 dark:text-blue-400': parent.props.text && parent.props.severity === 'info' && !parent.props.plain }, - // Info Outlined Button - { 'text-blue-500 border border-blue-500 hover:bg-blue-300/20 ': parent.props.outlined && parent.props.severity === 'info' && !parent.props.plain }, - - // Warning Button - { - 'text-white dark:text-surface-900': parent.props.severity === 'warning' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'bg-orange-500 dark:bg-orange-400': parent.props.severity === 'warning' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'border border-orange-500 dark:border-orange-400': parent.props.severity === 'warning' && !parent.props.text && !parent.props.outlined && !parent.props.plain - }, - // Warning Text Button - { 'text-orange-500 dark:text-orange-400': parent.props.text && parent.props.severity === 'warning' && !parent.props.plain }, - // Warning Outlined Button - { 'text-orange-500 border border-orange-500 hover:bg-orange-300/20': parent.props.outlined && parent.props.severity === 'warning' && !parent.props.plain }, - - // Help Button - { - 'text-white dark:text-surface-900': parent.props.severity === 'help' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'bg-purple-500 dark:bg-purple-400': parent.props.severity === 'help' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'border border-purple-500 dark:border-purple-400': parent.props.severity === 'help' && !parent.props.text && !parent.props.outlined && !parent.props.plain - }, - // Help Text Button - { 'text-purple-500 dark:text-purple-400': parent.props.text && parent.props.severity === 'help' && !parent.props.plain }, - // Help Outlined Button - { 'text-purple-500 border border-purple-500 hover:bg-purple-300/20': parent.props.outlined && parent.props.severity === 'help' && !parent.props.plain }, - - // Danger Button - { - 'text-white dark:text-surface-900': parent.props.severity === 'danger' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'bg-red-500 dark:bg-red-400': parent.props.severity === 'danger' && !parent.props.text && !parent.props.outlined && !parent.props.plain, - 'border border-red-500 dark:border-red-400': parent.props.severity === 'danger' && !parent.props.text && !parent.props.outlined && !parent.props.plain - }, - // Danger Text Button - { 'text-red-500 dark:text-red-400': parent.props.text && parent.props.severity === 'danger' && !parent.props.plain }, - // Danger Outlined Button - { 'text-red-500 border border-red-500 hover:bg-red-300/20': parent.props.outlined && parent.props.severity === 'danger' && !parent.props.plain }, - - // --- Severity Button States --- - 'focus:outline-none focus:outline-offset-0 focus:ring', - - // Link - { 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50': parent.props.link }, - - // Plain - { 'hover:bg-gray-600 hover:border-gray-600': parent.props.plain && !parent.props.outlined && !parent.props.text }, - // Text & Outlined Button - { 'hover:bg-surface-300/20': parent.props.plain && (parent.props.text || parent.props.outlined) }, - - // Primary - { 'hover:bg-primary-600 dark:hover:bg-primary-300 hover:border-primary-600 dark:hover:border-primary-300': !parent.props.link && parent.props.severity === null && !parent.props.text && !parent.props.outlined && !parent.props.plain }, - { 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50': !parent.props.link && parent.props.severity === null && !parent.props.text && !parent.props.outlined && !parent.props.plain }, - // Text & Outlined Button - { 'hover:bg-primary-300/20': (parent.props.text || parent.props.outlined) && parent.props.severity === null && !parent.props.plain }, - - // Secondary - { 'hover:bg-surface-600 dark:hover:bg-surface-300 hover:border-surface-600 dark:hover:border-surface-300': parent.props.severity === 'secondary' && !parent.props.text && !parent.props.outlined && !parent.props.plain }, - { 'focus:ring-surface-400/50 dark:focus:ring-surface-300/50': parent.props.severity === 'secondary' }, - // Text & Outlined Button - { 'hover:bg-surface-300/20': (parent.props.text || parent.props.outlined) && parent.props.severity === 'secondary' && !parent.props.plain }, - - // Success - { 'hover:bg-green-600 dark:hover:bg-green-300 hover:border-green-600 dark:hover:border-green-300': parent.props.severity === 'success' && !parent.props.text && !parent.props.outlined && !parent.props.plain }, - { 'focus:ring-green-400/50 dark:focus:ring-green-300/50': parent.props.severity === 'success' }, - // Text & Outlined Button - { 'hover:bg-green-300/20': (parent.props.text || parent.props.outlined) && parent.props.severity === 'success' && !parent.props.plain }, - - // Info - { 'hover:bg-blue-600 dark:hover:bg-blue-300 hover:border-blue-600 dark:hover:border-blue-300': parent.props.severity === 'info' && !parent.props.text && !parent.props.outlined && !parent.props.plain }, - { 'focus:ring-blue-400/50 dark:focus:ring-blue-300/50': parent.props.severity === 'info' }, - // Text & Outlined Button - { 'hover:bg-blue-300/20': (parent.props.text || parent.props.outlined) && parent.props.severity === 'info' && !parent.props.plain }, - - // Warning - { 'hover:bg-orange-600 dark:hover:bg-orange-300 hover:border-orange-600 dark:hover:border-orange-300': parent.props.severity === 'warning' && !parent.props.text && !parent.props.outlined && !parent.props.plain }, - { 'focus:ring-orange-400/50 dark:focus:ring-orange-300/50': parent.props.severity === 'warning' }, - // Text & Outlined Button - { 'hover:bg-orange-300/20': (parent.props.text || parent.props.outlined) && parent.props.severity === 'warning' && !parent.props.plain }, - - // Help - { 'hover:bg-purple-600 dark:hover:bg-purple-300 hover:border-purple-600 dark:hover:border-purple-300': parent.props.severity === 'help' && !parent.props.text && !parent.props.outlined && !parent.props.plain }, - { 'focus:ring-purple-400/50 dark:focus:ring-purple-300/50': parent.props.severity === 'help' }, - // Text & Outlined Button - { 'hover:bg-purple-300/20': (parent.props.text || parent.props.outlined) && parent.props.severity === 'help' && !parent.props.plain }, - - // Warning - { 'hover:bg-red-600 dark:hover:bg-red-300 hover:border-red-600 dark:hover:border-red-300': parent.props.severity === 'danger' && !parent.props.text && !parent.props.outlined && !parent.props.plain }, - { 'focus:ring-red-400/50 dark:focus:ring-red-300/50': parent.props.severity === 'danger' }, - // Text & Outlined Button - { 'hover:bg-red-300/20': (parent.props.text || parent.props.outlined) && parent.props.severity === 'danger' && !parent.props.plain }, - - // Transitions - 'transition duration-200 ease-in-out', - - // Misc - 'cursor-pointer overflow-hidden select-none' - ] - }), - label: { - class: ['hidden'] - } - }, - menu: { - root: { - class: [ - // Shape - 'rounded-md', - - // Size - 'min-w-[12rem]', - 'py-1', - - // Colors - 'bg-surface-0 dark:bg-surface-700', - 'border border-surface-200 dark:border-surface-700' - ] - }, - menu: { - class: [ - // Spacings and Shape - 'list-none', - 'm-0', - 'p-0', - 'outline-none' - ] - }, - menuitem: { - class: [ - // Position - 'relative' - ] - }, - content: ({ context }) => ({ - class: [ - //Shape - 'rounded-none', - - // Colors - { - 'text-surface-500 dark:text-white/70': !context.focused && !context.active, - 'text-surface-500 dark:text-white/70 bg-surface-200 dark:bg-surface-600/90': context.focused && !context.active, - 'text-primary-700 dark:text-surface-0/80 bg-primary-50 dark:bg-primary-400/30': context.focused && context.active, - 'text-primary-700 dark:text-surface-0/80 bg-primary-50 dark:bg-primary-400/30': !context.focused && context.active - }, - - // Hover States - { - 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context.active, - 'hover:bg-primary-500/50 dark:hover:bg-primary-300/30 text-primary-700 dark:text-surface-0/80': context.active - }, - - // Transitions - 'transition-shadow', - 'duration-200' - ] - }), - action: { - class: [ - 'relative', - // Flexbox - - 'flex', - 'items-center', - - // Spacing - 'py-3', - 'px-5', - - // Color - 'text-surface-700 dark:text-white/80', - - // Misc - 'no-underline', - 'overflow-hidden', - 'cursor-pointer', - 'select-none' - ] - }, - icon: { - class: [ - // Spacing - 'mr-2', - - // Color - 'text-surface-600 dark:text-white/70' - ] - }, - label: { - class: ['leading-none'] - }, - submenuicon: { - class: [ - // Position - 'ml-auto' - ] - }, - submenu: { - class: [ - // Size - 'w-full sm:w-48', - - // Spacing - 'py-1', - 'm-0', - 'list-none', - - // Shape - 'shadow-none sm:shadow-md', - 'border-0', - - // Position - 'static sm:absolute', - 'z-10', - - // Color - 'bg-surface-0 dark:bg-surface-700' - ] - }, - separator: { - class: 'border-t border-surface-200 dark:border-surface-600 my-1' - } - } + '[&>[data-pc-name=pcbutton]]:rounded-tr-none', + '[&>[data-pc-name=pcbutton]]:rounded-br-none', + '[&>[data-pc-name=pcdropdown]]:rounded-tl-none', + '[&>[data-pc-name=pcdropdown]]:rounded-bl-none', + '[&>[data-pc-name=pcmenu]]:min-w-full' + ] + }) }; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/stepper/index.js b/frontend/packages/kwai-ui/src/presets/kwai/stepper/index.js index f49ae892..a69485a6 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/stepper/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/stepper/index.js @@ -1,161 +1,13 @@ export default { - root: ({ props }) => ({ - class: ['flex-1', props.orientation === 'vertical' ? 'flex-col' : 'flex-row'] - }), - nav: { - class: [ - // Flexbox - 'flex', - 'justify-between', - 'items-center', - - // Spacing - 'm-0', - 'p-0', - - // Positioning - 'relative', - - // Lists - 'list-none', - - // Overflow - 'overflow-x-auto' - ] - }, - stepperpanel: { - panel: ({ context, parent }) => ({ - class: [context.active ? 'flex-1' : '', parent.props.orientation === 'vertical' ? 'flex flex-col flex-initial' : ''] - }), - header: ({ parent, context }) => ({ - class: [ - // Position - 'relative', - - // Flexbox - 'flex', - 'items-center', - context.last ? 'flex-initial' : 'flex-1', - parent.props.orientation === 'vertical' ? 'flex-initial' : '', - - // Spacing - 'p-2' - ] - }), - action: { - class: [ - // Borders - 'border-0', - 'border-none', - - // Flexbox - 'inline-flex', - 'items-center', - - // Text - 'text-decoration-none', - - // Transitions - 'transition', - 'transition-shadow', - 'duration-200', - - // Shape - 'rounded-md', - - // Backgrounds - 'bg-transparent', - - // Focus - 'outline-none' - ] - }, - number: ({ context }) => ({ - class: [ - // Flexbox - 'flex', - 'items-center', - 'justify-center', - - // Colors (Conditional) - context.active ? 'bg-primary-500 dark:bg-primary-400 text-surface-0 dark:text-surface-900' : 'border border-surface-200 dark:border-surface-700 text-surface-900 dark:text-surface-0', // Adjust colors as needed - - // Size and Shape - 'min-w-[2rem]', - 'h-[2rem]', - 'line-height-[2rem]', - 'rounded-full', - - // Text - 'text-lg', - - // Borders - context.active ? 'border-0 border-none' : 'border-solid border-2', - - // Transitions - 'transition', - 'transition-colors', - 'transition-shadow', - 'duration-200' - ] - }), - title: ({ context }) => ({ - class: [ - // Layout - 'block', - 'whitespace-nowrap', - 'overflow-hidden', - 'text-ellipsis', - 'max-w-full', - - // Spacing - 'ml-2', - - // Text - context.active ? 'text-surface-900 dark:text-surface-0' : 'text-surface-700 dark:text-surface-0/80', - 'font-bold', - - // Transitions - 'transition', - 'transition-colors', - 'transition-shadow', - 'duration-200' - ] - }), - separator: ({ context, state, parent }) => ({ - class: [ - // Colors (Conditional for active step) - state.d_activeStep <= context.index ? 'bg-surface-200 dark:bg-surface-700' : 'bg-primary-500 dark:bg-primary-400', - - // Conditional for Vertical Orientation - parent.props.orientation === 'vertical' ? ['flex-none', 'w-[2px]', 'h-auto', 'ml-[calc(1.29rem+2px)]'] : ['flex-1', 'w-full', 'h-[2px]', 'ml-4'], - - // Transitions - 'transition-shadow', - 'duration-200' - ] - }), - transition: { - class: ['flex flex-1', 'bg-surface-0 dark:bg-surface-800', 'text-surface-900 dark:text-surface-0'], - enterFromClass: 'max-h-0', - enterActiveClass: 'overflow-hidden transition-[max-height] duration-1000 ease-[cubic-bezier(0.42,0,0.58,1)]', - enterToClass: 'max-h-[1000px]', - leaveFromClass: 'max-h-[1000px]', - leaveActiveClass: 'overflow-hidden transition-[max-height] duration-[450ms] ease-[cubic-bezier(0,1,0,1)]', - leaveToClass: 'max-h-0' - }, - content: ({ parent }) => ({ - class: [parent.props.orientation === 'vertical' ? 'w-full pl-4' : ''] - }) - }, - panelcontainer: { - class: [ - // Colors - 'bg-surface-0 dark:bg-surface-800', - 'text-surface-900 dark:text-surface-0', - - // Spacing - 'p-4' - ] + root: 'has-[[data-pc-name=stepitem]]:flex has-[[data-pc-name=stepitem]]:flex-col', + separator: 'flex-1 w-full h-[2px] bg-surface-200 dark:bg-surface-700 transition-shadow duration-200', + transition: { + class: ['flex flex-1', 'bg-surface-0 dark:bg-surface-800', 'text-surface-900 dark:text-surface-0'], + enterFromClass: 'max-h-0', + enterActiveClass: 'overflow-hidden transition-[max-height] duration-1000 ease-[cubic-bezier(0.42,0,0.58,1)]', + enterToClass: 'max-h-[1000px]', + leaveFromClass: 'max-h-[1000px]', + leaveActiveClass: 'overflow-hidden transition-[max-height] duration-[450ms] ease-[cubic-bezier(0,1,0,1)]', + leaveToClass: 'max-h-0' } }; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/tabmenu/index.js b/frontend/packages/kwai-ui/src/presets/kwai/tabmenu/index.js index 2522382e..b6a21ecb 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/tabmenu/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/tabmenu/index.js @@ -45,8 +45,8 @@ export default { 'text-surface-700 dark:text-surface-0/80': state.d_activeIndex !== context.index, 'bg-surface-0 dark:bg-surface-800': state.d_activeIndex === context.index, - 'border-primary-500 dark:border-primary-400': state.d_activeIndex === context.index, - 'text-primary-500 dark:text-primary-400': state.d_activeIndex === context.index + 'border-primary': state.d_activeIndex === context.index, + 'text-primary': state.d_activeIndex === context.index }, // States diff --git a/frontend/packages/kwai-ui/src/presets/kwai/tag/index.js b/frontend/packages/kwai-ui/src/presets/kwai/tag/index.js index 4c7a7396..8694ff37 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/tag/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/tag/index.js @@ -17,13 +17,15 @@ export default { }, //Colors - 'text-white dark:text-surface-900', + 'text-primary-contrast', { - 'bg-primary-500 dark:bg-primary-400': props.severity == null || props.severity == 'primary', - 'bg-green-500 dark:bg-green-400': props.severity == 'success', - 'bg-blue-500 dark:bg-blue-400': props.severity == 'info', - 'bg-orange-500 dark:bg-orange-400': props.severity == 'warning', - 'bg-red-500 dark:bg-red-400': props.severity == 'danger' + 'bg-primary dark:bg-primary': props.severity == null || props.severity === 'primary', + 'text-surface-700 dark:text-surface-300 bg-surface-100 dark:bg-surface-500/20': props.severity === 'secondary', + 'bg-green-500 dark:bg-green-400': props.severity === 'success', + 'bg-blue-500 dark:bg-blue-400': props.severity === 'info', + 'bg-orange-500 dark:bg-orange-400': props.severity === 'warn', + 'bg-red-500 dark:bg-red-400': props.severity === 'danger', + 'text-surface-0 dark:text-surface-900 bg-surface-900 dark:bg-surface-0': props.severity === 'contrast' } ] }), diff --git a/frontend/packages/kwai-ui/src/presets/kwai/textarea/index.js b/frontend/packages/kwai-ui/src/presets/kwai/textarea/index.js index 9b08011c..756e9889 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/textarea/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/textarea/index.js @@ -1,8 +1,8 @@ export default { - root: ({ context, props }) => ({ + root: ({ context, props, parent }) => ({ class: [ // Font - 'font-sans leading-none', + 'leading-[normal]', // Spacing 'm-0', @@ -23,11 +23,14 @@ export default { // States { - 'hover:border-primary-500 dark:hover:border-primary-400': !context.disabled && !props.invalid, + 'hover:border-primary': !context.disabled && !props.invalid, 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-500/50 dark:focus:ring-primary-400/50': !context.disabled, 'opacity-60 select-none pointer-events-none cursor-default': context.disabled }, + // Filled State *for FloatLabel + { filled: parent.instance?.$name == 'FloatLabel' && props.modelValue !== null && props.modelValue?.length !== 0 }, + // Misc 'appearance-none', 'transition-colors duration-200' diff --git a/frontend/packages/kwai-ui/src/presets/kwai/tieredmenu/index.js b/frontend/packages/kwai-ui/src/presets/kwai/tieredmenu/index.js index d16e1594..44e316fc 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/tieredmenu/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/tieredmenu/index.js @@ -13,22 +13,23 @@ export default { 'border border-surface-200 dark:border-surface-700' ] }, - menu: { + rootList: { class: [ // Spacings and Shape + 'flex flex-col', 'list-none', 'm-0', 'p-0', 'outline-none' ] }, - menuitem: { + item: { class: [ // Position 'relative' ] }, - content: ({ context }) => ({ + itemContent: ({ context }) => ({ class: [ //Shape 'rounded-none', @@ -37,14 +38,13 @@ export default { { 'text-surface-500 dark:text-white/70': !context.focused && !context.active, 'text-surface-500 dark:text-white/70 bg-surface-200 dark:bg-surface-600/90': context.focused && !context.active, - 'text-primary-700 dark:text-surface-0/80 bg-primary-50 dark:bg-primary-400/30': context.focused && context.active, - 'text-primary-700 dark:text-surface-0/80 bg-primary-50 dark:bg-primary-400/30': !context.focused && context.active + 'bg-highlight': (context.focused && context.active) || context.active || (!context.focused && context.active) }, // Hover States { 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context.active, - 'hover:bg-primary-500/50 dark:hover:bg-primary-300/30 text-primary-700 dark:text-surface-0/80': context.active + 'hover:bg-highlight-emphasis': context.active }, // Transitions @@ -52,7 +52,7 @@ export default { 'duration-200' ] }), - action: { + itemLink: { class: [ 'relative', // Flexbox @@ -74,7 +74,7 @@ export default { 'select-none' ] }, - icon: { + itemIcon: { class: [ // Spacing 'mr-2', @@ -83,10 +83,10 @@ export default { 'text-surface-600 dark:text-white/70' ] }, - label: { + itemLabel: { class: ['leading-none'] }, - submenuicon: { + submenuIcon: { class: [ // Position 'ml-auto' @@ -94,6 +94,7 @@ export default { }, submenu: { class: [ + 'flex flex-col', // Size 'w-full sm:w-48', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/timeline/index.js b/frontend/packages/kwai-ui/src/presets/kwai/timeline/index.js index b037b738..a9437acc 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/timeline/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/timeline/index.js @@ -18,7 +18,7 @@ export default { } ] }), - opposite: ({ props, context }) => ({ + eventOpposite: ({ props, context }) => ({ class: [ 'flex-1', { @@ -31,7 +31,7 @@ export default { } ] }), - separator: ({ props }) => ({ + eventSeparator: ({ props }) => ({ class: [ 'flex items-center flex-initial', { @@ -40,7 +40,7 @@ export default { } ] }), - marker: { + eventMarker: { class: [ // Display & Flexbox 'flex self-baseline', @@ -49,10 +49,10 @@ export default { 'w-4 h-4', // Appearance - 'rounded-full border-2 border-primary-500 bg-surface-0 dark:border-primary-300 dark:bg-surface-900/40' + 'rounded-full border-2 border-primary bg-surface-0 dark:bg-surface-900/40' ] }, - connector: ({ props }) => ({ + eventConnector: ({ props }) => ({ class: [ 'grow bg-surface-300 dark:bg-surface-700', { @@ -61,7 +61,7 @@ export default { } ] }), - content: ({ props, context }) => ({ + eventContent: ({ props, context }) => ({ class: [ 'flex-1', { @@ -73,8 +73,8 @@ export default { 'text-right': props.align === 'right' || (props.layout === 'vertical' && props.align === 'alternate' && context.index % 2 === 1) }, { - 'min-h-0': props.layout === 'vertical' && context.index === context.count, - 'grow-0': props.layout === 'horizontal' && context.index === context.count + 'min-h-0': props.layout === 'vertical' && context.index === context.count - 1, + 'grow-0': props.layout === 'horizontal' && context.index === context.count - 1 } ] }) diff --git a/frontend/packages/kwai-ui/src/presets/kwai/toast/index.js b/frontend/packages/kwai-ui/src/presets/kwai/toast/index.js index 01a4e07b..b3e07cf5 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/toast/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/toast/index.js @@ -8,7 +8,7 @@ export default { { '-translate-x-2/4': props.position == 'top-center' || props.position == 'bottom-center' } ] }), - container: ({ props }) => ({ + message: ({ props }) => ({ class: [ 'my-4 rounded-md w-full', 'border-solid border-0 border-l-[6px]', @@ -35,23 +35,23 @@ export default { } ] }), - content: ({ props }) => ({ + messageContent: ({ props }) => ({ class: [ - 'flex p-4', - { - 'items-start': props.message.summary, - 'items-center': !props.message.summary, - }, - ], + 'flex p-4', + { + 'items-start': props.message.summary, + 'items-center': !props.message.summary + } + ] }), - icon: { + messageIcon: { class: [ // Sizing and Spacing 'w-6 h-6', 'text-lg leading-none mr-2 shrink-0' ] }, - text: { + messageText: { class: [ // Font and Text 'text-base leading-none', @@ -63,9 +63,9 @@ export default { class: 'font-bold block' }, detail: ({ props }) => ({ - class: ['block', { 'mt-2': props.message.summary }], + class: ['block', { 'mt-2': props.message.summary }] }), - closebutton: { + closeButton: { class: [ // Flexbox 'flex items-center justify-center', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/togglebutton/index.js b/frontend/packages/kwai-ui/src/presets/kwai/togglebutton/index.js index 592c3638..4444189b 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/togglebutton/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/togglebutton/index.js @@ -1,91 +1,45 @@ export default { - root: { + root: ({ props, context }) => ({ class: [ 'relative', // Alignment - 'inline-flex', - 'align-bottom', - - // Misc - 'cursor-pointer', - 'select-none' - ] - }, - box: ({ props }) => ({ - class: [ - // Alignments - 'items-center inline-flex flex-1 text-center align-bottom justify-center', - - // Sizes & Spacing - 'px-4 py-3 leading-none', - - // Shapes + 'flex items-center justify-center', + 'px-3 py-2', 'rounded-md border', - // Colors + //Color { 'bg-surface-0 dark:bg-surface-900 ': !props.modelValue, 'border-surface-200 dark:border-surface-700 ': !props.modelValue && !props.invalid, 'text-surface-700 dark:text-white/80': !props.modelValue, - 'bg-primary-500 dark:bg-primary-400 border-primary-500 dark:border-primary-400 text-white dark:text-surface-900': props.modelValue + 'bg-primary border-primary text-primary-contrast': props.modelValue }, - // Invalid State - { 'border-red-500 dark:border-red-400': props.invalid }, - // States { - 'peer-hover:bg-surface-50 dark:peer-hover:bg-surface-800/80 peer-hover:border-surface-200 dark:peer-hover:bg-surface-700 peer-hover:text-surface-700 dark:peer-hover:text-white/80': !props.modelValue && !props.invalid, - 'peer-hover:bg-primary-600 peer-hover:border-primary-600 dark:peer-hover:bg-primary-300 dark:peer-hover:border-primary-300': props.modelValue, - 'peer-focus-visible:ring peer-focus-visible:ring-primary-400/50 dark:peer-focus-visible:ring-primary-300/50': !props.disabled + 'hover:text-surface-800 dark:hover:text-white/80': !props.disabled && !props.modelValue, + 'focus:outline-none focus:outline-offset-0 focus-visible:ring-1 focus-visible:ring-primary-500 dark:focus-visible:ring-primary-400': !props.disabled }, + // Invalid State + { 'border-red-500 dark:border-red-400': props.invalid }, + + // Before + 'before:absolute before:left-1 before:top-1 before:w-[calc(100%-0.5rem)] before:h-[calc(100%-0.5rem)] before:rounded-[4px] before:z-0', + // Transitions 'transition-all duration-200', // Misc - { 'cursor-pointer': !props.disabled, 'opacity-60 select-none pointer-events-none cursor-default': props.disabled } - ] - }), - label: { - class: 'font-bold text-center w-full' - }, - input: { - class: [ - 'peer', - - // Size - 'w-full ', - 'h-full', - - // Position - 'absolute', - 'top-0 left-0', - 'z-10', - - // Spacing - 'p-0', - 'm-0', - - // Shape - 'opacity-0', - 'rounded-md', - 'outline-none', - 'border border-surface-200 dark:border-surface-700', + { 'cursor-pointer': !props.disabled, 'opacity-60 select-none pointer-events-none cursor-default': props.disabled }, // Misc - 'appearance-none', - 'cursor-pointer' - ] - }, - icon: ({ props }) => ({ - class: [ - ' mr-2', - { - 'text-surface-600 dark:text-white/70': !props.modelValue, - 'text-white dark:text-surface-900': props.modelValue - } + 'cursor-pointer', + 'select-none' ] - }) + }), + content: 'relative items-center inline-flex justify-center gap-2', + label: 'font-bold text-center w-full z-10 relative', + icon: 'relative z-10 mr-2' }; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/tree/index.js b/frontend/packages/kwai-ui/src/presets/kwai/tree/index.js index 28eb56b8..0a0f7511 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/tree/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/tree/index.js @@ -10,7 +10,8 @@ export default { // Color 'bg-surface-0 dark:bg-surface-800', 'text-surface-700 dark:text-white/80', - 'border border-solid border-surface-200 dark:border-surface-700' + 'border border-solid border-surface-200 dark:border-surface-700', + '[&_[data-pc-name=pcfilter]]:w-full' ] }, wrapper: { @@ -28,7 +29,7 @@ export default { node: { class: ['p-1', 'rounded-md', 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-inset focus:ring-primary-400/50 dark:focus:ring-primary-300/50'] }, - content: ({ context, props }) => ({ + nodeContent: ({ context, props }) => ({ class: [ // Flex and Alignment 'flex items-center', @@ -37,11 +38,11 @@ export default { 'rounded-md', // Spacing - 'p-2', + 'p-2 gap-2', // Colors 'text-surface-600 dark:text-white/70', - { 'bg-primary-50 dark:bg-primary-400/30 text-primary-600 dark:text-surface-0': context.selected }, + { 'bg-highlight': context.selected }, // States { 'hover:bg-surface-50 dark:hover:bg-surface-700/40': (props.selectionMode == 'single' || props.selectionMode == 'multiple') && !context.selected }, @@ -52,7 +53,7 @@ export default { { 'cursor-pointer select-none': props.selectionMode == 'single' || props.selectionMode == 'multiple' } ] }), - toggler: ({ context }) => ({ + nodeToggleButton: ({ context }) => ({ class: [ // Flex and Alignment 'inline-flex items-center justify-center', @@ -63,9 +64,6 @@ export default { // Size 'w-8 h-8', - // Spacing - 'mr-2', - // Colors 'bg-transparent', { @@ -85,111 +83,7 @@ export default { 'cursor-pointer select-none' ] }), - nodeCheckbox: ({ props, context, instance }) => ({ - root: { - class: [ - 'relative', - - // Alignment - 'inline-flex', - 'align-bottom', - - // Size - 'w-6', - 'h-6', - - // Spacing - 'mr-2', - - // Misc - 'cursor-pointer', - 'select-none' - ] - }, - box: { - class: [ - // Alignment - 'flex', - 'items-center', - 'justify-center', - - // Size - 'w-6', - 'h-6', - - // Shape - 'rounded-md', - 'border-2', - - // Colors - { - 'border-surface-200 bg-surface-0 dark:border-surface-700 dark:bg-surface-900': !context.checked, - 'border-primary-500 bg-primary-500 dark:border-primary-400 dark:bg-primary-400': context.checked - }, - - // States - { - 'peer-hover:border-primary-500 dark:peer-hover:border-primary-400': !props.disabled && !context.checked, - 'peer-hover:bg-primary-600 dark:peer-hover:bg-primary-300 peer-hover:border-primary-700 dark:peer-hover:border-primary-300': !props.disabled && context.checked, - 'peer-focus-visible:border-primary-500 dark:peer-focus-visible:border-primary-400 peer-focus-visible:ring-2 peer-focus-visible:ring-primary-400/20 dark:peer-focus-visible:ring-primary-300/20': !props.disabled, - 'cursor-default opacity-60': props.disabled - }, - - // Transitions - 'transition-colors', - 'duration-200' - ] - }, - input: { - class: [ - 'peer', - - // Size - 'w-full ', - 'h-full', - - // Position - 'absolute', - 'top-0 left-0', - 'z-10', - - // Spacing - 'p-0', - 'm-0', - - // Shape - 'opacity-0', - 'rounded-md', - 'outline-none', - 'border-2 border-surface-200 dark:border-surface-700', - - // Misc - 'appearance-none', - 'cursor-pointer' - ] - }, - icon: { - class: [ - // Font - 'text-base leading-none', - - // Size - 'w-4', - 'h-4', - - // Colors - { - 'text-white dark:text-surface-900': !instance.partialChecked, - 'text-gray dark:text-white': instance.partialChecked - }, - - // Transitions - 'transition-all', - 'duration-200' - ] - } - }), - nodeicon: { + nodeIcon: { class: [ // Space 'mr-2', @@ -198,61 +92,10 @@ export default { 'text-surface-600 dark:text-white/70' ] }, - subgroup: { + nodeChildren: { class: ['m-0 list-none p-0 pl-2 mt-1'] }, - filtercontainer: { - class: [ - 'relative block', - - // Space - 'mb-2', - - // Size - 'w-full' - ] - }, - input: { - class: [ - 'relative', - // Font - 'font-sans leading-none', - - // Spacing - 'm-0', - 'p-3 pr-10', - - // Size - 'w-full', - - // Shape - 'rounded-md', - - // Colors - 'text-surface-600 dark:text-surface-200', - 'placeholder:text-surface-400 dark:placeholder:text-surface-500', - 'bg-surface-0 dark:bg-surface-900', - 'border border-surface-300 dark:border-surface-600', - - // States - 'hover:border-primary-500 dark:hover:border-primary-400', - 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-500/50 dark:focus:ring-primary-400/50', - - // Transition & Misc - 'appearance-none', - 'transition-colors duration-200' - ] - }, - loadingicon: { + loadingIcon: { class: ['text-surface-500 dark:text-surface-0/70', 'absolute top-[50%] right-[50%] -mt-2 -mr-2 animate-spin'] - }, - searchicon: { - class: [ - // Position - 'absolute top-1/2 -mt-2 right-3', - - // Color - 'text-surface-600 dark:hover:text-white/70' - ] } }; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/treeselect/index.js b/frontend/packages/kwai-ui/src/presets/kwai/treeselect/index.js index d1e9628c..3614378b 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/treeselect/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/treeselect/index.js @@ -21,7 +21,7 @@ export default { 'duration-200', // States - { 'hover:border-primary-500 dark:hover:border-primary-300': !props.invalid }, + { 'hover:border-primary': !props.invalid }, { 'outline-none outline-offset-0 ring ring-primary-400/50 dark:ring-primary-300/50': state.focused }, // Misc @@ -35,7 +35,7 @@ export default { }, label: { class: [ - 'block leading-5', + 'block leading-[normal]', // Space 'p-3', @@ -50,7 +50,7 @@ export default { 'overflow-hidden whitespace-nowrap cursor-pointer overflow-ellipsis' ] }, - trigger: { + dropdown: { class: [ // Flexbox 'flex items-center justify-center', @@ -84,7 +84,7 @@ export default { 'dark:border-surface-700' ] }, - wrapper: { + treeContainer: { class: [ // Sizing 'max-h-[200px]', @@ -93,256 +93,6 @@ export default { 'overflow-auto' ] }, - tree: { - root: { - class: [ - // Space - 'p-5' - ] - }, - wrapper: { - class: ['overflow-auto'] - }, - container: { - class: [ - // Spacing - 'm-0 p-0', - - // Misc - 'list-none overflow-auto' - ] - }, - node: { - class: ['p-1', 'rounded-md', 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-inset focus:ring-primary-400/50 dark:focus:ring-primary-300/50'] - }, - content: ({ context, props }) => ({ - class: [ - // Flex and Alignment - 'flex items-center', - - // Shape - 'rounded-md', - - // Spacing - 'p-2', - - // Colors - 'text-surface-600 dark:text-white/70', - { 'bg-primary-50 dark:bg-primary-400/30 text-primary-600 dark:text-surface-0': context.selected }, - - // States - { 'hover:bg-surface-50 dark:hover:bg-surface-700/40': (props.selectionMode == 'single' || props.selectionMode == 'multiple') && !context.selected }, - - // Transition - 'transition-shadow duration-200', - - { 'cursor-pointer select-none': props.selectionMode == 'single' || props.selectionMode == 'multiple' } - ] - }), - toggler: ({ context }) => ({ - class: [ - // Flex and Alignment - 'inline-flex items-center justify-center', - - // Shape - 'border-0 rounded-full', - - // Size - 'w-8 h-8', - - // Spacing - 'mr-2', - - // Colors - 'bg-transparent', - { - 'text-surface-500 dark:text-white': !context.selected, - 'text-primary-600 dark:text-white': context.selected, - invisible: context.leaf - }, - - // States - 'hover:bg-surface-200/20 dark:hover:bg-surface-500/20', - 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50', - - // Transition - 'transition duration-200', - - // Misc - 'cursor-pointer select-none' - ] - }), - nodeCheckbox: ({ props, context, instance }) => ({ - root: { - class: [ - 'relative', - - // Alignment - 'inline-flex', - 'align-bottom', - - // Size - 'w-6', - 'h-6', - - // Spacing - 'mr-2', - - // Misc - 'cursor-pointer', - 'select-none' - ] - }, - box: { - class: [ - // Alignment - 'flex', - 'items-center', - 'justify-center', - - // Size - 'w-6', - 'h-6', - - // Shape - 'rounded-md', - 'border-2', - - // Colors - { - 'border-surface-200 bg-surface-0 dark:border-surface-700 dark:bg-surface-900': !context.checked, - 'border-primary-500 bg-primary-500 dark:border-primary-400 dark:bg-primary-400': context.checked - }, - - // States - { - 'peer-hover:border-primary-500 dark:peer-hover:border-primary-400': !props.disabled && !context.checked, - 'peer-hover:bg-primary-600 dark:peer-hover:bg-primary-300 peer-hover:border-primary-700 dark:peer-hover:border-primary-300': !props.disabled && context.checked, - 'peer-focus-visible:border-primary-500 dark:peer-focus-visible:border-primary-400 peer-focus-visible:ring-2 peer-focus-visible:ring-primary-400/20 dark:peer-focus-visible:ring-primary-300/20': !props.disabled, - 'cursor-default opacity-60': props.disabled - }, - - // Transitions - 'transition-colors', - 'duration-200' - ] - }, - input: { - class: [ - 'peer', - - // Size - 'w-full ', - 'h-full', - - // Position - 'absolute', - 'top-0 left-0', - 'z-10', - - // Spacing - 'p-0', - 'm-0', - - // Shape - 'opacity-0', - 'rounded-md', - 'outline-none', - 'border-2 border-surface-200 dark:border-surface-700', - - // Misc - 'appearance-none', - 'cursor-pointer' - ] - }, - icon: { - class: [ - // Font - 'text-base leading-none', - - // Size - 'w-4', - 'h-4', - - // Colors - { - 'text-white dark:text-surface-900': !instance.partialChecked, - 'text-gray dark:text-white': instance.partialChecked - }, - - // Transitions - 'transition-all', - 'duration-200' - ] - } - }), - nodeicon: { - class: [ - // Space - 'mr-2', - - // Color - 'text-surface-600 dark:text-white/70' - ] - }, - subgroup: { - class: ['m-0 list-none p-0 pl-2 mt-1'] - }, - filtercontainer: { - class: [ - 'relative block', - - // Space - 'mb-2', - - // Size - 'w-full' - ] - }, - input: { - class: [ - 'relative', - // Font - 'font-sans leading-none', - - // Spacing - 'm-0', - 'p-3 pr-10', - - // Size - 'w-full', - - // Shape - 'rounded-md', - - // Colors - 'text-surface-600 dark:text-surface-200', - 'placeholder:text-surface-400 dark:placeholder:text-surface-500', - 'bg-surface-0 dark:bg-surface-900', - 'border border-surface-300 dark:border-surface-600', - - // States - 'hover:border-primary-500 dark:hover:border-primary-400', - 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-500/50 dark:focus:ring-primary-400/50', - - // Transition & Misc - 'appearance-none', - 'transition-colors duration-200' - ] - }, - loadingicon: { - class: ['text-surface-500 dark:text-surface-0/70', 'absolute top-[50%] right-[50%] -mt-2 -mr-2 animate-spin'] - }, - searchicon: { - class: [ - // Position - 'absolute top-1/2 -mt-2 right-3', - - // Color - 'text-surface-600 dark:hover:text-white/70' - ] - } - }, transition: { enterFromClass: 'opacity-0 scale-y-[0.8]', enterActiveClass: 'transition-[transform,opacity] duration-[120ms] ease-[cubic-bezier(0,0,0.2,1)]', diff --git a/frontend/packages/kwai-ui/src/presets/kwai/treetable/index.js b/frontend/packages/kwai-ui/src/presets/kwai/treetable/index.js index 2a493c10..fbdb03aa 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/treetable/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/treetable/index.js @@ -7,7 +7,7 @@ export default { } ] }), - loadingoverlay: { + mask: { class: [ // Position 'absolute', @@ -27,10 +27,10 @@ export default { 'transition duration-200' ] }, - loadingicon: { + loadingIcon: { class: 'w-8 h-8 animate-spin' }, - wrapper: ({ props }) => ({ + tableContainer: ({ props }) => ({ class: [ // Overflow { @@ -96,7 +96,7 @@ export default { } ] }), - headerrow: ({ props }) => ({ + headerRow: ({ props }) => ({ class: [ // Flexbox & Width { @@ -111,7 +111,7 @@ export default { // Color 'dark:text-white/80', - { 'bg-primary-50 text-primary-700 dark:bg-primary-400/30': context.selected }, + { 'bg-highlight': context.selected }, { 'bg-surface-0 text-surface-600 dark:bg-surface-800': !context.selected }, // Hover & Flexbox @@ -124,7 +124,7 @@ export default { { 'transition duration-200': (props.selectionMode && !context.selected) || props.rowHover } ] }), - headercell: ({ context, props }) => ({ + headerCell: ({ context, props }) => ({ class: [ 'font-bold', @@ -146,8 +146,7 @@ export default { context?.size === 'small' ? 'p-2' : context?.size === 'large' ? 'p-5' : 'p-4', // Color - (props.sortable === '' || props.sortable) && context.sorted ? 'bg-primary-50 text-primary-700' : 'bg-surface-50 text-surface-700', - (props.sortable === '' || props.sortable) && context.sorted ? 'dark:text-white dark:bg-primary-400/30' : 'dark:text-white/80 dark:bg-surface-800', + (props.sortable === '' || props.sortable) && context.sorted ? 'bg-highlight' : 'bg-surface-50 text-surface-700 dark:text-white/80 dark:bg-surface-800', 'border-surface-200 dark:border-surface-700', // States @@ -164,7 +163,7 @@ export default { ] }), column: { - headercell: ({ context, props }) => ({ + headerCell: ({ context, props }) => ({ class: [ 'font-bold', @@ -186,8 +185,7 @@ export default { context?.size === 'small' ? 'p-2' : context?.size === 'large' ? 'p-5' : 'p-4', // Color - (props.sortable === '' || props.sortable) && context.sorted ? 'bg-primary-50 text-primary-700' : 'bg-surface-50 text-surface-700', - (props.sortable === '' || props.sortable) && context.sorted ? 'dark:text-white dark:bg-primary-400/30' : 'dark:text-white/80 dark:bg-surface-800', + (props.sortable === '' || props.sortable) && context.sorted ? 'bg-highlight' : 'bg-surface-50 text-surface-700 dark:text-white/80 dark:bg-surface-800', 'border-surface-200 dark:border-surface-700', // States @@ -203,7 +201,7 @@ export default { } ] }), - bodycell: ({ context }) => ({ + bodyCell: ({ context }) => ({ class: [ // Position { @@ -225,14 +223,10 @@ export default { }, { 'first:border-l border-r border-b': context?.showGridlines }, - // Color - 'bg-surface-0 dark:bg-surface-800', - // Spacing context?.size === 'small' ? 'p-2' : context?.size === 'large' ? 'p-5' : 'p-4', // Misc - 'dark:border-surface-700', { 'cursor-pointer': context.selectable, sticky: context.scrollable && context.scrollDirection === 'both' && context.frozen, @@ -240,7 +234,8 @@ export default { } ] }), - rowtoggler: { + bodyCellContent: 'flex items-center gap-2', + rowToggleButton: { class: [ 'relative', @@ -274,29 +269,10 @@ export default { 'cursor-pointer select-none' ] }, - sorticon: ({ context }) => ({ - class: ['ml-2 inline-block', context.sorted ? 'fill-primary-700 dark:fill-white/80' : 'fill-surface-700 dark:fill-white/70'] + sortIcon: ({ context }) => ({ + class: ['ml-2 inline-block', context.sorted ? 'text-inherit' : 'fill-surface-700 dark:fill-white/70'] }), - sortbadge: { - class: [ - // Flex & Alignment - 'inline-flex items-center justify-center align-middle', - - // Shape - 'rounded-full', - - // Size - 'w-[1.143rem] leading-[1.143rem]', - - // Spacing - 'ml-2', - - // Color - 'text-primary-700 dark:text-white', - 'bg-primary-50 dark:bg-primary-400/30' - ] - }, - columnresizer: { + columnResizer: { class: [ 'block', @@ -316,111 +292,6 @@ export default { 'cursor-col-resize' ] }, - rowCheckbox: ({ props, context, instance }) => ({ - root: { - class: [ - 'relative', - - // Alignment - 'inline-flex', - 'align-middle', - - // Size - 'w-6', - 'h-6', - - // Spacing - 'mr-2', - - // Misc - 'cursor-pointer', - 'select-none' - ] - }, - box: { - class: [ - // Alignment - 'flex', - 'items-center', - 'justify-center', - - // Size - 'w-6', - 'h-6', - - // Shape - 'rounded-md', - 'border-2', - - // Colors - { - 'border-surface-200 bg-surface-0 dark:border-surface-700 dark:bg-surface-900': !context.checked, - 'border-primary-500 bg-primary-500 dark:border-primary-400 dark:bg-primary-400': context.checked - }, - - // States - { - 'peer-hover:border-primary-500 dark:peer-hover:border-primary-400': !props.disabled && !context.checked, - 'peer-hover:bg-primary-700 dark:peer-hover:bg-primary-300 peer-hover:border-primary-700 dark:peer-hover:border-primary-300': !props.disabled && context.checked, - 'peer-focus-visible:border-primary-500 dark:peer-focus-visible:border-primary-400 peer-focus-visible:ring-2 peer-focus-visible:ring-primary-400/20 dark:peer-focus-visible:ring-primary-300/20': !props.disabled, - 'cursor-default opacity-60': props.disabled - }, - - // Transitions - 'transition-colors', - 'duration-200' - ] - }, - input: { - class: [ - 'peer', - - // Size - 'w-full ', - 'h-full', - - // Position - 'absolute', - 'top-0 left-0', - 'z-10', - - // Spacing - 'p-0', - 'm-0', - - // Shape - 'opacity-0', - 'rounded-md', - 'outline-none', - 'border-2 border-surface-200 dark:border-surface-700', - - // Misc - 'appearance-none', - 'cursor-pointer' - ] - }, - icon: { - class: [ - // Font - 'text-base leading-none', - - // Size - 'w-4', - 'h-4', - - // Colors - { - 'text-white dark:text-surface-900': !instance.partialChecked, - 'text-gray dark:text-white': instance.partialChecked - }, - - // Transitions - 'transition-all', - 'duration-200' - ] - } - }), - transition: { enterFromClass: 'opacity-0 scale-y-[0.8]', enterActiveClass: 'transition-[transform,opacity] duration-[120ms] ease-[cubic-bezier(0,0,0.2,1)]', @@ -428,7 +299,7 @@ export default { leaveToClass: 'opacity-0' } }, - resizehelper: { - class: 'absolute hidden w-[2px] z-20 bg-primary-500 dark:bg-primary-400' + columnResizeIndicator: { + class: 'absolute hidden w-[2px] z-20 bg-primary' } }; From 03f0ab5e63db33b5e3461c444217a09bee36184a Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 10 Sep 2024 19:07:40 +0200 Subject: [PATCH 202/410] feat: add primary property --- .../packages/kwai-ui/src/form/KwaiButton.vue | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/frontend/packages/kwai-ui/src/form/KwaiButton.vue b/frontend/packages/kwai-ui/src/form/KwaiButton.vue index fab4f1fb..c9a77b7c 100644 --- a/frontend/packages/kwai-ui/src/form/KwaiButton.vue +++ b/frontend/packages/kwai-ui/src/form/KwaiButton.vue @@ -7,8 +7,12 @@ interface Props { to?: RouteRecord | LocationAsRelativeRaw, method?: () => void, small?: boolean, + primary?: boolean } -const props = defineProps(); +const props = withDefaults( + defineProps(), + { to: undefined, method: undefined, small: false, primary: true } +); const attrs = useAttrs(); defineOptions({ @@ -31,6 +35,15 @@ const size = computed(() => props.small ? 'small' : undefined); @@ -39,6 +52,15 @@ const size = computed(() => props.small ? 'small' : undefined); v-else v-bind="$attrs" :size="size" + :pt="{ + root: { + class: { + 'bg-primary-500': primary, + 'text-primary-text': primary, + } + } + }" + :pt-options="{ mergeSections: false, mergeProps: true }" @[clickAttr]="method" > From 65c70a3012148c74f4376015f717556bb94b8856 Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 10 Sep 2024 19:12:41 +0200 Subject: [PATCH 203/410] fix: add flex items-center and remove data-pc-section styles --- frontend/packages/kwai-ui/src/nav/KwaiMenubar.vue | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/frontend/packages/kwai-ui/src/nav/KwaiMenubar.vue b/frontend/packages/kwai-ui/src/nav/KwaiMenubar.vue index 09ff2568..ac6f64f0 100644 --- a/frontend/packages/kwai-ui/src/nav/KwaiMenubar.vue +++ b/frontend/packages/kwai-ui/src/nav/KwaiMenubar.vue @@ -34,6 +34,7 @@ const menuItems = computed(() => { @@ -56,12 +57,3 @@ const menuItems = computed(() => { - - From 71f3743aac7719fb7c652a00386b97401fd7e0ed Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 10 Sep 2024 19:13:04 +0200 Subject: [PATCH 204/410] feat: add new theme files --- .../src/presets/kwai/confirmdialog/index.js | 3 + .../src/presets/kwai/datepicker/index.js | 435 ++++++++++++++++++ .../kwai-ui/src/presets/kwai/drawer/index.js | 149 ++++++ .../kwai-ui/src/presets/kwai/popover/index.js | 31 ++ .../kwai-ui/src/presets/kwai/select/index.js | 240 ++++++++++ .../kwai-ui/src/presets/kwai/tabs/index.js | 5 + .../src/presets/kwai/toggleswitch/index.js | 80 ++++ 7 files changed, 943 insertions(+) create mode 100644 frontend/packages/kwai-ui/src/presets/kwai/confirmdialog/index.js create mode 100644 frontend/packages/kwai-ui/src/presets/kwai/datepicker/index.js create mode 100644 frontend/packages/kwai-ui/src/presets/kwai/drawer/index.js create mode 100644 frontend/packages/kwai-ui/src/presets/kwai/popover/index.js create mode 100644 frontend/packages/kwai-ui/src/presets/kwai/select/index.js create mode 100644 frontend/packages/kwai-ui/src/presets/kwai/tabs/index.js create mode 100644 frontend/packages/kwai-ui/src/presets/kwai/toggleswitch/index.js diff --git a/frontend/packages/kwai-ui/src/presets/kwai/confirmdialog/index.js b/frontend/packages/kwai-ui/src/presets/kwai/confirmdialog/index.js new file mode 100644 index 00000000..52abb640 --- /dev/null +++ b/frontend/packages/kwai-ui/src/presets/kwai/confirmdialog/index.js @@ -0,0 +1,3 @@ +export default { + icon: 'w-8 h-8 text-[2rem] mr-2' +}; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/datepicker/index.js b/frontend/packages/kwai-ui/src/presets/kwai/datepicker/index.js new file mode 100644 index 00000000..51c0e6b5 --- /dev/null +++ b/frontend/packages/kwai-ui/src/presets/kwai/datepicker/index.js @@ -0,0 +1,435 @@ +export default { + root: ({ props }) => ({ + class: [ + // Display and Position + { + flex: props.fluid, + 'inline-flex': !props.fluid + }, + 'max-w-full', + 'relative', + + // Misc + { 'opacity-60 select-none pointer-events-none cursor-default': props.disabled } + ] + }), + pcInput: ({ props, parent }) => ({ + root: { + class: [ + // Display + 'flex-auto w-[1%]', + + // Font + 'leading-none', + + // Colors + 'text-surface-600 dark:text-surface-200', + 'placeholder:text-surface-400 dark:placeholder:text-surface-500', + 'bg-surface-0 dark:bg-surface-900', + 'border', + { 'border-surface-300 dark:border-surface-600': !props.invalid }, + + // Invalid State + { 'border-red-500 dark:border-red-400': props.invalid }, + + // Spacing + 'm-0 p-3', + + // Shape + 'appearance-none', + { 'rounded-md': !props.showIcon || props.iconDisplay == 'input' }, + { 'rounded-l-md flex-1 pr-9': props.showIcon && props.iconDisplay !== 'input' }, + { 'rounded-md flex-1 pr-9': props.showIcon && props.iconDisplay === 'input' }, + + // Transitions + 'transition-colors', + 'duration-200', + + // States + { 'hover:border-primary-emphasis': !props.invalid }, + 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-500/50 dark:focus:ring-primary-400/50', + + // Filled State *for FloatLabel + { filled: parent.instance?.$name == 'FloatLabel' && props.modelValue !== null } + ] + } + }), + dropdownIcon: { + class: ['absolute top-[50%] -mt-2', 'text-surface-600 dark:text-surface-200', 'right-[.75rem]'] + }, + dropdown: { + class: [ + 'relative w-10', + + // Alignments + 'items-center inline-flex text-center align-bottom justify-center', + + // Shape + 'rounded-r-md', + + // Size + 'px-4 py-3 leading-none', + + // Colors + 'text-primary-inverse', + 'bg-primary', + 'border border-primary', + + // States + 'focus:outline-none focus:outline-offset-0 focus:ring', + 'hover:bg-primary-hover hover:border-primary-hover', + 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50' + ] + }, + inputIconContainer: 'absolute cursor-pointer top-1/2 right-3 -mt-3', + inputIcon: 'inline-block text-base', + panel: ({ props }) => ({ + class: [ + // Display & Position + { + absolute: !props.inline, + 'inline-block': props.inline + }, + + // Size + { 'w-auto p-2 ': !props.inline }, + { 'min-w-[80vw] w-auto p-2 ': props.touchUI }, + { 'p-2 min-w-full': props.inline }, + + // Shape + 'border rounded-lg', + { + 'shadow-md': !props.inline + }, + + // Colors + 'bg-surface-0 dark:bg-surface-800', + 'border-surface-200 dark:border-surface-700', + + //misc + { 'overflow-x-auto': props.inline } + ] + }), + header: { + class: [ + //Font + 'font-semibold', + + // Flexbox and Alignment + 'flex items-center justify-between', + + // Spacing + 'p-2', + 'm-0', + + // Shape + 'border-b', + 'rounded-t-md', + + // Colors + 'text-surface-700 dark:text-white/80', + 'bg-surface-0 dark:bg-surface-800', + 'border-surface-200 dark:border-surface-700' + ] + }, + title: { + class: [ + // Text + 'leading-8', + 'mx-auto my-0' + ] + }, + selectMonth: { + class: [ + // Font + 'text-base leading-[normal]', + 'font-semibold', + + // Colors + 'text-surface-700 dark:text-white/80', + + // Transitions + 'transition duration-200', + + // Spacing + 'p-2', + 'm-0 mr-2', + + // States + 'hover:text-primary-500 dark:hover:text-primary-400', + + // Misc + 'cursor-pointer' + ] + }, + selectYear: { + class: [ + // Font + 'text-base leading-[normal]', + 'font-semibold', + + // Colors + 'text-surface-700 dark:text-white/80', + + // Transitions + 'transition duration-200', + + // Spacing + 'p-2', + 'm-0', + + // States + 'hover:text-primary-500 dark:hover:text-primary-400', + + // Misc + 'cursor-pointer' + ] + }, + table: { + class: [ + // Font + 'text-base leading-none', + // Size & Shape + 'border-collapse', + 'w-full', + + // Spacing + 'm-0 my-2' + ] + }, + tableHeaderCell: { + class: [ + // Spacing + 'p-0 md:p-2' + ] + }, + weekHeader: { + class: ['leading-[normal]', 'text-surface-600 dark:text-white/70', 'opacity-60 cursor-default'] + }, + weekNumber: { + class: ['text-surface-600 dark:text-white/70', 'opacity-60 cursor-default'] + }, + weekday: { + class: [ + // Colors + 'text-surface-500 dark:text-white/60' + ] + }, + dayCell: { + class: [ + // Spacing + 'p-0 md:p-2' + ] + }, + weekLabelContainer: { + class: [ + // Flexbox and Alignment + 'flex items-center justify-center', + 'mx-auto', + + // Shape & Size + 'w-10 h-10', + 'rounded-full', + 'border-transparent border', + + // Colors + 'opacity-60 cursor-default' + ] + }, + dayView: 'w-full', + day: ({ context }) => ({ + class: [ + // Flexbox and Alignment + 'flex items-center justify-center', + 'mx-auto', + + // Shape & Size + 'w-10 h-10', + 'rounded-full', + 'border-transparent border', + + // Colors + { + 'text-primary': context.date.today, + 'text-surface-600 dark:text-white/70 bg-transparent': !context.selected && !context.disabled && !context.date.today, + 'bg-highlight': context.selected && !context.disabled + }, + + // States + 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50', + { + 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context.selected && !context.disabled, + 'hover:bg-primary-highlight-hover': context.selected && !context.disabled + }, + { + 'opacity-60 cursor-default': context.disabled, + 'cursor-pointer': !context.disabled + } + ] + }), + monthView: { + class: [ + // Spacing + 'my-2' + ] + }, + month: ({ context }) => ({ + class: [ + // Flexbox and Alignment + 'inline-flex items-center justify-center', + + // Size + 'w-1/3', + 'p-2', + + // Shape + 'rounded-md', + + // Colors + { + 'text-surface-600 dark:text-white/70 bg-transparent': !context.selected && !context.disabled, + 'bg-highlight': context.selected && !context.disabled + }, + + // States + 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50', + { + 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context.selected && !context.disabled, + 'hover:bg-primary-highlight-hover': context.selected && !context.disabled + }, + + // Misc + 'cursor-pointer' + ] + }), + yearView: { + class: [ + // Spacing + 'my-2' + ] + }, + year: ({ context }) => ({ + class: [ + // Flexbox and Alignment + 'inline-flex items-center justify-center', + + // Size + 'w-1/3', + 'p-2', + + // Shape + 'rounded-md', + + // Colors + { + 'text-surface-600 dark:text-white/70 bg-transparent': !context.selected && !context.disabled, + 'bg-highlight': context.selected && !context.disabled + }, + + // States + 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50', + { + 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context.selected && !context.disabled, + 'hover:bg-primary-highlight-hover': context.selected && !context.disabled + }, + + // Misc + 'cursor-pointer' + ] + }), + timePicker: { + class: [ + // Flexbox + 'flex', + 'justify-center items-center', + + // Borders + 'border-t-1', + 'border-solid border-surface-200', + + // Spacing + 'p-2' + ] + }, + separatorContainer: { + class: [ + // Flexbox and Alignment + 'flex', + 'items-center', + 'flex-col', + + // Spacing + 'px-2' + ] + }, + separator: { + class: [ + // Text + 'text-xl' + ] + }, + hourPicker: { + class: [ + // Flexbox and Alignment + 'flex', + 'items-center', + 'flex-col', + + // Spacing + 'px-2' + ] + }, + minutePicker: { + class: [ + // Flexbox and Alignment + 'flex', + 'items-center', + 'flex-col', + + // Spacing + 'px-2' + ] + }, + secondPicker: { + class: [ + // Flexbox and Alignment + 'flex', + 'items-center', + 'flex-col', + + // Spacing + 'px-2' + ] + }, + ampmPicker: { + class: [ + // Flexbox and Alignment + 'flex', + 'items-center', + 'flex-col', + + // Spacing + 'px-2' + ] + }, + calendarContainer: 'flex', + calendar: 'flex-auto border-l first:border-l-0 border-surface-200', + buttonbar: { + class: [ + // Flexbox + 'flex justify-between items-center', + + // Spacing + 'py-3 px-0', + + // Shape + 'border-t border-surface-200 dark:border-surface-700' + ] + }, + transition: { + enterFromClass: 'opacity-0 scale-y-[0.8]', + enterActiveClass: 'transition-[transform,opacity] duration-[120ms] ease-[cubic-bezier(0,0,0.2,1)]', + leaveActiveClass: 'transition-opacity duration-100 ease-linear', + leaveToClass: 'opacity-0' + } +}; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/drawer/index.js b/frontend/packages/kwai-ui/src/presets/kwai/drawer/index.js new file mode 100644 index 00000000..27b4160d --- /dev/null +++ b/frontend/packages/kwai-ui/src/presets/kwai/drawer/index.js @@ -0,0 +1,149 @@ +export default { + root: ({ props }) => ({ + class: [ + // Flexbox + 'flex flex-col', + + // Position + 'relative', + { '!transition-none !transform-none !w-screen !h-screen !max-h-full !top-0 !left-0': props.position == 'full' }, + + // Size + { + 'h-full w-80': props.position == 'left' || props.position == 'right', + 'h-auto w-full': props.position == 'top' || props.position == 'bottom' + }, + + // Shape + 'border-0 dark:border', + 'shadow-lg', + + // Colors + 'bg-surface-0 dark:bg-surface-800', + 'text-surface-700 dark:text-white/80', + 'dark:border-surface-700', + + // Transitions + 'transition-transform', + 'duration-300', + + // Misc + 'pointer-events-auto' + ] + }), + header: { + class: [ + // Flexbox and Alignment + 'flex items-center justify-between', + 'shrink-0', + + // Spacing + 'p-5', + + // Colors + 'bg-surface-0 dark:bg-surface-800', + 'text-surface-700 dark:text-surface-0/80' + ] + }, + title: { + class: ['font-bold text-lg'] + }, + icons: { + class: ['flex items-center'] + }, + closeButton: { + class: [ + 'relative', + + // Flexbox and Alignment + 'flex items-center justify-center', + + // Size and Spacing + 'mr-2', + 'last:mr-0', + 'w-8 h-8', + + // Shape + 'border-0', + 'rounded-full', + + // Colors + 'text-surface-500', + 'bg-transparent', + + // Transitions + 'transition duration-200 ease-in-out', + + // States + 'hover:text-surface-700 dark:hover:text-white/80', + 'hover:bg-surface-100 dark:hover:bg-surface-800/80', + 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-inset', + 'focus:ring-primary-400/50 dark:focus:ring-primary-300/50', + + // Misc + 'overflow-hidden' + ] + }, + closeButtonIcon: { + class: [ + // Display + 'inline-block', + + // Size + 'w-4', + 'h-4' + ] + }, + content: { + class: [ + // Spacing and Size + 'p-5', + 'pt-0', + 'h-full', + 'w-full', + + // Growth and Overflow + 'grow', + 'overflow-y-auto' + ] + }, + mask: ({ props }) => ({ + class: [ + // Transitions + 'transition-all', + 'duration-300', + { 'p-5': !props.position == 'full' }, + + // Background and Effects + { 'has-[.mask-active]:bg-transparent bg-black/40': props.modal, 'has-[.mask-active]:backdrop-blur-none backdrop-blur-sm': props.modal } + ] + }), + transition: ({ props }) => { + return props.position === 'top' + ? { + enterFromClass: 'translate-x-0 -translate-y-full translate-z-0 mask-active', + leaveToClass: 'translate-x-0 -translate-y-full translate-z-0 mask-active' + } + : props.position === 'bottom' + ? { + enterFromClass: 'translate-x-0 translate-y-full translate-z-0 mask-active', + leaveToClass: 'translate-x-0 translate-y-full translate-z-0 mask-active' + } + : props.position === 'left' + ? { + enterFromClass: '-translate-x-full translate-y-0 translate-z-0 mask-active', + leaveToClass: '-translate-x-full translate-y-0 translate-z-0 mask-active' + } + : props.position === 'right' + ? { + enterFromClass: 'translate-x-full translate-y-0 translate-z-0 mask-active', + leaveToClass: 'translate-x-full translate-y-0 translate-z-0 mask-active' + } + : { + enterFromClass: 'opacity-0 mask-active', + enterActiveClass: 'transition-opacity duration-400 ease-in', + leaveActiveClass: 'transition-opacity duration-400 ease-in', + leaveToClass: 'opacity-0 mask-active' + }; + } +}; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/popover/index.js b/frontend/packages/kwai-ui/src/presets/kwai/popover/index.js new file mode 100644 index 00000000..1bb96eb3 --- /dev/null +++ b/frontend/packages/kwai-ui/src/presets/kwai/popover/index.js @@ -0,0 +1,31 @@ +export default { + root: { + class: [ + // Shape + 'rounded-md shadow-lg', + 'border-0 dark:border', + + // Position + 'absolute left-0 top-0 mt-2', + 'z-40 transform origin-center', + + // Color + 'bg-surface-0 dark:bg-surface-800', + 'text-surface-700 dark:text-surface-0/80', + 'dark:border-surface-700', + + // Before: Arrow + 'before:absolute before:w-0 before:-top-3 before:h-0 before:border-transparent before:border-solid before:ml-[10px] before:border-x-[10px] before:border-b-[10px] before:border-t-0 before:border-b-surface-300/10 dark:before:border-b-surface-700', + 'after:absolute after:w-0 after:-top-[0.54rem] after:left-[4px] after:h-0 after:border-transparent after:border-solid after:ml-[8px] after:border-x-[8px] after:border-b-[8px] after:border-t-0 after:border-b-surface-0 dark:after:border-b-surface-800' + ] + }, + content: { + class: 'p-5 items-center flex' + }, + transition: { + enterFromClass: 'opacity-0 scale-y-[0.8]', + enterActiveClass: 'transition-[transform,opacity] duration-[120ms] ease-[cubic-bezier(0,0,0.2,1)]', + leaveActiveClass: 'transition-opacity duration-100 ease-linear', + leaveToClass: 'opacity-0' + } +}; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/select/index.js b/frontend/packages/kwai-ui/src/presets/kwai/select/index.js new file mode 100644 index 00000000..8d6158af --- /dev/null +++ b/frontend/packages/kwai-ui/src/presets/kwai/select/index.js @@ -0,0 +1,240 @@ +export default { + root: ({ props, state, parent }) => ({ + class: [ + // Display and Position + 'inline-flex', + 'relative', + + // Shape + { 'rounded-md': parent.instance.$name !== 'InputGroup' }, + { 'first:rounded-l-md rounded-none last:rounded-r-md': parent.instance.$name == 'InputGroup' }, + { 'border-0 border-y border-l last:border-r': parent.instance.$name == 'InputGroup' }, + { 'first:ml-0 ml-[-1px]': parent.instance.$name == 'InputGroup' && !props.showButtons }, + + // Color and Background + 'bg-surface-0 dark:bg-surface-900', + + 'border border-surface-300', + { 'dark:border-surface-700': parent.instance.$name != 'InputGroup' }, + { 'dark:border-surface-600': parent.instance.$name == 'InputGroup' }, + { 'border-surface-300 dark:border-surface-600': !props.invalid }, + + // Invalid State + { 'border-red-500 dark:border-red-400': props.invalid }, + + // Transitions + 'transition-all', + 'duration-200', + + // States + { 'hover:border-primary': !props.invalid }, + { 'outline-none outline-offset-0 ring ring-primary-400/50 dark:ring-primary-300/50': state.focused }, + + // Misc + 'cursor-pointer', + 'select-none', + { 'opacity-60': props.disabled, 'pointer-events-none': props.disabled, 'cursor-default': props.disabled } + ] + }), + label: ({ props, parent }) => ({ + class: [ + //Font + 'leading-[normal]', + + // Display + 'block', + 'flex-auto', + + // Color and Background + 'bg-transparent', + 'border-0', + { 'text-surface-800 dark:text-white/80': props.modelValue != undefined, 'text-surface-400 dark:text-surface-500': props.modelValue == undefined }, + 'placeholder:text-surface-400 dark:placeholder:text-surface-500', + + // Sizing and Spacing + 'w-[1%]', + 'p-3', + { 'pr-7': props.showClear }, + + //Shape + 'rounded-none', + + // Transitions + 'transition', + 'duration-200', + + // States + 'focus:outline-none focus:shadow-none', + + // Filled State *for FloatLabel + { filled: parent.instance?.$name == 'FloatLabel' && props.modelValue !== null }, + + // Misc + 'relative', + 'cursor-pointer', + 'overflow-hidden overflow-ellipsis', + 'whitespace-nowrap', + 'appearance-none' + ] + }), + dropdown: { + class: [ + // Flexbox + 'flex items-center justify-center', + 'shrink-0', + + // Color and Background + 'bg-transparent', + 'text-surface-500', + + // Size + 'w-12', + + // Shape + 'rounded-tr-md', + 'rounded-br-md' + ] + }, + overlay: { + class: [ + // Position + 'absolute top-0 left-0', + + // Shape + 'border-0 dark:border', + 'rounded-md', + 'shadow-md', + + // Color + 'bg-surface-0 dark:bg-surface-800', + 'text-surface-800 dark:text-white/80', + 'dark:border-surface-700' + ] + }, + listContainer: { + class: [ + // Sizing + 'max-h-[200px]', + + // Misc + 'overflow-auto' + ] + }, + list: { + class: 'py-3 list-none m-0' + }, + option: ({ context }) => ({ + class: [ + // Font + 'font-normal', + 'leading-none', + + // Position + 'relative', + 'flex items-center', + + // Shape + 'border-0', + 'rounded-none', + + // Spacing + 'm-0', + 'py-3 px-5', + + // Colors + { + 'text-surface-700 dark:text-white/80': !context.focused && !context.selected, + 'bg-surface-200 dark:bg-surface-600/60': context.focused && !context.selected, + 'text-surface-700 dark:text-white/80': context.focused && !context.selected, + 'bg-highlight': context.selected + }, + + //States + { 'hover:bg-surface-100 dark:hover:bg-surface-600/80': !context.focused && !context.selected }, + { 'hover:bg-highlight-emphasis': context.selected }, + 'focus-visible:outline-none focus-visible:outline-offset-0 focus-visible:ring focus-visible:ring-inset focus-visible:ring-primary-400/50 dark:focus-visible:ring-primary-300/50', + + // Transitions + 'transition-shadow', + 'duration-200', + + // Misc + { 'pointer-events-none cursor-default': context.disabled }, + { 'cursor-pointer': !context.disabled }, + 'overflow-hidden', + 'whitespace-nowrap' + ] + }), + optionGroup: { + class: [ + //Font + 'font-bold', + + // Spacing + 'm-0', + 'py-3 px-5', + + // Color + 'text-surface-800 dark:text-white/80', + 'bg-surface-0 dark:bg-surface-600/80', + + // Misc + 'cursor-auto' + ] + }, + optionCheckIcon: 'relative -ms-1.5 me-1.5 text-surface-700 dark:text-white/80 w-4 h-4', + optionBlankIcon: 'w-4 h-4', + emptyMessage: { + class: [ + // Font + 'leading-none', + + // Spacing + 'py-3 px-5', + + // Color + 'text-surface-800 dark:text-white/80', + 'bg-transparent' + ] + }, + header: { + class: [ + // Spacing + 'py-3 px-5', + 'm-0', + + //Shape + 'border-b', + 'rounded-tl-md', + 'rounded-tr-md', + + // Color + 'text-surface-700 dark:text-white/80', + 'bg-surface-100 dark:bg-surface-800', + 'border-surface-300 dark:border-surface-700' + ] + }, + clearIcon: { + class: [ + // Color + 'text-surface-500', + + // Position + 'absolute', + 'top-1/2', + 'right-12', + + // Spacing + '-mt-2' + ] + }, + loadingIcon: { + class: 'text-surface-400 dark:text-surface-500 animate-spin' + }, + transition: { + enterFromClass: 'opacity-0 scale-y-[0.8]', + enterActiveClass: 'transition-[transform,opacity] duration-[120ms] ease-[cubic-bezier(0,0,0.2,1)]', + leaveActiveClass: 'transition-opacity duration-100 ease-linear', + leaveToClass: 'opacity-0' + } +}; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/tabs/index.js b/frontend/packages/kwai-ui/src/presets/kwai/tabs/index.js new file mode 100644 index 00000000..0e694583 --- /dev/null +++ b/frontend/packages/kwai-ui/src/presets/kwai/tabs/index.js @@ -0,0 +1,5 @@ +export default { + root: ({ props }) => ({ + class: ['flex flex-col', { '[&>[data-pc-name=tablist]]:overflow-hidden': props.scrollable }] + }) +}; diff --git a/frontend/packages/kwai-ui/src/presets/kwai/toggleswitch/index.js b/frontend/packages/kwai-ui/src/presets/kwai/toggleswitch/index.js new file mode 100644 index 00000000..e602c3ff --- /dev/null +++ b/frontend/packages/kwai-ui/src/presets/kwai/toggleswitch/index.js @@ -0,0 +1,80 @@ +export default { + root: ({ props }) => ({ + class: [ + 'inline-block relative', + 'w-12 h-7', + 'rounded-2xl', + { + 'opacity-60 select-none pointer-events-none cursor-default': props.disabled + } + ] + }), + slider: ({ props }) => ({ + class: [ + // Position + 'absolute top-0 left-0 right-0 bottom-0', + { 'before:transform before:translate-x-5': props.modelValue == props.trueValue }, + + // Shape + 'rounded-2xl', + + // Before: + 'before:absolute before:top-1/2 before:left-1', + 'before:-mt-2.5', + 'before:h-5 before:w-5', + 'before:rounded-full', + 'before:duration-200', + 'before:bg-surface-0 before:dark:bg-surface-900', + + // Colors + 'border', + { + 'bg-surface-200 dark:bg-surface-700': !(props.modelValue == props.trueValue), + 'bg-primary': props.modelValue == props.trueValue + }, + + { 'border-transparent': !props.invalid }, + + // Invalid State + { 'border-red-500 dark:border-red-400': props.invalid }, + + // States + { 'peer-hover:bg-surface-300 dark:peer-hover:bg-surface-600 ': !(props.modelValue == props.trueValue) && !props.disabled }, + { 'peer-hover:bg-primary-hover ': props.modelValue == props.trueValue && !props.disabled }, + 'peer-focus-visible:ring peer-focus-visible:ring-primary-400/50 dark:peer-focus-visible:ring-primary-300/50', + + // Transition + 'transition-colors duration-200', + + // Misc + 'cursor-pointer' + ] + }), + input: { + class: [ + 'peer', + + // Size + 'w-full ', + 'h-full', + + // Position + 'absolute', + 'top-0 left-0', + 'z-10', + + // Spacing + 'p-0', + 'm-0', + + // Shape + 'opacity-0', + 'rounded-[2.5rem]', + 'outline-none', + + // Misc + 'appearance-none', + 'cursor-pointer' + ] + } +}; From 76ed364bcc5f89856c86926ba23f395f1d3aabb9 Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 10 Sep 2024 19:14:31 +0200 Subject: [PATCH 205/410] chore: text-center for number of members --- frontend/apps/club/src/pages/teams/TeamsPage.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/apps/club/src/pages/teams/TeamsPage.vue b/frontend/apps/club/src/pages/teams/TeamsPage.vue index 6ed0d7b4..a097c6f1 100644 --- a/frontend/apps/club/src/pages/teams/TeamsPage.vue +++ b/frontend/apps/club/src/pages/teams/TeamsPage.vue @@ -47,7 +47,7 @@ const { data: teams, isPending, isError } = useTeams({}); {{ t('teams.members') }} @@ -78,7 +78,7 @@ const { data: teams, isPending, isError } = useTeams({}); {{ team.name }} - + {{ team.members.length }} From b4e1f624721911e2c682192cc06efe83d868f2c2 Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 10 Sep 2024 19:20:00 +0200 Subject: [PATCH 206/410] feat: add AddMemberIcon.vue --- .../club/src/components/icons/AddMemberIcon.vue | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 frontend/apps/club/src/components/icons/AddMemberIcon.vue diff --git a/frontend/apps/club/src/components/icons/AddMemberIcon.vue b/frontend/apps/club/src/components/icons/AddMemberIcon.vue new file mode 100644 index 00000000..8945c90e --- /dev/null +++ b/frontend/apps/club/src/components/icons/AddMemberIcon.vue @@ -0,0 +1,15 @@ + + + + + From 5bcb4867e205d9220f29d6749abfcd5c8f7fbdc4 Mon Sep 17 00:00:00 2001 From: zumuta Date: Tue, 10 Sep 2024 20:01:01 +0200 Subject: [PATCH 207/410] feat: add icon slot --- frontend/packages/kwai-ui/src/form/KwaiButton.vue | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frontend/packages/kwai-ui/src/form/KwaiButton.vue b/frontend/packages/kwai-ui/src/form/KwaiButton.vue index c9a77b7c..924a9bea 100644 --- a/frontend/packages/kwai-ui/src/form/KwaiButton.vue +++ b/frontend/packages/kwai-ui/src/form/KwaiButton.vue @@ -46,6 +46,9 @@ const size = computed(() => props.small ? 'small' : undefined); :pt-options="{ mergeSections: false, mergeProps: true }" > + From ea45395ca8b1131b6f34ef5a8bd093c123858cb8 Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 11 Sep 2024 16:49:41 +0200 Subject: [PATCH 208/410] refactor: use KwaiButton instead of Button --- frontend/apps/auth/src/index.ts | 3 + .../auth/src/pages/ChangePasswordPage.vue | 144 ++++++------ frontend/apps/auth/src/pages/InvitedPage.vue | 206 +++++++++--------- frontend/apps/auth/src/pages/LoginPage.vue | 11 +- .../auth/src/pages/RecoverPasswordPage.vue | 92 ++++---- .../apps/auth/src/pages/ResetPasswordPage.vue | 184 ++++++++-------- 6 files changed, 321 insertions(+), 319 deletions(-) diff --git a/frontend/apps/auth/src/index.ts b/frontend/apps/auth/src/index.ts index 44f4738f..7eed5faf 100644 --- a/frontend/apps/auth/src/index.ts +++ b/frontend/apps/auth/src/index.ts @@ -10,6 +10,8 @@ import messages from '@intlify/unplugin-vue-i18n/messages'; // Setup pinia store import { createPinia } from 'pinia'; +import { init } from '@kwai/ui'; + // Setup router import { createRouter, createWebHistory } from 'vue-router'; import { routes } from './routes'; @@ -30,5 +32,6 @@ const router = createRouter({ routes, }); app.use(router); +init(app); app.mount('#app'); diff --git a/frontend/apps/auth/src/pages/ChangePasswordPage.vue b/frontend/apps/auth/src/pages/ChangePasswordPage.vue index 7b84ccd5..3e565cda 100644 --- a/frontend/apps/auth/src/pages/ChangePasswordPage.vue +++ b/frontend/apps/auth/src/pages/ChangePasswordPage.vue @@ -1,77 +1,6 @@ - - + + diff --git a/frontend/apps/auth/src/pages/InvitedPage.vue b/frontend/apps/auth/src/pages/InvitedPage.vue index 481db2e7..18028874 100644 --- a/frontend/apps/auth/src/pages/InvitedPage.vue +++ b/frontend/apps/auth/src/pages/InvitedPage.vue @@ -1,3 +1,102 @@ + + - - diff --git a/frontend/apps/auth/src/pages/LoginPage.vue b/frontend/apps/auth/src/pages/LoginPage.vue index 45dfc549..f4726ede 100644 --- a/frontend/apps/auth/src/pages/LoginPage.vue +++ b/frontend/apps/auth/src/pages/LoginPage.vue @@ -1,5 +1,5 @@ + + diff --git a/frontend/apps/auth/src/pages/ResetPasswordPage.vue b/frontend/apps/auth/src/pages/ResetPasswordPage.vue index 61d27c5c..95a34fcf 100644 --- a/frontend/apps/auth/src/pages/ResetPasswordPage.vue +++ b/frontend/apps/auth/src/pages/ResetPasswordPage.vue @@ -1,3 +1,91 @@ + + - - From 7a49f20c14f261c231ca53f4153086d5a6cf58fb Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 11 Sep 2024 20:58:10 +0200 Subject: [PATCH 209/410] refactor: use KwaiButton instead of Button and PrimaryButton --- .../author/src/components/AuthorToolbar.vue | 7 ++--- .../author/src/components/PrimaryButton.vue | 24 --------------- frontend/apps/author/src/index.ts | 3 ++ frontend/apps/author/src/pages/HomePage.vue | 15 +++++----- .../applications/ApplicationEditPage.vue | 9 +++--- .../pages/applications/ApplicationsPage.vue | 7 ++--- .../apps/author/src/pages/news/NewsPage.vue | 16 ++++------ .../src/pages/news/components/NewsForm.vue | 9 +++--- .../apps/author/src/pages/pages/PagesPage.vue | 16 ++++------ .../src/pages/pages/components/PageForm.vue | 11 +++---- frontend/apps/author/tailwind.config.js | 8 ++++- .../club/src/components/PrimaryButton.vue | 26 ----------------- .../apps/club/src/pages/teams/TeamsPage.vue | 16 ++++++++-- .../coach/src/components/CoachToolbar.vue | 7 ++--- .../coach/src/components/PrimaryButton.vue | 26 ----------------- frontend/apps/coach/src/index.ts | 3 ++ .../apps/coach/src/pages/home/HomePage.vue | 5 ++-- .../components/TrainingDefinitionsCard.vue | 5 ++-- .../pages/home/components/TrainingsCard.vue | 7 ++--- .../GenerateTrainingsPage.vue | 16 ++++------ .../TrainingDefinitionsPage.vue | 26 +++++++---------- .../components/TrainingDefinitionForm.vue | 9 +++--- .../src/pages/trainings/TrainingsPage.vue | 20 +++++-------- .../trainings/components/TrainingForm.vue | 18 ++++-------- frontend/apps/coach/tailwind.config.js | 8 ++++- .../portal/src/components/PrimaryButton.vue | 29 ------------------- .../apps/portal/src/pages/TrainingsPage.vue | 23 +++++---------- 27 files changed, 119 insertions(+), 250 deletions(-) delete mode 100644 frontend/apps/author/src/components/PrimaryButton.vue delete mode 100644 frontend/apps/club/src/components/PrimaryButton.vue delete mode 100644 frontend/apps/coach/src/components/PrimaryButton.vue delete mode 100644 frontend/apps/portal/src/components/PrimaryButton.vue diff --git a/frontend/apps/author/src/components/AuthorToolbar.vue b/frontend/apps/author/src/components/AuthorToolbar.vue index 0161ae59..3d61666a 100644 --- a/frontend/apps/author/src/components/AuthorToolbar.vue +++ b/frontend/apps/author/src/components/AuthorToolbar.vue @@ -3,10 +3,9 @@ import logoUrl from '/logo.png'; import { website } from '@kwai/config'; import type { MenuItem } from '@kwai/ui'; -import { ToolbarLogo, ToolbarMenu } from '@kwai/ui'; +import { KwaiButton, ToolbarLogo, ToolbarMenu } from '@kwai/ui'; import { useRouter } from 'vue-router'; import { computed } from 'vue'; -import PrimaryButton from '@root/components/PrimaryButton.vue'; const router = useRouter(); const menuItems = computed(() : MenuItem[] => { @@ -43,9 +42,9 @@ const menuItems = computed(() : MenuItem[] => {
- + Login - +
diff --git a/frontend/apps/author/src/components/PrimaryButton.vue b/frontend/apps/author/src/components/PrimaryButton.vue deleted file mode 100644 index fbfc30c0..00000000 --- a/frontend/apps/author/src/components/PrimaryButton.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - - - diff --git a/frontend/apps/author/src/index.ts b/frontend/apps/author/src/index.ts index 89886a94..b3f22b45 100644 --- a/frontend/apps/author/src/index.ts +++ b/frontend/apps/author/src/index.ts @@ -12,6 +12,8 @@ import messages from '@intlify/unplugin-vue-i18n/messages'; import routes from './routes'; +import { init } from '@kwai/ui'; + const app = createApp(App); app.use(VueQueryPlugin); @@ -27,5 +29,6 @@ const router = createRouter({ routes, }); app.use(router); +init(app); app.mount('#app'); diff --git a/frontend/apps/author/src/pages/HomePage.vue b/frontend/apps/author/src/pages/HomePage.vue index 7c9ab94c..31675c35 100644 --- a/frontend/apps/author/src/pages/HomePage.vue +++ b/frontend/apps/author/src/pages/HomePage.vue @@ -1,6 +1,5 @@ diff --git a/frontend/apps/author/src/pages/news/NewsPage.vue b/frontend/apps/author/src/pages/news/NewsPage.vue index 7d433ec7..1237f3ee 100644 --- a/frontend/apps/author/src/pages/news/NewsPage.vue +++ b/frontend/apps/author/src/pages/news/NewsPage.vue @@ -8,12 +8,12 @@ import { CancelIcon, CheckIcon, EditIcon, + KwaiButton, OffsetPagination, usePagination, } from '@kwai/ui'; import { useNewsItems } from '@root/composables/useNewsItem'; -import PrimaryButton from '@root/components/PrimaryButton.vue'; import { useI18n } from 'vue-i18n'; import PromotedIcon from '@root/components/icons/PromotedIcon.vue'; @@ -37,13 +37,10 @@ const { data: newsItems } = useNewsItems({ offset, limit });

- + - + diff --git a/frontend/apps/author/src/pages/news/components/NewsForm.vue b/frontend/apps/author/src/pages/news/components/NewsForm.vue index eb1d49d5..a5039f7f 100644 --- a/frontend/apps/author/src/pages/news/components/NewsForm.vue +++ b/frontend/apps/author/src/pages/news/components/NewsForm.vue @@ -1,6 +1,6 @@ - - - - diff --git a/frontend/apps/club/src/pages/teams/TeamsPage.vue b/frontend/apps/club/src/pages/teams/TeamsPage.vue index a097c6f1..55260970 100644 --- a/frontend/apps/club/src/pages/teams/TeamsPage.vue +++ b/frontend/apps/club/src/pages/teams/TeamsPage.vue @@ -6,10 +6,13 @@ import { ContainerSectionTitle, ContainerSectionContent, ErrorAlert, + KwaiButton, LoadingIcon, CheckIcon, CancelIcon, + EditIcon, } from '@kwai/ui'; +import AddMemberIcon from '@root/components/icons/AddMemberIcon.vue'; const { t } = useI18n({ useScope: 'global' }); const { data: teams, isPending, isError } = useTeams({}); @@ -84,8 +87,17 @@ const { data: teams, isPending, isError } = useTeams({}); {{ team.remark }} - - Edit + + + + + + + diff --git a/frontend/apps/coach/src/components/CoachToolbar.vue b/frontend/apps/coach/src/components/CoachToolbar.vue index af7733a3..e3feaec7 100644 --- a/frontend/apps/coach/src/components/CoachToolbar.vue +++ b/frontend/apps/coach/src/components/CoachToolbar.vue @@ -1,9 +1,8 @@ @@ -28,9 +27,9 @@ const menuItems = useMenu();
- + Login - +
diff --git a/frontend/apps/coach/src/components/PrimaryButton.vue b/frontend/apps/coach/src/components/PrimaryButton.vue deleted file mode 100644 index b4d5ba9a..00000000 --- a/frontend/apps/coach/src/components/PrimaryButton.vue +++ /dev/null @@ -1,26 +0,0 @@ - - - - - diff --git a/frontend/apps/coach/src/index.ts b/frontend/apps/coach/src/index.ts index 271ef479..8235c24a 100644 --- a/frontend/apps/coach/src/index.ts +++ b/frontend/apps/coach/src/index.ts @@ -11,6 +11,8 @@ import messages from '@intlify/unplugin-vue-i18n/messages'; import { VueQueryPlugin } from '@tanstack/vue-query'; +import { init } from '@kwai/ui'; + const app = createApp(App); app.use(VueQueryPlugin); @@ -27,4 +29,5 @@ const router = createRouter({ }); app.use(router); +init(app); app.mount('#app'); diff --git a/frontend/apps/coach/src/pages/home/HomePage.vue b/frontend/apps/coach/src/pages/home/HomePage.vue index cdd89943..1b7d46dc 100644 --- a/frontend/apps/coach/src/pages/home/HomePage.vue +++ b/frontend/apps/coach/src/pages/home/HomePage.vue @@ -1,7 +1,6 @@ @@ -24,12 +23,12 @@ const { t } = useI18n({ useScope: 'global' });

diff --git a/frontend/apps/coach/src/pages/home/components/TrainingDefinitionsCard.vue b/frontend/apps/coach/src/pages/home/components/TrainingDefinitionsCard.vue index 47e919d9..daba10ec 100644 --- a/frontend/apps/coach/src/pages/home/components/TrainingDefinitionsCard.vue +++ b/frontend/apps/coach/src/pages/home/components/TrainingDefinitionsCard.vue @@ -1,6 +1,5 @@ @@ -17,12 +16,12 @@ const { t } = useI18n({ useScope: 'global' });

diff --git a/frontend/apps/coach/src/pages/home/components/TrainingsCard.vue b/frontend/apps/coach/src/pages/home/components/TrainingsCard.vue index e7036e8d..dbf1f90a 100644 --- a/frontend/apps/coach/src/pages/home/components/TrainingsCard.vue +++ b/frontend/apps/coach/src/pages/home/components/TrainingsCard.vue @@ -1,6 +1,5 @@ @@ -17,12 +16,12 @@ const { t } = useI18n({ useScope: 'global' });

diff --git a/frontend/apps/coach/src/pages/training_definitions/GenerateTrainingsPage.vue b/frontend/apps/coach/src/pages/training_definitions/GenerateTrainingsPage.vue index 66c46427..cd4a7b88 100644 --- a/frontend/apps/coach/src/pages/training_definitions/GenerateTrainingsPage.vue +++ b/frontend/apps/coach/src/pages/training_definitions/GenerateTrainingsPage.vue @@ -9,11 +9,11 @@ import { DateRangePicker, DeleteIcon, InfoAlert, + KwaiButton, LinkTag, NewIcon, } from '@kwai/ui'; import { useI18n } from 'vue-i18n'; -import PrimaryButton from '@root/components/PrimaryButton.vue'; import TrainingDefinitionCard from '@root/pages/training_definitions/components/TrainingDefinitionCard.vue'; import { ref, toRef } from 'vue'; import { useForm } from 'vee-validate'; @@ -98,13 +98,10 @@ const saveTrainings = () => { name="period" :time="false" /> - + {{ t('generate_trainings.banner.button') }} - + @@ -171,13 +168,10 @@ const saveTrainings = () => { v-if="trainings.length > 0" class="w-full flex flex-col" > - + {{ t('generate_trainings.save') }} - +
diff --git a/frontend/apps/coach/src/pages/training_definitions/TrainingDefinitionsPage.vue b/frontend/apps/coach/src/pages/training_definitions/TrainingDefinitionsPage.vue index 28813538..c2831b81 100644 --- a/frontend/apps/coach/src/pages/training_definitions/TrainingDefinitionsPage.vue +++ b/frontend/apps/coach/src/pages/training_definitions/TrainingDefinitionsPage.vue @@ -4,11 +4,12 @@ import { ContainerSection, ContainerSectionBanner, ContainerSectionContent, - ContainerSectionTitle, EditIcon, + ContainerSectionTitle, + EditIcon, + KwaiButton, NewIcon, } from '@kwai/ui'; import { useI18n } from 'vue-i18n'; -import PrimaryButton from '@root/components/PrimaryButton.vue'; import TrainingDefinitionCard from '@root/pages/training_definitions/components/TrainingDefinitionCard.vue'; import AddCalendarIcon from '@root/components/icons/AddCalendarIcon.vue'; @@ -33,13 +34,10 @@ const { data: trainingDefinitions } = useTrainingDefinitions();

@@ -50,9 +48,8 @@ const { data: trainingDefinitions } = useTrainingDefinitions(); diff --git a/frontend/apps/coach/src/pages/training_definitions/components/TrainingDefinitionForm.vue b/frontend/apps/coach/src/pages/training_definitions/components/TrainingDefinitionForm.vue index b3346be2..906cccf8 100644 --- a/frontend/apps/coach/src/pages/training_definitions/components/TrainingDefinitionForm.vue +++ b/frontend/apps/coach/src/pages/training_definitions/components/TrainingDefinitionForm.vue @@ -5,7 +5,7 @@ import { useI18n } from 'vue-i18n'; import { useForm } from 'vee-validate'; import { - Button, + KwaiButton, CheckBox, ErrorAlert, FormSection, @@ -278,13 +278,12 @@ watch(definition, nv => {
- +
{{ t('training_definition.form.error') }} diff --git a/frontend/apps/coach/src/pages/trainings/TrainingsPage.vue b/frontend/apps/coach/src/pages/trainings/TrainingsPage.vue index 9e0dd4f3..6de01927 100644 --- a/frontend/apps/coach/src/pages/trainings/TrainingsPage.vue +++ b/frontend/apps/coach/src/pages/trainings/TrainingsPage.vue @@ -12,9 +12,9 @@ import { CancelIcon, CheckIcon, EditIcon, + KwaiButton, TextBadge, } from '@kwai/ui'; -import PrimaryButton from '@root/components/PrimaryButton.vue'; import { createDate, createFromDate, now } from '@kwai/date'; import { computed, ref, watch } from 'vue'; import { useRoute, useRouter } from 'vue-router'; @@ -103,16 +103,13 @@ const setToCurrent = () => { :format="format" auto-apply /> - + - - + + {{ t('trainings.banner.button') }} - +
@@ -188,12 +185,9 @@ const setToCurrent = () => { /> - + - + diff --git a/frontend/apps/coach/src/pages/trainings/components/TrainingForm.vue b/frontend/apps/coach/src/pages/trainings/components/TrainingForm.vue index f398bf66..e9bf32bb 100644 --- a/frontend/apps/coach/src/pages/trainings/components/TrainingForm.vue +++ b/frontend/apps/coach/src/pages/trainings/components/TrainingForm.vue @@ -1,12 +1,12 @@ - - - - diff --git a/frontend/apps/portal/src/pages/TrainingsPage.vue b/frontend/apps/portal/src/pages/TrainingsPage.vue index 04b5f823..ba791280 100644 --- a/frontend/apps/portal/src/pages/TrainingsPage.vue +++ b/frontend/apps/portal/src/pages/TrainingsPage.vue @@ -7,12 +7,12 @@ import { useRoute, useRouter } from 'vue-router'; import { useApplications } from '@root/composables/useApplication'; import { usePages } from '@root/composables/usePage'; import { createDate, now } from '@kwai/date'; +import { KwaiButton } from '@kwai/ui'; import { useTrainingDays, useTrainings } from '@root/composables/useTraining'; import TrainingTimeline from '@root/pages/trainings/components/TrainingTimeline.vue'; import SectionTitle from '@root/components/SectionTitle.vue'; import LeftArrowIcon from '@root/components/icons/LeftArrowIcon.vue'; import RightArrowIcon from '@root/components/icons/RightArrowIcon.vue'; -import PrimaryButton from '@root/components/PrimaryButton.vue'; import FullArticle from '@root/components/FullArticle.vue'; import CoachList from '@root/pages/trainings/components/CoachList.vue'; @@ -176,24 +176,15 @@ const showNextMonth = () => { Trainingsrooster
- + Vorige Maand - - + + Deze Maand - - + + Volgende Maand - +

{{ start.format("MMMM") }} {{ start.format("YYYY") }} From d3a7023c6f6b68809220c67959f21c3ee192820f Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 11 Sep 2024 21:09:14 +0200 Subject: [PATCH 210/410] fix: add missing import KwaiButton --- frontend/apps/coach/src/pages/home/HomePage.vue | 2 +- .../coach/src/pages/home/components/TrainingDefinitionsCard.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/apps/coach/src/pages/home/HomePage.vue b/frontend/apps/coach/src/pages/home/HomePage.vue index 1b7d46dc..e74c318d 100644 --- a/frontend/apps/coach/src/pages/home/HomePage.vue +++ b/frontend/apps/coach/src/pages/home/HomePage.vue @@ -1,5 +1,5 @@ From 94a42ad1723ffe6596e04337cd166ae89ebfe6b6 Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 11 Sep 2024 21:57:26 +0200 Subject: [PATCH 211/410] refactor: use KwaiButton for Login --- .../apps/portal/src/components/toolbar/ToolbarUser.vue | 8 +++----- frontend/apps/portal/src/index.ts | 3 ++- frontend/apps/portal/tailwind.config.js | 8 +++++++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/frontend/apps/portal/src/components/toolbar/ToolbarUser.vue b/frontend/apps/portal/src/components/toolbar/ToolbarUser.vue index 193d17d1..d0cb0817 100644 --- a/frontend/apps/portal/src/components/toolbar/ToolbarUser.vue +++ b/frontend/apps/portal/src/components/toolbar/ToolbarUser.vue @@ -1,16 +1,14 @@ diff --git a/frontend/apps/portal/src/index.ts b/frontend/apps/portal/src/index.ts index a4367108..dcab3fd7 100644 --- a/frontend/apps/portal/src/index.ts +++ b/frontend/apps/portal/src/index.ts @@ -2,7 +2,7 @@ import { createApp } from 'vue'; import App from './App.vue'; import './index.css'; - +import { init } from '@kwai/ui'; import { createRouter, createWebHistory } from 'vue-router'; import routes from './routes'; import { VueQueryPlugin } from '@tanstack/vue-query'; @@ -26,5 +26,6 @@ router.beforeEach((to, from, next) => { }); routes.forEach(route => router.addRoute(route)); app.use(router); +init(app); app.mount('#app'); diff --git a/frontend/apps/portal/tailwind.config.js b/frontend/apps/portal/tailwind.config.js index f2a53ce4..f5b829d3 100644 --- a/frontend/apps/portal/tailwind.config.js +++ b/frontend/apps/portal/tailwind.config.js @@ -1,4 +1,5 @@ /** @type {import('tailwindcss').Config} */ +import colors from 'tailwindcss/colors'; module.exports = { content: [ './index.html', @@ -6,7 +7,12 @@ module.exports = { '../../packages/kwai-ui/src/**/*.{html,js,ts,vue,jsx,tsx}', ], theme: { - extend: {}, + extend: { + colors: { + primary: colors.red, + 'primary-text': colors.white, + }, + }, }, plugins: [], }; From 4be067dab2980c2f161d400acaca9e966ff9a74e Mon Sep 17 00:00:00 2001 From: zumuta Date: Wed, 11 Sep 2024 22:06:28 +0200 Subject: [PATCH 212/410] refactor: remove Button --- frontend/packages/kwai-ui/src/form/Button.vue | 41 ------------------- frontend/packages/kwai-ui/src/form/index.ts | 1 - 2 files changed, 42 deletions(-) delete mode 100644 frontend/packages/kwai-ui/src/form/Button.vue diff --git a/frontend/packages/kwai-ui/src/form/Button.vue b/frontend/packages/kwai-ui/src/form/Button.vue deleted file mode 100644 index 41450a01..00000000 --- a/frontend/packages/kwai-ui/src/form/Button.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - diff --git a/frontend/packages/kwai-ui/src/form/index.ts b/frontend/packages/kwai-ui/src/form/index.ts index a0cfb2b2..bb34a310 100644 --- a/frontend/packages/kwai-ui/src/form/index.ts +++ b/frontend/packages/kwai-ui/src/form/index.ts @@ -2,7 +2,6 @@ export { default as FormSectionHeader } from './FormSectionHeader.vue'; export { default as FormSectionFields } from './FormSectionFields.vue'; export { default as FormSection } from './FormSection.vue'; export { default as ButtonGroup } from './ButtonGroup.vue'; -export { default as Button } from './Button.vue'; export { default as RangeSlider } from './RangeSlider.vue'; export type { Option } from './SelectOption.vue'; export { default as SelectOption } from './SelectOption.vue'; From ecd5308968e3c4bf6091ebe86839ed5da639fa66 Mon Sep 17 00:00:00 2001 From: zumuta Date: Thu, 12 Sep 2024 20:33:42 +0200 Subject: [PATCH 213/410] feat: add hover color for primary --- frontend/packages/kwai-ui/src/form/KwaiButton.vue | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/packages/kwai-ui/src/form/KwaiButton.vue b/frontend/packages/kwai-ui/src/form/KwaiButton.vue index 924a9bea..9a015d3d 100644 --- a/frontend/packages/kwai-ui/src/form/KwaiButton.vue +++ b/frontend/packages/kwai-ui/src/form/KwaiButton.vue @@ -39,6 +39,7 @@ const size = computed(() => props.small ? 'small' : undefined); root: { class: { 'bg-primary-500': primary, + 'hover:bg-primary-600': primary, 'text-primary-text': primary, } } @@ -59,6 +60,7 @@ const size = computed(() => props.small ? 'small' : undefined); root: { class: { 'bg-primary-500': primary, + 'hover:bg-primary-600': primary, 'text-primary-text': primary, } } From 6b219a4494dfcf594462cac619beaa2d0ddebf57 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 13 Sep 2024 21:51:28 +0200 Subject: [PATCH 214/410] ci: replace turbo with taskfile --- .gitignore | 2 +- Taskfile.yml | 4 + frontend/Taskfile.yml | 96 ++++++++++++++ frontend/package-lock.json | 254 +++++++++++++++++++++---------------- frontend/package.json | 23 ++-- frontend/turbo.json | 14 -- 6 files changed, 258 insertions(+), 135 deletions(-) create mode 100644 Taskfile.yml create mode 100644 frontend/Taskfile.yml delete mode 100644 frontend/turbo.json diff --git a/.gitignore b/.gitignore index f583e858..ebd47905 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,6 @@ /_site/ /backend/src/.venv/ /backend/src/.coverage -.turbo dist node_modules public @@ -26,3 +25,4 @@ __pycache__ stats.html /backend/.venv/ /frontend/packages/kwai-config/src/config.production.toml +.task diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 00000000..5b4ab5fb --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,4 @@ +version: '3' + +includes: + frontend: ./frontend diff --git a/frontend/Taskfile.yml b/frontend/Taskfile.yml new file mode 100644 index 00000000..08d8e4e4 --- /dev/null +++ b/frontend/Taskfile.yml @@ -0,0 +1,96 @@ +version: '3' + +tasks: + # Internal task to run npm build for a package. + _npm_build_package: + internal: true + label: build_package_{{.PACKAGE}} + requires: + vars: [PACKAGE] + sources: + - packages/{{.PACKAGE}}/src/* + generates: + - packages/{{.PACKAGE}}/dist/* + cmds: + - npm run build -w packages/{{.PACKAGE}} + + # @kwai/config package is a dependency for all other packages. + _npm_build_config_package: + internal: true + run: once + cmds: + - task: _npm_build_package + vars: { PACKAGE: 'kwai-config' } + + # Build a package. + build_package: + desc: Build a package + requires: + vars: [PACKAGE] + deps: [_npm_build_config_package] + cmds: + - task: _npm_build_package + vars: { PACKAGE: '{{.PACKAGE}}' } + + # Build all packages. + build_packages: + desc: Build all packages + run: once # When used as a dependency, one run is enough. + deps: + - task: build_package + vars: { PACKAGE: 'kwai-types' } + - task: build_package + vars: { PACKAGE: 'kwai-date' } + - task: build_package + vars: { PACKAGE: 'kwai-api' } + - task: build_package + vars: { PACKAGE: 'kwai-ui' } + + # Build and start a development server for an application. + # All packages will be built before starting the application. + dev_app: + desc: Build and start a development server for this application + requires: + vars: [APP] + deps: [build_packages] + cmds: + - npm run dev -w apps/{{.APP}} + + # Build and start a development server for all applications. + dev_apps: + desc: Build and start a development server for all applications + deps: + - task: dev_app + vars: { APP: 'auth' } + - task: dev_app + vars: { APP: 'author' } + - task: dev_app + vars: { APP: 'club' } + - task: dev_app + vars: { APP: 'coach' } + - task: dev_app + vars: { APP: 'portal' } + + # Build an application. + build_app: + desc: Build an application + requires: + vars: [APP] + deps: [build_packages] + cmds: + - npm run build -w apps/{{.APP}} + + # Build all applications. + build: + desc: Build all applications of the frontend + deps: + - task: build_app + vars: { APP: 'auth' } + - task: build_app + vars: { APP: 'author' } + - task: build_app + vars: { APP: 'club' } + - task: build_app + vars: { APP: 'coach' } + - task: build_app + vars: { APP: 'portal' } diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 2cc3fe43..7f17532a 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -11,18 +11,16 @@ "apps/*", "packages/*" ], - "dependencies": { - "vitest": "^2.0.5" - }, "devDependencies": { + "@go-task/cli": "^3.39.0", "@vue/test-utils": "^2.4.3", "eslint-config-kwai": "*", "msw": "^2.0.11", "rollup-plugin-visualizer": "^5.11.0", "syncpack": "^12.3.2", - "turbo": "^1.13.2", "typescript": "^5.2.2", - "vite": "^4.5.3" + "vite": "^4.5.3", + "vitest": "^2.0.5" }, "engines": { "node": ">=18.0.0" @@ -392,6 +390,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -545,6 +544,7 @@ "cpu": [ "ppc64" ], + "dev": true, "optional": true, "os": [ "aix" @@ -1000,6 +1000,25 @@ "node": ">= 8.0.0" } }, + "node_modules/@go-task/cli": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/@go-task/cli/-/cli-3.39.0.tgz", + "integrity": "sha512-KhJ3Ao0ZR9JmmA5ad8ovFwr2mJmSLVqd0Y7hJBI130MZ9JXPmxavkoDc10d4oul/TCKG6nGwypru/OmFqkHTTw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@go-task/go-npm": "^0.2.0" + } + }, + "node_modules/@go-task/go-npm": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@go-task/go-npm/-/go-npm-0.2.0.tgz", + "integrity": "sha512-vQbdtBvesHm8EUFHX8QKg4rbBodmu9VsAXH1ozpbiN5jdTMOYHTCMM31EurAYmY+rNNtxJQ4JGy6t383RPlqbw==", + "dev": true, + "bin": { + "go-npm": "bin/index.js" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -1335,6 +1354,7 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -1348,6 +1368,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -1356,6 +1377,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -1369,6 +1391,7 @@ "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -1732,6 +1755,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "android" @@ -1744,6 +1768,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "android" @@ -1756,6 +1781,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -1768,6 +1794,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -1780,6 +1807,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1792,6 +1820,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1804,6 +1833,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1816,6 +1846,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1828,6 +1859,7 @@ "cpu": [ "ppc64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1840,6 +1872,7 @@ "cpu": [ "riscv64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1852,6 +1885,7 @@ "cpu": [ "s390x" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1864,6 +1898,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1876,6 +1911,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -1888,6 +1924,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -1900,6 +1937,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "win32" @@ -1912,6 +1950,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -2189,7 +2228,7 @@ "version": "20.12.7", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", - "devOptional": true, + "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -2461,6 +2500,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz", "integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==", + "dev": true, "dependencies": { "@vitest/spy": "2.0.5", "@vitest/utils": "2.0.5", @@ -2475,6 +2515,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz", "integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==", + "dev": true, "dependencies": { "tinyrainbow": "^1.2.0" }, @@ -2486,6 +2527,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.5.tgz", "integrity": "sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==", + "dev": true, "dependencies": { "@vitest/utils": "2.0.5", "pathe": "^1.1.2" @@ -2498,6 +2540,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.5.tgz", "integrity": "sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==", + "dev": true, "dependencies": { "@vitest/pretty-format": "2.0.5", "magic-string": "^0.30.10", @@ -2511,6 +2554,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz", "integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==", + "dev": true, "dependencies": { "tinyspy": "^3.0.0" }, @@ -2522,6 +2566,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz", "integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==", + "dev": true, "dependencies": { "@vitest/pretty-format": "2.0.5", "estree-walker": "^3.0.3", @@ -2536,6 +2581,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0" } @@ -3162,6 +3208,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, "engines": { "node": ">=12" } @@ -3314,6 +3361,7 @@ "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, "engines": { "node": ">=8" } @@ -3378,6 +3426,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", + "dev": true, "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", @@ -3435,6 +3484,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, "engines": { "node": ">= 16" } @@ -3776,6 +3826,7 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, "engines": { "node": ">=6" } @@ -4736,6 +4787,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", @@ -4758,6 +4810,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, "engines": { "node": ">=12" }, @@ -4769,6 +4822,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, "dependencies": { "mimic-fn": "^4.0.0" }, @@ -5029,6 +5083,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, "engines": { "node": "*" } @@ -5056,6 +5111,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, "engines": { "node": ">=16" }, @@ -5327,6 +5383,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, "engines": { "node": ">=16.17.0" } @@ -5673,6 +5730,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -6052,6 +6110,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "dev": true, "dependencies": { "get-func-name": "^2.0.1" } @@ -6076,7 +6135,8 @@ "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true }, "node_modules/merge2": { "version": "1.4.1", @@ -6313,6 +6373,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, "dependencies": { "path-key": "^4.0.0" }, @@ -6327,6 +6388,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, "engines": { "node": ">=12" }, @@ -6703,6 +6765,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, "engines": { "node": ">= 14.16" } @@ -7486,12 +7549,14 @@ "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==" + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, "engines": { "node": ">=14" }, @@ -7543,7 +7608,8 @@ "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==" + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true }, "node_modules/statuses": { "version": "2.0.1", @@ -7557,7 +7623,8 @@ "node_modules/std-env": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==" + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true }, "node_modules/stdin-discarder": { "version": "0.2.2", @@ -7744,6 +7811,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, "engines": { "node": ">=12" }, @@ -7955,6 +8023,15 @@ "node": ">=14.0.0" } }, + "node_modules/tailwindcss-primeui": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/tailwindcss-primeui/-/tailwindcss-primeui-0.3.4.tgz", + "integrity": "sha512-5+Qfoe5Kpq2Iwrd6umBUb3rQH6b7+pL4jxJUId0Su5agUM6TwCyH5Pyl9R0y3QQB3IRuTxBNmeS11B41f+30zw==", + "dev": true, + "peerDependencies": { + "tailwindcss": ">=3.1.0" + } + }, "node_modules/tailwindcss/node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -8005,12 +8082,14 @@ "node_modules/tinybench": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", - "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==" + "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", + "dev": true }, "node_modules/tinypool": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz", "integrity": "sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==", + "dev": true, "engines": { "node": "^18.0.0 || >=20.0.0" } @@ -8019,6 +8098,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, "engines": { "node": ">=14.0.0" } @@ -8027,6 +8107,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz", "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==", + "dev": true, "engines": { "node": ">=14.0.0" } @@ -8103,101 +8184,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, - "node_modules/turbo": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/turbo/-/turbo-1.13.2.tgz", - "integrity": "sha512-rX/d9f4MgRT3yK6cERPAkfavIxbpBZowDQpgvkYwGMGDQ0Nvw1nc0NVjruE76GrzXQqoxR1UpnmEP54vBARFHQ==", - "dev": true, - "bin": { - "turbo": "bin/turbo" - }, - "optionalDependencies": { - "turbo-darwin-64": "1.13.2", - "turbo-darwin-arm64": "1.13.2", - "turbo-linux-64": "1.13.2", - "turbo-linux-arm64": "1.13.2", - "turbo-windows-64": "1.13.2", - "turbo-windows-arm64": "1.13.2" - } - }, - "node_modules/turbo-darwin-64": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-1.13.2.tgz", - "integrity": "sha512-CCSuD8CfmtncpohCuIgq7eAzUas0IwSbHfI8/Q3vKObTdXyN8vAo01gwqXjDGpzG9bTEVedD0GmLbD23dR0MLA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/turbo-darwin-arm64": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-1.13.2.tgz", - "integrity": "sha512-0HySm06/D2N91rJJ89FbiI/AodmY8B3WDSFTVEpu2+8spUw7hOJ8okWOT0e5iGlyayUP9gr31eOeL3VFZkpfCw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/turbo-linux-64": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-1.13.2.tgz", - "integrity": "sha512-7HnibgbqZrjn4lcfIouzlPu8ZHSBtURG4c7Bedu7WJUDeZo+RE1crlrQm8wuwO54S0siYqUqo7GNHxu4IXbioQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/turbo-linux-arm64": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-1.13.2.tgz", - "integrity": "sha512-sUq4dbpk6SNKg/Hkwn256Vj2AEYSQdG96repio894h5/LEfauIK2QYiC/xxAeW3WBMc6BngmvNyURIg7ltrePg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/turbo-windows-64": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-1.13.2.tgz", - "integrity": "sha512-DqzhcrciWq3dpzllJR2VVIyOhSlXYCo4mNEWl98DJ3FZ08PEzcI3ceudlH6F0t/nIcfSItK1bDP39cs7YoZHEA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/turbo-windows-arm64": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-1.13.2.tgz", - "integrity": "sha512-WnPMrwfCXxK69CdDfS1/j2DlzcKxSmycgDAqV0XCYpK/812KB0KlvsVAt5PjEbZGXkY88pCJ1BLZHAjF5FcbqA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -8338,7 +8324,7 @@ "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "devOptional": true + "dev": true }, "node_modules/unicorn-magic": { "version": "0.1.0", @@ -8510,6 +8496,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.5.tgz", "integrity": "sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==", + "dev": true, "dependencies": { "cac": "^6.7.14", "debug": "^4.3.5", @@ -8534,6 +8521,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "android" @@ -8549,6 +8537,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "android" @@ -8564,6 +8553,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "android" @@ -8579,6 +8569,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -8594,6 +8585,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -8609,6 +8601,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -8624,6 +8617,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -8639,6 +8633,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" @@ -8654,6 +8649,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -8669,6 +8665,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "linux" @@ -8684,6 +8681,7 @@ "cpu": [ "loong64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -8699,6 +8697,7 @@ "cpu": [ "mips64el" ], + "dev": true, "optional": true, "os": [ "linux" @@ -8714,6 +8713,7 @@ "cpu": [ "ppc64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -8729,6 +8729,7 @@ "cpu": [ "riscv64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -8744,6 +8745,7 @@ "cpu": [ "s390x" ], + "dev": true, "optional": true, "os": [ "linux" @@ -8759,6 +8761,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -8774,6 +8777,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "netbsd" @@ -8789,6 +8793,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "openbsd" @@ -8804,6 +8809,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "sunos" @@ -8819,6 +8825,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -8834,6 +8841,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "win32" @@ -8849,6 +8857,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -8861,6 +8870,7 @@ "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -8898,6 +8908,7 @@ "version": "4.21.2", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz", "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==", + "dev": true, "dependencies": { "@types/estree": "1.0.5" }, @@ -8932,6 +8943,7 @@ "version": "5.4.3", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.3.tgz", "integrity": "sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==", + "dev": true, "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -9017,6 +9029,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.5.tgz", "integrity": "sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==", + "dev": true, "dependencies": { "@ampproject/remapping": "^2.3.0", "@vitest/expect": "2.0.5", @@ -9083,6 +9096,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "android" @@ -9098,6 +9112,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "android" @@ -9113,6 +9128,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "android" @@ -9128,6 +9144,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -9143,6 +9160,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -9158,6 +9176,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -9173,6 +9192,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -9188,6 +9208,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" @@ -9203,6 +9224,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -9218,6 +9240,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "linux" @@ -9233,6 +9256,7 @@ "cpu": [ "loong64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -9248,6 +9272,7 @@ "cpu": [ "mips64el" ], + "dev": true, "optional": true, "os": [ "linux" @@ -9263,6 +9288,7 @@ "cpu": [ "ppc64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -9278,6 +9304,7 @@ "cpu": [ "riscv64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -9293,6 +9320,7 @@ "cpu": [ "s390x" ], + "dev": true, "optional": true, "os": [ "linux" @@ -9308,6 +9336,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -9323,6 +9352,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "netbsd" @@ -9338,6 +9368,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "openbsd" @@ -9353,6 +9384,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "sunos" @@ -9368,6 +9400,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -9383,6 +9416,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "win32" @@ -9398,6 +9432,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -9410,6 +9445,7 @@ "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -9447,6 +9483,7 @@ "version": "4.21.2", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz", "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==", + "dev": true, "dependencies": { "@types/estree": "1.0.5" }, @@ -9481,6 +9518,7 @@ "version": "5.4.3", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.3.tgz", "integrity": "sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==", + "dev": true, "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -9710,6 +9748,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" @@ -10625,6 +10664,7 @@ "autoprefixer": "^10.4.16", "postcss": "^8.4.31", "tailwindcss": "^3.4.3", + "tailwindcss-primeui": "^0.3.4", "vite-plugin-dts": "^3.6.3", "vue": "3.4.25" }, diff --git a/frontend/package.json b/frontend/package.json index 98cd5b96..ddb4bf17 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,29 +1,26 @@ { "name": "kwai", "version": "1.0.0", - "devDependencies": { - "@vue/test-utils": "^2.4.3", - "eslint-config-kwai": "*", - "msw": "^2.0.11", - "rollup-plugin-visualizer": "^5.11.0", - "syncpack": "^12.3.2", - "turbo": "^1.13.2", - "typescript": "^5.2.2", - "vite": "^4.5.3" - }, "engines": { "node": ">=18.0.0" }, "private": true, "scripts": { - "build": "turbo run build --force", - "dev": "turbo run dev --parallel --continue" + "test": "vitest" }, "workspaces": [ "apps/*", "packages/*" ], - "dependencies": { + "devDependencies": { + "@go-task/cli": "^3.39.0", + "@vue/test-utils": "^2.4.3", + "eslint-config-kwai": "*", + "msw": "^2.0.11", + "rollup-plugin-visualizer": "^5.11.0", + "syncpack": "^12.3.2", + "typescript": "^5.2.2", + "vite": "^4.5.3", "vitest": "^2.0.5" } } diff --git a/frontend/turbo.json b/frontend/turbo.json deleted file mode 100644 index c1543e3b..00000000 --- a/frontend/turbo.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "pipeline": { - "build": { - "dependsOn": ["^build"], - "outputs": ["dist/**"] - }, - "lint": { - "outputs": [] - }, - "dev": { - "cache": false - } - } -} From 715b765ecc225dd4b125c279d7fe2c70b7bc4a38 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 13 Sep 2024 22:02:12 +0200 Subject: [PATCH 215/410] docs: add task --- frontend/docs/index.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/frontend/docs/index.md b/frontend/docs/index.md index d1d4ca39..2033bc16 100644 --- a/frontend/docs/index.md +++ b/frontend/docs/index.md @@ -15,23 +15,30 @@ Clone the repository to your system. [npm](https://www.npmjs.com/) is used as packaging and dependency management tool. Make sure it is available. -Use npm to install all dependencies: +Make `frontend` the current directory and use npm to install all dependencies: `npm install` +[Task](https://taskfile.dev/) is used as runner and build tool. + ### Configuration The frontend uses a config package. ## Development -A development version of the frontend can be started: +A development version of the frontend can be started. Make `frontend` the current directory +and run the `dev_apps` task. This task will build all the packages from the monorepo +and build and serve the applications. -`npm run dev` +`task dev_apps` [Vite](https://vitejs.dev/) is the local development server. -Each application will have a vite server. To serve all applications -from one url, Nginx can be used as reverse proxy. Use the following +Each application will have a vite server. + +The FastAPI backend can be used to serve all applications from one url. + +To serve all applications from one url, Nginx can be used as reverse proxy. Use the following configuration for Nginx: ```` @@ -67,6 +74,6 @@ server { To create a production version of the frontend: -`npm run build` +`task build_apps` This will create dist folders in each application. From 99a919af047abfebe14fde5d47baffb4589f810f Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 13 Sep 2024 22:09:54 +0200 Subject: [PATCH 216/410] ci: add tailwindcss-primeui --- frontend/packages/kwai-ui/package.json | 1 + frontend/packages/kwai-ui/tailwind.config.js | 25 ++++++++++---------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/frontend/packages/kwai-ui/package.json b/frontend/packages/kwai-ui/package.json index 460bed9e..a6a3509f 100644 --- a/frontend/packages/kwai-ui/package.json +++ b/frontend/packages/kwai-ui/package.json @@ -13,6 +13,7 @@ "autoprefixer": "^10.4.16", "postcss": "^8.4.31", "tailwindcss": "^3.4.3", + "tailwindcss-primeui": "^0.3.4", "vite-plugin-dts": "^3.6.3", "vue": "3.4.25" }, diff --git a/frontend/packages/kwai-ui/tailwind.config.js b/frontend/packages/kwai-ui/tailwind.config.js index 0186e8e8..74d89a35 100644 --- a/frontend/packages/kwai-ui/tailwind.config.js +++ b/frontend/packages/kwai-ui/tailwind.config.js @@ -1,15 +1,16 @@ /** @type {import('tailwindcss').Config} */ -import TailwindForms from "@tailwindcss/forms" +import TailwindForms from '@tailwindcss/forms'; +import primeui from 'tailwindcss-primeui'; export default { - content: [ - "./index.ts", - "./src/**/*.{html,js,ts,vue,jsx,tsx}" - ], - theme: { - extend: {}, - }, - plugins: [ - TailwindForms() - ], -} + content: [ + './index.ts', + './src/**/*.{html,js,ts,vue,jsx,tsx}', + ], + theme: { + extend: {}, + }, + plugins: [ + TailwindForms(), primeui, + ], +}; From 87eb220c90131af8f231d58e6ee76086ce245708 Mon Sep 17 00:00:00 2001 From: zumuta Date: Fri, 13 Sep 2024 22:18:09 +0200 Subject: [PATCH 217/410] ci: make it possible to run frontend tasks from the root folder --- Taskfile.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Taskfile.yml b/Taskfile.yml index 5b4ab5fb..cae5690b 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -1,4 +1,6 @@ version: '3' includes: - frontend: ./frontend + frontend: + taskfile: ./frontend/Taskfile.yml + dir: ./frontend From ef711dd2741994e95dd6d8d13935532840cd9a55 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 14 Sep 2024 15:49:41 +0200 Subject: [PATCH 218/410] fix: set primary bg and text color --- .../kwai-ui/src/presets/kwai/button/index.js | 472 +++++++++--------- 1 file changed, 236 insertions(+), 236 deletions(-) diff --git a/frontend/packages/kwai-ui/src/presets/kwai/button/index.js b/frontend/packages/kwai-ui/src/presets/kwai/button/index.js index cdc5241f..69087263 100644 --- a/frontend/packages/kwai-ui/src/presets/kwai/button/index.js +++ b/frontend/packages/kwai-ui/src/presets/kwai/button/index.js @@ -1,238 +1,238 @@ export default { - root: ({ props, context, parent }) => ({ - class: [ - 'relative', - - // Alignments - 'items-center inline-flex text-center align-bottom justify-center', - { 'flex-col': (props.iconPos === 'top' || props.iconPos === 'bottom') && props.label }, - - // Sizes & Spacing - 'leading-[normal]', - { - 'px-4 py-[0.625rem]': props.size === null, - 'text-sm py-2 px-3': props.size === 'small', - 'text-xl py-3 px-4': props.size === 'large' - }, - { 'gap-2': props.label !== null }, - { - 'w-12 px-0 py-3': props.label == null && props.icon !== null - }, - - // Shapes - { 'shadow-lg': props.raised }, - { 'rounded-md': !props.rounded, 'rounded-full': props.rounded }, - { 'rounded-none first:rounded-l-md last:rounded-r-md': parent.instance.$name == 'InputGroup' }, - - // Link Button - { 'text-primary-600 bg-transparent border-transparent': props.link }, - - // Plain Button - { 'text-white bg-gray-500 border border-gray-500': props.plain && !props.outlined && !props.text }, - // Plain Text Button - { 'text-surface-500': props.plain && props.text }, - // Plain Outlined Button - { 'text-surface-500 border border-gray-500': props.plain && props.outlined }, - - // Text Button - { 'bg-transparent border-transparent': props.text && !props.plain }, - - // Outlined Button - { 'bg-transparent border': props.outlined && !props.plain }, - - // --- Severity Buttons --- - - // Primary Button - { - 'text-primary-contrast': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain, - 'bg-primary': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain, - 'border border-primary': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain - }, - // Primary Text Button - { 'text-primary': props.text && props.severity === null && !props.plain }, - // Primary Outlined Button - { 'text-primary border border-primary': props.outlined && props.severity === null && !props.plain }, - - // Secondary Button - { - 'text-white dark:text-surface-900': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain, - 'bg-surface-500 dark:bg-surface-400': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain, - 'border border-surface-500 dark:border-surface-400': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain - }, - // Secondary Text Button - { 'text-surface-500 dark:text-surface-300': props.text && props.severity === 'secondary' && !props.plain }, - // Secondary Outlined Button - { 'text-surface-500 dark:text-surface-300 border border-surface-500 hover:bg-surface-300/20': props.outlined && props.severity === 'secondary' && !props.plain }, - - // Success Button - { - 'text-white dark:text-green-900': props.severity === 'success' && !props.text && !props.outlined && !props.plain, - 'bg-green-500 dark:bg-green-400': props.severity === 'success' && !props.text && !props.outlined && !props.plain, - 'border border-green-500 dark:border-green-400': props.severity === 'success' && !props.text && !props.outlined && !props.plain - }, - // Success Text Button - { 'text-green-500 dark:text-green-400': props.text && props.severity === 'success' && !props.plain }, - // Success Outlined Button - { 'text-green-500 border border-green-500 hover:bg-green-300/20': props.outlined && props.severity === 'success' && !props.plain }, - - // Info Button - { - 'text-white dark:text-surface-900': props.severity === 'info' && !props.text && !props.outlined && !props.plain, - 'bg-blue-500 dark:bg-blue-400': props.severity === 'info' && !props.text && !props.outlined && !props.plain, - 'border border-blue-500 dark:border-blue-400': props.severity === 'info' && !props.text && !props.outlined && !props.plain - }, - // Info Text Button - { 'text-blue-500 dark:text-blue-400': props.text && props.severity === 'info' && !props.plain }, - // Info Outlined Button - { 'text-blue-500 border border-blue-500 hover:bg-blue-300/20 ': props.outlined && props.severity === 'info' && !props.plain }, - - // Warning Button - { - 'text-white dark:text-surface-900': props.severity === 'warn' && !props.text && !props.outlined && !props.plain, - 'bg-orange-500 dark:bg-orange-400': props.severity === 'warn' && !props.text && !props.outlined && !props.plain, - 'border border-orange-500 dark:border-orange-400': props.severity === 'warn' && !props.text && !props.outlined && !props.plain - }, - // Warning Text Button - { 'text-orange-500 dark:text-orange-400': props.text && props.severity === 'warn' && !props.plain }, - // Warning Outlined Button - { 'text-orange-500 border border-orange-500 hover:bg-orange-300/20': props.outlined && props.severity === 'warn' && !props.plain }, - - // Help Button - { - 'text-white dark:text-surface-900': props.severity === 'help' && !props.text && !props.outlined && !props.plain, - 'bg-purple-500 dark:bg-purple-400': props.severity === 'help' && !props.text && !props.outlined && !props.plain, - 'border border-purple-500 dark:border-purple-400': props.severity === 'help' && !props.text && !props.outlined && !props.plain - }, - // Help Text Button - { 'text-purple-500 dark:text-purple-400': props.text && props.severity === 'help' && !props.plain }, - // Help Outlined Button - { 'text-purple-500 border border-purple-500 hover:bg-purple-300/20': props.outlined && props.severity === 'help' && !props.plain }, - - // Danger Button - { - 'text-white dark:text-surface-900': props.severity === 'danger' && !props.text && !props.outlined && !props.plain, - 'bg-red-500 dark:bg-red-400': props.severity === 'danger' && !props.text && !props.outlined && !props.plain, - 'border border-red-500 dark:border-red-400': props.severity === 'danger' && !props.text && !props.outlined && !props.plain - }, - // Danger Text Button - { 'text-red-500 dark:text-red-400': props.text && props.severity === 'danger' && !props.plain }, - // Danger Outlined Button - { 'text-red-500 border border-red-500 hover:bg-red-300/20': props.outlined && props.severity === 'danger' && !props.plain }, - // Contrast Button - { - 'text-white dark:text-surface-900': props.severity === 'contrast' && !props.text && !props.outlined && !props.plain, - 'bg-surface-900 dark:bg-surface-0': props.severity === 'contrast' && !props.text && !props.outlined && !props.plain, - 'border border-surface-900 dark:border-surface-0': props.severity === 'contrast' && !props.text && !props.outlined && !props.plain - }, - // Contrast Text Button - { 'text-surface-900 dark:text-surface-0': props.text && props.severity === 'contrast' && !props.plain }, - // Contrast Outlined Button - { 'text-surface-900 dark:text-surface-0 border border-surface-900 dark:border-surface-0': props.outlined && props.severity === 'contrast' && !props.plain }, - - // --- Severity Button States --- - 'focus:outline-none focus:outline-offset-0 focus:ring', - - // Link - { 'focus:ring-primary': props.link }, - - // Plain - { 'hover:bg-gray-600 hover:border-gray-600': props.plain && !props.outlined && !props.text }, - // Text & Outlined Button - { 'hover:bg-surface-300/20': props.plain && (props.text || props.outlined) }, - - // Primary - { 'hover:bg-primary-emphasis hover:border-primary-emphasis': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-primary': props.severity === null }, - // Text & Outlined Button - { 'hover:bg-primary-300/20': (props.text || props.outlined) && props.severity === null && !props.plain }, - - // Secondary - { 'hover:bg-surface-600 dark:hover:bg-surface-300 hover:border-surface-600 dark:hover:border-surface-300': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-surface-400/50 dark:focus:ring-surface-300/50': props.severity === 'secondary' }, - // Text & Outlined Button - { 'hover:bg-surface-300/20': (props.text || props.outlined) && props.severity === 'secondary' && !props.plain }, - - // Success - { 'hover:bg-green-600 dark:hover:bg-green-300 hover:border-green-600 dark:hover:border-green-300': props.severity === 'success' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-green-400/50 dark:focus:ring-green-300/50': props.severity === 'success' }, - // Text & Outlined Button - { 'hover:bg-green-300/20': (props.text || props.outlined) && props.severity === 'success' && !props.plain }, - - // Info - { 'hover:bg-blue-600 dark:hover:bg-blue-300 hover:border-blue-600 dark:hover:border-blue-300': props.severity === 'info' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-blue-400/50 dark:focus:ring-blue-300/50': props.severity === 'info' }, - // Text & Outlined Button - { 'hover:bg-blue-300/20': (props.text || props.outlined) && props.severity === 'info' && !props.plain }, - - // Warning - { 'hover:bg-orange-600 dark:hover:bg-orange-300 hover:border-orange-600 dark:hover:border-orange-300': props.severity === 'warn' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-orange-400/50 dark:focus:ring-orange-300/50': props.severity === 'warn' }, - // Text & Outlined Button - { 'hover:bg-orange-300/20': (props.text || props.outlined) && props.severity === 'warn' && !props.plain }, - - // Help - { 'hover:bg-purple-600 dark:hover:bg-purple-300 hover:border-purple-600 dark:hover:border-purple-300': props.severity === 'help' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-purple-400/50 dark:focus:ring-purple-300/50': props.severity === 'help' }, - // Text & Outlined Button - { 'hover:bg-purple-300/20': (props.text || props.outlined) && props.severity === 'help' && !props.plain }, - - // Danger - { 'hover:bg-red-600 dark:hover:bg-red-300 hover:border-red-600 dark:hover:border-red-300': props.severity === 'danger' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-red-400/50 dark:focus:ring-red-300/50': props.severity === 'danger' }, - // Text & Outlined Button - { 'hover:bg-red-300/20': (props.text || props.outlined) && props.severity === 'danger' && !props.plain }, - // Contrast - { 'hover:bg-surface-800 dark:hover:bg-surface-100 hover:border-surface-800 dark:hover:border-surface-100': props.severity === 'contrast' && !props.text && !props.outlined && !props.plain }, - { 'focus:ring-surface-500 dark:focus:ring-surface-400': props.severity === 'contrast' }, - // Text & Outlined Button - { 'hover:bg-surface-900/10 dark:hover:bg-[rgba(255,255,255,0.03)]': (props.text || props.outlined) && props.severity === 'contrast' && !props.plain }, - // Disabled - { 'opacity-60 pointer-events-none cursor-default': context.disabled }, - - // Transitions - 'transition duration-200 ease-in-out', - - // Misc - 'cursor-pointer overflow-hidden select-none', - - // Badge - '[&>[data-pc-name=badge]]:min-w-4 [&>[data-pc-name=badge]]:h-4 [&>[data-pc-name=badge]]:leading-4' - ] - }), - label: ({ props }) => ({ - class: [ - 'duration-200', - 'font-bold', - { - 'hover:underline': props.link - }, - { 'flex-1': props.label !== null, 'invisible w-0': props.label == null } - ] - }), - icon: ({ props }) => ({ - class: [ - 'mx-0', - { - 'mr-2': props.iconPos == 'left' && props.label != null, - 'ml-2 order-1': props.iconPos == 'right' && props.label != null, - 'order-2': props.iconPos == 'bottom' && props.label != null - } - ] - }), - loadingIcon: ({ props }) => ({ - class: [ - 'h-4 w-4', - 'mx-0', - { - 'mr-2': props.iconPos == 'left' && props.label != null, - 'ml-2 order-1': props.iconPos == 'right' && props.label != null, - 'mb-2': props.iconPos == 'top' && props.label != null, - 'mt-2': props.iconPos == 'bottom' && props.label != null - }, - 'animate-spin' - ] - }), - badge: ({ props }) => ({ - class: [{ 'ml-2 w-4 h-4 leading-none flex items-center justify-center': props.badge }] - }) + root: ({ props, context, parent }) => ({ + class: [ + 'relative', + + // Alignments + 'items-center inline-flex text-center align-bottom justify-center', + { 'flex-col': (props.iconPos === 'top' || props.iconPos === 'bottom') && props.label }, + + // Sizes & Spacing + 'leading-[normal]', + { + 'px-4 py-[0.625rem]': props.size === null, + 'text-sm py-2 px-3': props.size === 'small', + 'text-xl py-3 px-4': props.size === 'large', + }, + { 'gap-2': props.label !== null }, + { + 'w-12 px-0 py-3': props.label == null && props.icon !== null, + }, + + // Shapes + { 'shadow-lg': props.raised }, + { 'rounded-md': !props.rounded, 'rounded-full': props.rounded }, + { 'rounded-none first:rounded-l-md last:rounded-r-md': parent.instance.$name == 'InputGroup' }, + + // Link Button + { 'text-primary-600 bg-transparent border-transparent': props.link }, + + // Plain Button + { 'text-white bg-gray-500 border border-gray-500': props.plain && !props.outlined && !props.text }, + // Plain Text Button + { 'text-surface-500': props.plain && props.text }, + // Plain Outlined Button + { 'text-surface-500 border border-gray-500': props.plain && props.outlined }, + + // Text Button + { 'bg-transparent border-transparent': props.text && !props.plain }, + + // Outlined Button + { 'bg-transparent border': props.outlined && !props.plain }, + + // --- Severity Buttons --- + + // Primary Button + { + 'text-primary-contrast text-primary-text': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain, + 'bg-primary-500 hover:bg-primary-600': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain, + 'border border-primary': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain, + }, + // Primary Text Button + { 'text-primary-text': props.text && props.severity === null && !props.plain }, + // Primary Outlined Button + { 'text-primary border border-primary': props.outlined && props.severity === null && !props.plain }, + + // Secondary Button + { + 'text-white dark:text-surface-900': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain, + 'bg-surface-500 dark:bg-surface-400': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain, + 'border border-surface-500 dark:border-surface-400': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain, + }, + // Secondary Text Button + { 'text-surface-500 dark:text-surface-300': props.text && props.severity === 'secondary' && !props.plain }, + // Secondary Outlined Button + { 'text-surface-500 dark:text-surface-300 border border-surface-500 hover:bg-surface-300/20': props.outlined && props.severity === 'secondary' && !props.plain }, + + // Success Button + { + 'text-white dark:text-green-900': props.severity === 'success' && !props.text && !props.outlined && !props.plain, + 'bg-green-500 dark:bg-green-400': props.severity === 'success' && !props.text && !props.outlined && !props.plain, + 'border border-green-500 dark:border-green-400': props.severity === 'success' && !props.text && !props.outlined && !props.plain, + }, + // Success Text Button + { 'text-green-500 dark:text-green-400': props.text && props.severity === 'success' && !props.plain }, + // Success Outlined Button + { 'text-green-500 border border-green-500 hover:bg-green-300/20': props.outlined && props.severity === 'success' && !props.plain }, + + // Info Button + { + 'text-white dark:text-surface-900': props.severity === 'info' && !props.text && !props.outlined && !props.plain, + 'bg-blue-500 dark:bg-blue-400': props.severity === 'info' && !props.text && !props.outlined && !props.plain, + 'border border-blue-500 dark:border-blue-400': props.severity === 'info' && !props.text && !props.outlined && !props.plain, + }, + // Info Text Button + { 'text-blue-500 dark:text-blue-400': props.text && props.severity === 'info' && !props.plain }, + // Info Outlined Button + { 'text-blue-500 border border-blue-500 hover:bg-blue-300/20 ': props.outlined && props.severity === 'info' && !props.plain }, + + // Warning Button + { + 'text-white dark:text-surface-900': props.severity === 'warn' && !props.text && !props.outlined && !props.plain, + 'bg-orange-500 dark:bg-orange-400': props.severity === 'warn' && !props.text && !props.outlined && !props.plain, + 'border border-orange-500 dark:border-orange-400': props.severity === 'warn' && !props.text && !props.outlined && !props.plain, + }, + // Warning Text Button + { 'text-orange-500 dark:text-orange-400': props.text && props.severity === 'warn' && !props.plain }, + // Warning Outlined Button + { 'text-orange-500 border border-orange-500 hover:bg-orange-300/20': props.outlined && props.severity === 'warn' && !props.plain }, + + // Help Button + { + 'text-white dark:text-surface-900': props.severity === 'help' && !props.text && !props.outlined && !props.plain, + 'bg-purple-500 dark:bg-purple-400': props.severity === 'help' && !props.text && !props.outlined && !props.plain, + 'border border-purple-500 dark:border-purple-400': props.severity === 'help' && !props.text && !props.outlined && !props.plain, + }, + // Help Text Button + { 'text-purple-500 dark:text-purple-400': props.text && props.severity === 'help' && !props.plain }, + // Help Outlined Button + { 'text-purple-500 border border-purple-500 hover:bg-purple-300/20': props.outlined && props.severity === 'help' && !props.plain }, + + // Danger Button + { + 'text-white dark:text-surface-900': props.severity === 'danger' && !props.text && !props.outlined && !props.plain, + 'bg-red-500 dark:bg-red-400': props.severity === 'danger' && !props.text && !props.outlined && !props.plain, + 'border border-red-500 dark:border-red-400': props.severity === 'danger' && !props.text && !props.outlined && !props.plain, + }, + // Danger Text Button + { 'text-red-500 dark:text-red-400': props.text && props.severity === 'danger' && !props.plain }, + // Danger Outlined Button + { 'text-red-500 border border-red-500 hover:bg-red-300/20': props.outlined && props.severity === 'danger' && !props.plain }, + // Contrast Button + { + 'text-white dark:text-surface-900': props.severity === 'contrast' && !props.text && !props.outlined && !props.plain, + 'bg-surface-900 dark:bg-surface-0': props.severity === 'contrast' && !props.text && !props.outlined && !props.plain, + 'border border-surface-900 dark:border-surface-0': props.severity === 'contrast' && !props.text && !props.outlined && !props.plain, + }, + // Contrast Text Button + { 'text-surface-900 dark:text-surface-0': props.text && props.severity === 'contrast' && !props.plain }, + // Contrast Outlined Button + { 'text-surface-900 dark:text-surface-0 border border-surface-900 dark:border-surface-0': props.outlined && props.severity === 'contrast' && !props.plain }, + + // --- Severity Button States --- + 'focus:outline-none focus:outline-offset-0 focus:ring', + + // Link + { 'focus:ring-primary': props.link }, + + // Plain + { 'hover:bg-gray-600 hover:border-gray-600': props.plain && !props.outlined && !props.text }, + // Text & Outlined Button + { 'hover:bg-surface-300/20': props.plain && (props.text || props.outlined) }, + + // Primary + { 'hover:bg-primary-emphasis hover:border-primary-emphasis': !props.link && props.severity === null && !props.text && !props.outlined && !props.plain }, + { 'focus:ring-primary': props.severity === null }, + // Text & Outlined Button + { 'hover:bg-primary-300/20': (props.text || props.outlined) && props.severity === null && !props.plain }, + + // Secondary + { 'hover:bg-surface-600 dark:hover:bg-surface-300 hover:border-surface-600 dark:hover:border-surface-300': props.severity === 'secondary' && !props.text && !props.outlined && !props.plain }, + { 'focus:ring-surface-400/50 dark:focus:ring-surface-300/50': props.severity === 'secondary' }, + // Text & Outlined Button + { 'hover:bg-surface-300/20': (props.text || props.outlined) && props.severity === 'secondary' && !props.plain }, + + // Success + { 'hover:bg-green-600 dark:hover:bg-green-300 hover:border-green-600 dark:hover:border-green-300': props.severity === 'success' && !props.text && !props.outlined && !props.plain }, + { 'focus:ring-green-400/50 dark:focus:ring-green-300/50': props.severity === 'success' }, + // Text & Outlined Button + { 'hover:bg-green-300/20': (props.text || props.outlined) && props.severity === 'success' && !props.plain }, + + // Info + { 'hover:bg-blue-600 dark:hover:bg-blue-300 hover:border-blue-600 dark:hover:border-blue-300': props.severity === 'info' && !props.text && !props.outlined && !props.plain }, + { 'focus:ring-blue-400/50 dark:focus:ring-blue-300/50': props.severity === 'info' }, + // Text & Outlined Button + { 'hover:bg-blue-300/20': (props.text || props.outlined) && props.severity === 'info' && !props.plain }, + + // Warning + { 'hover:bg-orange-600 dark:hover:bg-orange-300 hover:border-orange-600 dark:hover:border-orange-300': props.severity === 'warn' && !props.text && !props.outlined && !props.plain }, + { 'focus:ring-orange-400/50 dark:focus:ring-orange-300/50': props.severity === 'warn' }, + // Text & Outlined Button + { 'hover:bg-orange-300/20': (props.text || props.outlined) && props.severity === 'warn' && !props.plain }, + + // Help + { 'hover:bg-purple-600 dark:hover:bg-purple-300 hover:border-purple-600 dark:hover:border-purple-300': props.severity === 'help' && !props.text && !props.outlined && !props.plain }, + { 'focus:ring-purple-400/50 dark:focus:ring-purple-300/50': props.severity === 'help' }, + // Text & Outlined Button + { 'hover:bg-purple-300/20': (props.text || props.outlined) && props.severity === 'help' && !props.plain }, + + // Danger + { 'hover:bg-red-600 dark:hover:bg-red-300 hover:border-red-600 dark:hover:border-red-300': props.severity === 'danger' && !props.text && !props.outlined && !props.plain }, + { 'focus:ring-red-400/50 dark:focus:ring-red-300/50': props.severity === 'danger' }, + // Text & Outlined Button + { 'hover:bg-red-300/20': (props.text || props.outlined) && props.severity === 'danger' && !props.plain }, + // Contrast + { 'hover:bg-surface-800 dark:hover:bg-surface-100 hover:border-surface-800 dark:hover:border-surface-100': props.severity === 'contrast' && !props.text && !props.outlined && !props.plain }, + { 'focus:ring-surface-500 dark:focus:ring-surface-400': props.severity === 'contrast' }, + // Text & Outlined Button + { 'hover:bg-surface-900/10 dark:hover:bg-[rgba(255,255,255,0.03)]': (props.text || props.outlined) && props.severity === 'contrast' && !props.plain }, + // Disabled + { 'opacity-60 pointer-events-none cursor-default': context.disabled }, + + // Transitions + 'transition duration-200 ease-in-out', + + // Misc + 'cursor-pointer overflow-hidden select-none', + + // Badge + '[&>[data-pc-name=badge]]:min-w-4 [&>[data-pc-name=badge]]:h-4 [&>[data-pc-name=badge]]:leading-4', + ], + }), + label: ({ props }) => ({ + class: [ + 'duration-200', + 'font-bold', + { + 'hover:underline': props.link, + }, + { 'flex-1': props.label !== null, 'invisible w-0': props.label == null }, + ], + }), + icon: ({ props }) => ({ + class: [ + 'mx-0', + { + 'mr-2': props.iconPos == 'left' && props.label != null, + 'ml-2 order-1': props.iconPos == 'right' && props.label != null, + 'order-2': props.iconPos == 'bottom' && props.label != null, + }, + ], + }), + loadingIcon: ({ props }) => ({ + class: [ + 'h-4 w-4', + 'mx-0', + { + 'mr-2': props.iconPos == 'left' && props.label != null, + 'ml-2 order-1': props.iconPos == 'right' && props.label != null, + 'mb-2': props.iconPos == 'top' && props.label != null, + 'mt-2': props.iconPos == 'bottom' && props.label != null, + }, + 'animate-spin', + ], + }), + badge: ({ props }) => ({ + class: [{ 'ml-2 w-4 h-4 leading-none flex items-center justify-center': props.badge }], + }), }; From 5c4dcd1046842cdfd50d88be9a728bb3278240f8 Mon Sep 17 00:00:00 2001 From: zumuta Date: Sat, 14 Sep 2024 15:55:54 +0200 Subject: [PATCH 219/410] fix: remove bg-primary-500 and text-primary-text --- frontend/packages/kwai-ui/src/nav/KwaiMenubar.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/packages/kwai-ui/src/nav/KwaiMenubar.vue b/frontend/packages/kwai-ui/src/nav/KwaiMenubar.vue index ac6f64f0..849daff3 100644 --- a/frontend/packages/kwai-ui/src/nav/KwaiMenubar.vue +++ b/frontend/packages/kwai-ui/src/nav/KwaiMenubar.vue @@ -21,7 +21,7 @@ const menuItems = computed(() => {