diff --git a/ansible/bake-pies.yml b/ansible/bake-pies.yml index 3002600..291851d 100755 --- a/ansible/bake-pies.yml +++ b/ansible/bake-pies.yml @@ -59,15 +59,15 @@ line: "{{ terminus_key }}" when: terminuskey_test.stdout == "0" - - name: Check rohan public key - shell: "grep -c \"{{ rohan_key }}\" /home/{{ user }}/.ssh/authorized_keys || true" - register: rohankey_test + - name: Check clair public key + shell: "grep -c \"{{ clair_key }}\" /home/{{ user }}/.ssh/authorized_keys || true" + register: clairkey_test - - name: Add Rohan public key + - name: Add clair public key lineinfile: dest: "/home/{{ user }}/.ssh/authorized_keys" - line: "{{ rohan_key }}" - when: rohankey_test.stdout == "0" + line: "{{ clair_key }}" + when: clairkey_test.stdout == "0" - name: Check Anjin public key shell: "grep -c \"{{ anjin_key }}\" /home/{{ user }}/.ssh/authorized_keys || true" @@ -146,21 +146,21 @@ groups: lp append: yes - - name: install rohan-redis-tunnel systemd unit file + - name: install nats-tunnel systemd unit file template: - src: "files/rohan-redis-tunnel.service" - dest: "/etc/systemd/system/rohan-redis-tunnel.service" + src: "files/nats-tunnel.service" + dest: "/etc/systemd/system/nats-tunnel.service" - - name: enable service rohan-redis-tunnel and ensure it is not masked + - name: enable service nats-tunnel and ensure it is not masked systemd: - name: rohan-redis-tunnel + name: nats-tunnel enabled: yes masked: no - - name: Make sure rohan-redis-tunnel service is running + - name: Make sure nats-tunnel service is running systemd: state: started - name: rohan-redis-tunnel + name: nats-tunnel - name: install leardal systemd unit file template: diff --git a/ansible/files/config b/ansible/files/config index cee95cd..9e56a2a 100644 --- a/ansible/files/config +++ b/ansible/files/config @@ -1,4 +1,4 @@ -Host rohan rohan.tanshu.com - HostName rohan.tanshu.com +Host {{ server }} {{ server }}.tanshu.com + HostName {{ server }}.tanshu.com IdentityFile ~/.ssh/id_ed25519 User tanshu diff --git a/ansible/files/frank.service b/ansible/files/frank.service index 613a245..242d3a3 100644 --- a/ansible/files/frank.service +++ b/ansible/files/frank.service @@ -1,9 +1,9 @@ [Unit] Description=Frank container service -After=docker.service rohan-redis-tunnel.service -Wants=network-online.target docker.socket rohan-redis-tunnel.service -Requires=docker.socket rohan-redis-tunnel.service -PartOf=rohan-redis-tunnel.service +After=docker.service {{ server }}-redis-tunnel.service +Wants=network-online.target docker.socket {{ server }}-redis-tunnel.service +Requires=docker.socket {{ server }}-redis-tunnel.service +PartOf={{ server }}-redis-tunnel.service [Service] Restart=always diff --git a/ansible/files/leardal.service b/ansible/files/leardal.service index 4795a3c..604e5bf 100644 --- a/ansible/files/leardal.service +++ b/ansible/files/leardal.service @@ -6,7 +6,7 @@ After=network.target Type=simple User={{ user }} -ExecStart=/usr/bin/ssh -NTg -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -o ServerAliveCountMax=3 -o StrictHostKeyChecking=no -i /home/{{ user }}/.ssh/id_ed25519 -R {{ ssh_port }}:localhost:22 tanshu@rohan.tanshu.com +ExecStart=/usr/bin/ssh -NTg -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -o ServerAliveCountMax=3 -o StrictHostKeyChecking=no -i /home/{{ user }}/.ssh/id_ed25519 -R {{ ssh_port }}:localhost:22 tanshu@{{ server }}.tanshu.com # Restart every >2 seconds to avoid StartLimitInterval failure Restart=always diff --git a/ansible/files/rohan-redis-tunnel.service b/ansible/files/nats-tunnel.service similarity index 79% rename from ansible/files/rohan-redis-tunnel.service rename to ansible/files/nats-tunnel.service index 2d67793..5cc3b89 100644 --- a/ansible/files/rohan-redis-tunnel.service +++ b/ansible/files/nats-tunnel.service @@ -5,7 +5,7 @@ After=network.target [Service] User={{ user }} -ExecStart=/usr/bin/ssh -NT -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes -o ServerAliveCountMax=2 -o StrictHostKeyChecking=no -i /home/{{ user }}/.ssh/id_ed25519 -L 6379:localhost:6379 tanshu@rohan.tanshu.com +ExecStart=/usr/bin/ssh -NT -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes -o ServerAliveCountMax=2 -o StrictHostKeyChecking=no -i /home/{{ user }}/.ssh/id_ed25519 -L 4222:localhost:4222 tanshu@{{ server }}.tanshu.com # Restart every >2 seconds to avoid StartLimitInterval failure RestartSec=5 diff --git a/ansible/files/nginx.conf.j2 b/ansible/files/nginx.conf.j2 deleted file mode 100644 index 9bd5782..0000000 --- a/ansible/files/nginx.conf.j2 +++ /dev/null @@ -1,39 +0,0 @@ -server { - - listen 80; - server_name {{ http_host }}; - - # Allow large attachments - client_max_body_size 128M; - - location /api { - proxy_set_header Host $host:$server_port; - proxy_set_header X-Scheme $scheme; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_pass http://localhost:{{ host_port }}; - } - location /token { - - proxy_set_header Host $host:$server_port; - proxy_set_header X-Scheme $scheme; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_pass http://localhost:{{ host_port }}; - } - location /refresh { - proxy_set_header Host $host:$server_port; - proxy_set_header X-Scheme $scheme; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_pass http://localhost:{{ host_port }}; - } - location /db-image { - proxy_set_header Host $host:$server_port; - proxy_set_header X-Scheme $scheme; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_pass http://localhost:{{ host_port }}; - } - location / { - root /var/lib/{{ host_directory }}/frontend; - index index.html index.htm; - try_files $uri $uri/ /index.html =404; - } -} diff --git a/ansible/vars/pies.yml b/ansible/vars/pies.yml index bcf7af6..2924a22 100644 --- a/ansible/vars/pies.yml +++ b/ansible/vars/pies.yml @@ -3,5 +3,6 @@ hostname: "moz2" ssh_port: "22542" user: "vari" terminus_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK8WQHla0uCcNwmN0DUE49lbjNWa6+7A6OxrX3WEPQH0 tanshu@terminus 2023.01.08" -rohan_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKk6HHpwGQTfciXFaKOBWg+zh09XtTYvYxFZaaW3yMln tanshu@rohan 2023.08.06" +clair_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBeTz3weHvjJRTlBg+ovP3KfQNDvyn9mVsekAGwX1HMn tanshu@clair 2025-06-30" anjin_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMlvalE0JqKyjpEsGTgtf/N1d9QK2MgNFJib+e8O2h9M tanshu@anjin 2024.09.28" +server: "clair" diff --git a/barker/barker/__version__.py b/barker/barker/__version__.py index 4bdf804..ba852a5 100644 --- a/barker/barker/__version__.py +++ b/barker/barker/__version__.py @@ -1 +1 @@ -__version__ = "14.5.0" +__version__ = "14.5.1" diff --git a/barker/barker/core/arq.py b/barker/barker/core/arq.py deleted file mode 100644 index 1e405b6..0000000 --- a/barker/barker/core/arq.py +++ /dev/null @@ -1,6 +0,0 @@ -from arq.connections import RedisSettings - -from .config import settings as sett - - -settings = RedisSettings(host=sett.REDIS_HOST, port=sett.REDIS_PORT) diff --git a/barker/barker/core/config.py b/barker/barker/core/config.py index 743ae1b..35f3a70 100644 --- a/barker/barker/core/config.py +++ b/barker/barker/core/config.py @@ -18,14 +18,10 @@ class Settings(BaseSettings): LOG_LEVEL: str = "NOTSET" SQLALCHEMY_DATABASE_URI: str = "" - REDIS_HOST: str = "127.0.0.1" - REDIS_PORT: int = 6379 - ALEMBIC_LOG_LEVEL: str = "INFO" ALEMBIC_SQLALCHEMY_LOG_LEVEL: str = "WARN" - WORKER_REDIS_HOST: str = "127.0.0.1" - WORKER_REDIS_PORT: int = 6379 + NATS_URL: str = "nats://127.0.0.1:4222" WORKER_QUEUE_NAME: str = "arq:queue" model_config = SettingsConfigDict(case_sensitive=True, env_file=".env") diff --git a/barker/barker/core/taskiq.py b/barker/barker/core/taskiq.py new file mode 100644 index 0000000..6d6cf38 --- /dev/null +++ b/barker/barker/core/taskiq.py @@ -0,0 +1,28 @@ +import asyncio + +from taskiq_nats import PullBasedJetStreamBroker + +from .config import settings + + +broker = PullBasedJetStreamBroker(settings.NATS_URL) + + +@broker.task(task_name="sent_to_printer") +async def sent_to_printer(data: str, address: str, cut_code: str) -> None: + pass + + +def enqueue_print_job_sync(printer_name: str, data: str, address: str, cut_code: str) -> None: + async def _enqueue() -> None: + await broker.startup() + try: + await ( + sent_to_printer.kicker().with_labels(queue=f"barker.print.{printer_name}").kiq(data, address, cut_code) + ) + finally: + await broker.shutdown() + + loop = asyncio.new_event_loop() + loop.run_until_complete(_enqueue()) + loop.close() diff --git a/barker/barker/main.py b/barker/barker/main.py index be10f3e..2849890 100644 --- a/barker/barker/main.py +++ b/barker/barker/main.py @@ -4,7 +4,6 @@ import uvicorn from fastapi import FastAPI, Request from fastapi.responses import JSONResponse -from fastapi.staticfiles import StaticFiles from sqlalchemy.exc import IntegrityError, SQLAlchemyError from starlette.middleware.sessions import SessionMiddleware @@ -148,7 +147,7 @@ app.include_router(split.router, prefix="/api", tags=["voucher"]) app.include_router(change.router, prefix="/api/voucher", tags=["voucher"]) app.include_router(health.router, prefix="/health", tags=["health"]) -app.mount("/static", StaticFiles(directory="static"), name="static") +app.frontend("/", directory="frontend", check_dir="auto") def init() -> None: diff --git a/barker/barker/printing/bill.py b/barker/barker/printing/bill.py index e056ce4..f5a9572 100644 --- a/barker/barker/printing/bill.py +++ b/barker/barker/printing/bill.py @@ -1,16 +1,14 @@ -import asyncio import re import uuid from datetime import timedelta from decimal import Decimal -from arq import ArqRedis, create_pool from sqlalchemy import Date, func, select from sqlalchemy.orm import Session -from ..core.arq import settings as redis_settings from ..core.config import settings +from ..core.taskiq import enqueue_print_job_sync from ..models.bill import Bill from ..models.db_setting import DbSetting from ..models.inventory import Inventory @@ -49,22 +47,11 @@ def print_bill(voucher_id: uuid.UUID, db: Session) -> None: bill_text = design_bill(voucher, regime_id, inventories, taxes_list, db) bills.append(bill_text) - loop = asyncio.new_event_loop() - redis: ArqRedis = loop.run_until_complete(create_pool(redis_settings)) if len(bills) > 1: total = design_total(voucher, regimes, db) - loop.run_until_complete( - redis.enqueue_job( - "sent_to_printer", total, printer.address, printer.cut_code, _queue_name=f"barker:print:{printer.name}" - ) - ) + enqueue_print_job_sync(printer.name, total, printer.address, printer.cut_code) for bill in bills: - loop.run_until_complete( - redis.enqueue_job( - "sent_to_printer", bill, printer.address, printer.cut_code, _queue_name=f"barker:print:{printer.name}" - ) - ) - loop.close() + enqueue_print_job_sync(printer.name, bill, printer.address, printer.cut_code) def get_inventories(voucher: Voucher) -> list[Inventory]: diff --git a/barker/barker/printing/cashier_report.py b/barker/barker/printing/cashier_report.py index 27a259a..27f6a6f 100644 --- a/barker/barker/printing/cashier_report.py +++ b/barker/barker/printing/cashier_report.py @@ -1,14 +1,12 @@ -import asyncio import uuid from datetime import datetime, timedelta -from arq import ArqRedis, create_pool from sqlalchemy import select from sqlalchemy.orm import Session -from ..core.arq import settings as redis_settings from ..core.config import settings +from ..core.taskiq import enqueue_print_job_sync from ..models.device import Device from ..models.printer import Printer from ..models.section_printer import SectionPrinter @@ -27,19 +25,8 @@ def print_cashier_report(report: CashierReport, device_id: uuid.UUID, db: Sessio .where(SectionPrinter.sale_category_id == None) # noqa: E711 ).scalar_one() - loop = asyncio.new_event_loop() - redis: ArqRedis = loop.run_until_complete(create_pool(redis_settings)) - loop.run_until_complete( - redis.enqueue_job( - "sent_to_printer", summary, printer.address, printer.cut_code, _queue_name=f"barker:print:{printer.name}" - ) - ) - loop.run_until_complete( - redis.enqueue_job( - "sent_to_printer", details, printer.address, printer.cut_code, _queue_name=f"barker:print:{printer.name}" - ) - ) - loop.close() + enqueue_print_job_sync(printer.name, summary, printer.address, printer.cut_code) + enqueue_print_job_sync(printer.name, details, printer.address, printer.cut_code) def design_cashier_report_summary(report: CashierReport) -> str: diff --git a/barker/barker/printing/discount_report.py b/barker/barker/printing/discount_report.py index 24bf4ea..2130299 100644 --- a/barker/barker/printing/discount_report.py +++ b/barker/barker/printing/discount_report.py @@ -1,11 +1,9 @@ -import asyncio import uuid -from arq import ArqRedis, create_pool from sqlalchemy import select from sqlalchemy.orm import Session -from ..core.arq import settings as redis_settings +from ..core.taskiq import enqueue_print_job_sync from ..models.device import Device from ..models.printer import Printer from ..models.section_printer import SectionPrinter @@ -23,14 +21,7 @@ def print_discount_report(report: DiscountReport, device_id: uuid.UUID, db: Sess .where(SectionPrinter.sale_category_id == None) # noqa: E711 ).scalar_one() - loop = asyncio.new_event_loop() - redis: ArqRedis = loop.run_until_complete(create_pool(redis_settings)) - loop.run_until_complete( - redis.enqueue_job( - "sent_to_printer", data, printer.address, printer.cut_code, _queue_name=f"barker:print:{printer.name}" - ) - ) - loop.close() + enqueue_print_job_sync(printer.name, data, printer.address, printer.cut_code) def design_discount_report(report: DiscountReport) -> str: diff --git a/barker/barker/printing/kot.py b/barker/barker/printing/kot.py index bc4eec6..daf71c5 100644 --- a/barker/barker/printing/kot.py +++ b/barker/barker/printing/kot.py @@ -1,15 +1,13 @@ -import asyncio import uuid from datetime import timedelta from typing import Any -from arq import ArqRedis, create_pool from sqlalchemy import Date, func, or_, select from sqlalchemy.orm import Session -from ..core.arq import settings as redis_settings from ..core.config import settings +from ..core.taskiq import enqueue_print_job_sync from ..models.inventory import Inventory from ..models.kot import Kot from ..models.printer import Printer @@ -80,20 +78,9 @@ def print_kot(voucher_id: uuid.UUID, db: Session) -> None: if key not in my_hash: my_hash[key] = (printer, []) my_hash[key][1].append(item) - loop = asyncio.new_event_loop() - redis: ArqRedis = loop.run_until_complete(create_pool(redis_settings)) for key, value in my_hash.items(): printer_id, copies = key printer, items = value for c in range(int(copies)): data = design_kot(voucher, kot, items, c) - loop.run_until_complete( - redis.enqueue_job( - "sent_to_printer", - data, - printer.address, - printer.cut_code, - _queue_name=f"barker:print:{printer.name}", - ) - ) - loop.close() + enqueue_print_job_sync(printer.name, data, printer.address, printer.cut_code) diff --git a/barker/barker/printing/product_sale_report.py b/barker/barker/printing/product_sale_report.py index 0a43bde..40b4a2f 100644 --- a/barker/barker/printing/product_sale_report.py +++ b/barker/barker/printing/product_sale_report.py @@ -1,14 +1,12 @@ -import asyncio import uuid from datetime import datetime, timedelta -from arq import ArqRedis, create_pool from sqlalchemy import select from sqlalchemy.orm import Session -from ..core.arq import settings as redis_settings from ..core.config import settings +from ..core.taskiq import enqueue_print_job_sync from ..models.device import Device from ..models.printer import Printer from ..models.section_printer import SectionPrinter @@ -25,14 +23,7 @@ def print_product_sale_report(report: ProductSaleReport, device_id: uuid.UUID, d .where(SectionPrinter.sale_category_id == None) # noqa: E711 ).scalar_one() - loop = asyncio.new_event_loop() - redis: ArqRedis = loop.run_until_complete(create_pool(redis_settings)) - loop.run_until_complete( - redis.enqueue_job( - "sent_to_printer", data, printer.address, printer.cut_code, _queue_name=f"barker:print:{printer.name}" - ) - ) - loop.close() + enqueue_print_job_sync(printer.name, data, printer.address, printer.cut_code) def design_product_sale_report(report: ProductSaleReport) -> str: diff --git a/barker/barker/printing/sale_report.py b/barker/barker/printing/sale_report.py index 91a5b42..b829d9e 100644 --- a/barker/barker/printing/sale_report.py +++ b/barker/barker/printing/sale_report.py @@ -1,14 +1,12 @@ -import asyncio import uuid from datetime import datetime, timedelta -from arq import ArqRedis, create_pool from sqlalchemy import select from sqlalchemy.orm import Session -from ..core.arq import settings as redis_settings from ..core.config import settings +from ..core.taskiq import enqueue_print_job_sync from ..models.device import Device from ..models.printer import Printer from ..models.section_printer import SectionPrinter @@ -26,14 +24,7 @@ def print_sale_report(report: SaleReport, device_id: uuid.UUID, db: Session) -> .where(SectionPrinter.sale_category_id == None) # noqa: E711 ).scalar_one() - loop = asyncio.new_event_loop() - redis: ArqRedis = loop.run_until_complete(create_pool(redis_settings)) - loop.run_until_complete( - redis.enqueue_job( - "sent_to_printer", data, printer.address, printer.cut_code, _queue_name=f"barker:print:{printer.name}" - ) - ) - loop.close() + enqueue_print_job_sync(printer.name, data, printer.address, printer.cut_code) def design_sale_report(report: SaleReport) -> str: diff --git a/barker/barker/routers/customer.py b/barker/barker/routers/customer.py index a890fc2..c002280 100644 --- a/barker/barker/routers/customer.py +++ b/barker/barker/routers/customer.py @@ -122,8 +122,8 @@ def show_term( q: str | None, p: int = 0, # Page number s: int = 25, # Page size - f: str | None = None, # Sort field - d: str | None = None, # Sort direction + f: str = "name", # Sort field + d: str = "asc", # Sort direction ) -> list[schemas.Customer]: # Handle dynamic sorting safely sort_field = ALLOWED_SORT_FIELDS.get(f or "name", Customer.name) # Default to name @@ -139,8 +139,8 @@ def customer_list( filter: list[str], page: int | None, page_size: int | None, - sort_field: InstrumentedAttribute[Any] | None, - sort_direction: Any | None, + sort_field: InstrumentedAttribute[Any], + sort_direction: Any, db: Session, ) -> tuple[Sequence[Customer], int]: # Handle dynamic sorting safely diff --git a/barker/pyproject.toml b/barker/pyproject.toml index e2d70aa..7492d51 100644 --- a/barker/pyproject.toml +++ b/barker/pyproject.toml @@ -1,13 +1,12 @@ [project] name = "barker" -version = "14.5.0" +version = "14.5.1" description = "Point of Sale for a restaurant" requires-python = ">=3.14" authors = [{ name = "tanshu", email = "git@tanshu.com" }] dependencies = [ "aiohttp>=3.14.3", "alembic>=1.19.1", - "arq>=0.28.0", "cryptography>=50.0.0", "fastapi[all]>=0.141.1", "gunicorn>=26.0.0", @@ -20,6 +19,8 @@ dependencies = [ "python-dotenv>=1.2.2", "python-multipart>=0.0.32", "sqlalchemy>=2.0.51", + "taskiq>=0.12.4", + "taskiq-nats>=0.6.0", "uvicorn[standard]>=0.52.1", ] @@ -105,9 +106,7 @@ ignore = [ "W191", # indentation contains tabs "B904", # Allow raising exceptions without from e, for HTTPException ] -fixable = [ - "ALL" -] # Allow fix for all enabled rules (when `--fix`) is provided. +fixable = ["ALL"] # Allow fix for all enabled rules (when `--fix`) is provided. dummy-variable-rgx = "^(user|_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" [tool.ruff.lint.isort] diff --git a/barker/uv.lock b/barker/uv.lock index 4e10573..6dafc25 100644 --- a/barker/uv.lock +++ b/barker/uv.lock @@ -129,19 +129,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl", hash = "sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c", size = 113592, upload-time = "2026-01-06T11:45:19.497Z" }, ] -[[package]] -name = "arq" -version = "0.28.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "redis", extra = ["hiredis"] }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a4/81/7f9db65a89c29ba374000309b9dd95509500045df5c7e22f26c3731b7380/arq-0.28.0.tar.gz", hash = "sha256:a458188aefc2d7ee17d136f80d8fa8df1d6eba4ceebdead87e9f172d027dc311", size = 416141, upload-time = "2026-04-16T10:50:23.893Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/48/32/66b616976c5058d434ca2017979bfffd784888177b16b5038abcec93954a/arq-0.28.0-py3-none-any.whl", hash = "sha256:b1696bf5614d60f4172a2c0cbdc177e23ba03a5eb9acc29bd8181f4ea71fff94", size = 26061, upload-time = "2026-04-16T10:50:22.321Z" }, -] - [[package]] name = "ast-serialize" version = "0.8.0" @@ -244,12 +231,11 @@ wheels = [ [[package]] name = "barker" -version = "14.5.0" +version = "14.5.1" source = { editable = "." } dependencies = [ { name = "aiohttp" }, { name = "alembic" }, - { name = "arq" }, { name = "cryptography" }, { name = "fastapi", extra = ["all"] }, { name = "gunicorn" }, @@ -262,6 +248,8 @@ dependencies = [ { name = "python-dotenv" }, { name = "python-multipart" }, { name = "sqlalchemy" }, + { name = "taskiq" }, + { name = "taskiq-nats" }, { name = "uvicorn", extra = ["standard"] }, ] @@ -278,7 +266,6 @@ dev = [ requires-dist = [ { name = "aiohttp", specifier = ">=3.14.3" }, { name = "alembic", specifier = ">=1.19.1" }, - { name = "arq", specifier = ">=0.28.0" }, { name = "cryptography", specifier = ">=50.0.0" }, { name = "fastapi", extras = ["all"], specifier = ">=0.141.1" }, { name = "gunicorn", specifier = ">=26.0.0" }, @@ -291,6 +278,8 @@ requires-dist = [ { name = "python-dotenv", specifier = ">=1.2.2" }, { name = "python-multipart", specifier = ">=0.0.32" }, { name = "sqlalchemy", specifier = ">=2.0.51" }, + { name = "taskiq", specifier = ">=0.12.4" }, + { name = "taskiq-nats", specifier = ">=0.6.0" }, { name = "uvicorn", extras = ["standard"], specifier = ">=0.52.1" }, ] @@ -720,40 +709,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, ] -[[package]] -name = "hiredis" -version = "3.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/65/82/d2817ce0653628e0a0cb128533f6af0dd6318a49f3f3a6a7bd1f2f2154af/hiredis-3.3.0.tar.gz", hash = "sha256:105596aad9249634361815c574351f1bd50455dc23b537c2940066c4a9dea685", size = 89048, upload-time = "2025-10-14T16:33:34.263Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/aa/b3/b948ee76a6b2bc7e45249861646f91f29704f743b52565cf64cee9c4658b/hiredis-3.3.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c135bda87211f7af9e2fd4e046ab433c576cd17b69e639a0f5bb2eed5e0e71a9", size = 82105, upload-time = "2025-10-14T16:32:37.204Z" }, - { url = "https://files.pythonhosted.org/packages/a2/9b/4210f4ebfb3ab4ada964b8de08190f54cbac147198fb463cd3c111cc13e0/hiredis-3.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2f855c678230aed6fc29b962ce1cc67e5858a785ef3a3fd6b15dece0487a2e60", size = 46237, upload-time = "2025-10-14T16:32:38.07Z" }, - { url = "https://files.pythonhosted.org/packages/b3/7a/e38bfd7d04c05036b4ccc6f42b86b1032185cf6ae426e112a97551fece14/hiredis-3.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4059c78a930cbb33c391452ccce75b137d6f89e2eebf6273d75dafc5c2143c03", size = 41894, upload-time = "2025-10-14T16:32:38.929Z" }, - { url = "https://files.pythonhosted.org/packages/28/d3/eae43d9609c5d9a6effef0586ee47e13a0d84b44264b688d97a75cd17ee5/hiredis-3.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:334a3f1d14c253bb092e187736c3384203bd486b244e726319bbb3f7dffa4a20", size = 170486, upload-time = "2025-10-14T16:32:40.147Z" }, - { url = "https://files.pythonhosted.org/packages/c3/fd/34d664554880b27741ab2916d66207357563b1639e2648685f4c84cfb755/hiredis-3.3.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd137b147235447b3d067ec952c5b9b95ca54b71837e1b38dbb2ec03b89f24fc", size = 182031, upload-time = "2025-10-14T16:32:41.06Z" }, - { url = "https://files.pythonhosted.org/packages/08/a3/0c69fdde3f4155b9f7acc64ccffde46f312781469260061b3bbaa487fd34/hiredis-3.3.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8f88f4f2aceb73329ece86a1cb0794fdbc8e6d614cb5ca2d1023c9b7eb432db8", size = 180542, upload-time = "2025-10-14T16:32:42.993Z" }, - { url = "https://files.pythonhosted.org/packages/68/7a/ad5da4d7bc241e57c5b0c4fe95aa75d1f2116e6e6c51577394d773216e01/hiredis-3.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:550f4d1538822fc75ebf8cf63adc396b23d4958bdbbad424521f2c0e3dfcb169", size = 172353, upload-time = "2025-10-14T16:32:43.965Z" }, - { url = "https://files.pythonhosted.org/packages/4b/dc/c46eace64eb047a5b31acd5e4b0dc6d2f0390a4a3f6d507442d9efa570ad/hiredis-3.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:54b14211fbd5930fc696f6fcd1f1f364c660970d61af065a80e48a1fa5464dd6", size = 166435, upload-time = "2025-10-14T16:32:44.97Z" }, - { url = "https://files.pythonhosted.org/packages/4a/ac/ad13a714e27883a2e4113c980c94caf46b801b810de5622c40f8d3e8335f/hiredis-3.3.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:c9e96f63dbc489fc86f69951e9f83dadb9582271f64f6822c47dcffa6fac7e4a", size = 177218, upload-time = "2025-10-14T16:32:45.936Z" }, - { url = "https://files.pythonhosted.org/packages/c2/38/268fabd85b225271fe1ba82cb4a484fcc1bf922493ff2c74b400f1a6f339/hiredis-3.3.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:106e99885d46684d62ab3ec1d6b01573cc0e0083ac295b11aaa56870b536c7ec", size = 170477, upload-time = "2025-10-14T16:32:46.898Z" }, - { url = "https://files.pythonhosted.org/packages/20/6b/02bb8af810ea04247334ab7148acff7a61c08a8832830c6703f464be83a9/hiredis-3.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:087e2ef3206361281b1a658b5b4263572b6ba99465253e827796964208680459", size = 167915, upload-time = "2025-10-14T16:32:47.847Z" }, - { url = "https://files.pythonhosted.org/packages/83/94/901fa817e667b2e69957626395e6dee416e31609dca738f28e6b545ca6c2/hiredis-3.3.0-cp314-cp314-win32.whl", hash = "sha256:80638ebeab1cefda9420e9fedc7920e1ec7b4f0513a6b23d58c9d13c882f8065", size = 21165, upload-time = "2025-10-14T16:32:50.753Z" }, - { url = "https://files.pythonhosted.org/packages/b1/7e/4881b9c1d0b4cdaba11bd10e600e97863f977ea9d67c5988f7ec8cd363e5/hiredis-3.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a68aaf9ba024f4e28cf23df9196ff4e897bd7085872f3a30644dca07fa787816", size = 22996, upload-time = "2025-10-14T16:32:51.543Z" }, - { url = "https://files.pythonhosted.org/packages/a7/b6/d7e6c17da032665a954a89c1e6ee3bd12cb51cd78c37527842b03519981d/hiredis-3.3.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:f7f80442a32ce51ee5d89aeb5a84ee56189a0e0e875f1a57bbf8d462555ae48f", size = 83034, upload-time = "2025-10-14T16:32:52.395Z" }, - { url = "https://files.pythonhosted.org/packages/27/6c/6751b698060cdd1b2d8427702cff367c9ed7a1705bcf3792eb5b896f149b/hiredis-3.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:a1a67530da714954ed50579f4fe1ab0ddbac9c43643b1721c2cb226a50dde263", size = 46701, upload-time = "2025-10-14T16:32:53.572Z" }, - { url = "https://files.pythonhosted.org/packages/ce/8e/20a5cf2c83c7a7e08c76b9abab113f99f71cd57468a9c7909737ce6e9bf8/hiredis-3.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:616868352e47ab355559adca30f4f3859f9db895b4e7bc71e2323409a2add751", size = 42381, upload-time = "2025-10-14T16:32:54.762Z" }, - { url = "https://files.pythonhosted.org/packages/be/0a/547c29c06e8c9c337d0df3eec39da0cf1aad701daf8a9658dd37f25aca66/hiredis-3.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e799b79f3150083e9702fc37e6243c0bd47a443d6eae3f3077b0b3f510d6a145", size = 180313, upload-time = "2025-10-14T16:32:55.644Z" }, - { url = "https://files.pythonhosted.org/packages/89/8a/488de5469e3d0921a1c425045bf00e983d48b2111a90e47cf5769eaa536c/hiredis-3.3.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9ef1dfb0d2c92c3701655e2927e6bbe10c499aba632c7ea57b6392516df3864b", size = 190488, upload-time = "2025-10-14T16:32:56.649Z" }, - { url = "https://files.pythonhosted.org/packages/b5/59/8493edc3eb9ae0dbea2b2230c2041a52bc03e390b02ffa3ac0bca2af9aea/hiredis-3.3.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c290da6bc2a57e854c7da9956cd65013483ede935677e84560da3b848f253596", size = 189210, upload-time = "2025-10-14T16:32:57.759Z" }, - { url = "https://files.pythonhosted.org/packages/f0/de/8c9a653922057b32fb1e2546ecd43ef44c9aa1a7cf460c87cae507eb2bc7/hiredis-3.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd8c438d9e1728f0085bf9b3c9484d19ec31f41002311464e75b69550c32ffa8", size = 180972, upload-time = "2025-10-14T16:32:58.737Z" }, - { url = "https://files.pythonhosted.org/packages/e4/a3/51e6e6afaef2990986d685ca6e254ffbd191f1635a59b2d06c9e5d10c8a2/hiredis-3.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1bbc6b8a88bbe331e3ebf6685452cebca6dfe6d38a6d4efc5651d7e363ba28bd", size = 175315, upload-time = "2025-10-14T16:32:59.774Z" }, - { url = "https://files.pythonhosted.org/packages/96/54/e436312feb97601f70f8b39263b8da5ac4a5d18305ebdfb08ad7621f6119/hiredis-3.3.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:55d8c18fe9a05496c5c04e6eccc695169d89bf358dff964bcad95696958ec05f", size = 185653, upload-time = "2025-10-14T16:33:00.749Z" }, - { url = "https://files.pythonhosted.org/packages/ed/a3/88e66030d066337c6c0f883a912c6d4b2d6d7173490fbbc113a6cbe414ff/hiredis-3.3.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:4ddc79afa76b805d364e202a754666cb3c4d9c85153cbfed522871ff55827838", size = 179032, upload-time = "2025-10-14T16:33:01.711Z" }, - { url = "https://files.pythonhosted.org/packages/bc/1f/fb7375467e9adaa371cd617c2984fefe44bdce73add4c70b8dd8cab1b33a/hiredis-3.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8e8a4b8540581dcd1b2b25827a54cfd538e0afeaa1a0e3ca87ad7126965981cc", size = 176127, upload-time = "2025-10-14T16:33:02.793Z" }, - { url = "https://files.pythonhosted.org/packages/66/14/0dc2b99209c400f3b8f24067273e9c3cb383d894e155830879108fb19e98/hiredis-3.3.0-cp314-cp314t-win32.whl", hash = "sha256:298593bb08487753b3afe6dc38bac2532e9bac8dcee8d992ef9977d539cc6776", size = 22024, upload-time = "2025-10-14T16:33:03.812Z" }, - { url = "https://files.pythonhosted.org/packages/b2/2f/8a0befeed8bbe142d5a6cf3b51e8cbe019c32a64a596b0ebcbc007a8f8f1/hiredis-3.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b442b6ab038a6f3b5109874d2514c4edf389d8d8b553f10f12654548808683bc", size = 23808, upload-time = "2025-10-14T16:33:04.965Z" }, -] - [[package]] name = "httpcore" version = "1.0.9" @@ -1079,6 +1034,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] +[[package]] +name = "nats-py" +version = "2.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/02/f0/fc5e93f2b0dd14a202590ad9d30eda1955ea872039b5204357348d0f4b1e/nats_py-2.15.0.tar.gz", hash = "sha256:6622c547d9a7d2313d9c147d46c386188f4ec2c7b5c9f9a0438a4d1b55f54a93", size = 75995, upload-time = "2026-06-05T07:34:03.904Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/a8/b55606c7c621fb813c8ec78baf201d2c78bf6051091ec0c7ada572999e95/nats_py-2.15.0-py3-none-any.whl", hash = "sha256:9f8d36aa52a9926a88b8f1d70cf1fdce0ad387941479b500ee9ab3e51073cefd", size = 90334, upload-time = "2026-06-05T07:34:02.81Z" }, +] + [[package]] name = "nltk" version = "3.9.2" @@ -1258,6 +1222,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, ] +[[package]] +name = "pycron" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/5d/340be12ae4a69c33102dfb6ddc1dc6e53e69b2d504fa26b5d34a472c3057/pycron-3.2.0.tar.gz", hash = "sha256:e125a28aca0295769541a40633f70b602579df48c9cb357c36c28d2628ba2b13", size = 4248, upload-time = "2025-06-05T13:24:12.636Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/76/caf316909f4545e7158e0e1defd8956a1da49f4af04f5d16b18c358dfeac/pycron-3.2.0-py3-none-any.whl", hash = "sha256:6d2349746270bd642b71b9f7187cf13f4d9ee2412b4710396a507b5fe4f60dac", size = 4904, upload-time = "2025-06-05T13:24:11.477Z" }, +] + [[package]] name = "pydantic" version = "2.13.4" @@ -1408,23 +1381,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] -[[package]] -name = "redis" -version = "5.3.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pyjwt" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6a/cf/128b1b6d7086200c9f387bd4be9b2572a30b90745ef078bd8b235042dc9f/redis-5.3.1.tar.gz", hash = "sha256:ca49577a531ea64039b5a36db3d6cd1a0c7a60c34124d46924a45b956e8cf14c", size = 4626200, upload-time = "2025-07-25T08:06:27.778Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/26/5c5fa0e83c3621db835cfc1f1d789b37e7fa99ed54423b5f519beb931aa7/redis-5.3.1-py3-none-any.whl", hash = "sha256:dc1909bd24669cc31b5f67a039700b16ec30571096c5f1f0d9d2324bff31af97", size = 272833, upload-time = "2025-07-25T08:06:26.317Z" }, -] - -[package.optional-dependencies] -hiredis = [ - { name = "hiredis" }, -] - [[package]] name = "regex" version = "2026.2.19" @@ -1679,6 +1635,45 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/69/06/36d260a695f383345ab5bbc3fd447249594ae2fa8dfd19c533d5ae23f46b/stevedore-5.7.0-py3-none-any.whl", hash = "sha256:fd25efbb32f1abb4c9e502f385f0018632baac11f9ee5d1b70f88cc5e22ad4ed", size = 54483, upload-time = "2026-02-20T13:27:05.561Z" }, ] +[[package]] +name = "taskiq" +version = "0.12.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "anyio" }, + { name = "packaging" }, + { name = "pycron" }, + { name = "pydantic" }, + { name = "taskiq-dependencies" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/68/7b3c557782af291e22b26479127f287520fdf066d4684838e1bdd146cdc0/taskiq-0.12.5.tar.gz", hash = "sha256:fbdfc949fdefe746f771195faa34769fa6dbbb109cbd41cb1d056b794f933f43", size = 407451, upload-time = "2026-08-21T14:25:50.031Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/4b/c37a3cdfaff2ff53c3ca5d5289636b42141c9964f67d16df3017a97be9c6/taskiq-0.12.5-py3-none-any.whl", hash = "sha256:3937969fcb5290d1a007e068e7af45d0a44f885e3bfe4bf1860f7e81794930f8", size = 94204, upload-time = "2026-08-21T14:25:48.948Z" }, +] + +[[package]] +name = "taskiq-dependencies" +version = "1.5.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/47/90/47a627696e53bfdcacabc3e8c05b73bf1424685bcb5f17209cb8b12da1bf/taskiq_dependencies-1.5.7.tar.gz", hash = "sha256:0d3b240872ef152b719153b9526d866d2be978aeeaea6600e878414babc2dcb4", size = 14875, upload-time = "2025-02-26T22:07:39.876Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/6d/4a012f2de002c2e93273f5e7d3e3feea02f7fdbb7b75ca2ca1dd10703091/taskiq_dependencies-1.5.7-py3-none-any.whl", hash = "sha256:6fcee5d159bdb035ef915d4d848826169b6f06fe57cc2297a39b62ea3e76036f", size = 13801, upload-time = "2025-02-26T22:07:38.622Z" }, +] + +[[package]] +name = "taskiq-nats" +version = "0.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nats-py" }, + { name = "taskiq" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/4a/35a179f3bb4e41048fe68401cd3fae91c371e9b877f9266b3d8e80fb13e6/taskiq_nats-0.6.0.tar.gz", hash = "sha256:3335fc416e9872a6ed3dbb0af3b51d1d61f23aaa9983c91337c16534abe71c72", size = 7611, upload-time = "2025-11-25T11:06:03.02Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/b0/6b564579476b26c1e881e051e256c62ba3eb4a0f522fb536531e35f150d2/taskiq_nats-0.6.0-py3-none-any.whl", hash = "sha256:3d08288cbcca1da500663a45a3c33f03160721380e61cb2351e962f4805cadba", size = 8930, upload-time = "2025-11-25T11:06:02.048Z" }, +] + [[package]] name = "tenacity" version = "9.1.4" diff --git a/bookie/package.json b/bookie/package.json index 2c1ede2..6b082fb 100644 --- a/bookie/package.json +++ b/bookie/package.json @@ -1,6 +1,6 @@ { "name": "bookie", - "version": "14.5.0", + "version": "14.5.1", "scripts": { "ng": "ng", "start": "ng serve", diff --git a/bookie/src/app/app.environment.ts b/bookie/src/app/app.environment.ts index 96913ab..7ce7e1e 100644 --- a/bookie/src/app/app.environment.ts +++ b/bookie/src/app/app.environment.ts @@ -1,7 +1,7 @@ export const environment = { production: true, ACCESS_TOKEN_REFRESH_MINUTES: 10, // refresh token 10 minutes before expiry - version: '14.5.0', + version: '14.5.1', }; export const dateFormat = { diff --git a/bookie/src/app/auth/login/login.component.html b/bookie/src/app/auth/login/login.component.html index 57d3aa7..39050e3 100644 --- a/bookie/src/app/auth/login/login.component.html +++ b/bookie/src/app/auth/login/login.component.html @@ -3,14 +3,14 @@
Username - +
Password - - {{ hide ? 'visibility' : 'visibility_off' }} + + {{ hide() ? 'visibility' : 'visibility_off' }}
@if (unregisteredDevice()) { diff --git a/bookie/src/app/auth/login/login.component.ts b/bookie/src/app/auth/login/login.component.ts index 31c9f66..739c917 100644 --- a/bookie/src/app/auth/login/login.component.ts +++ b/bookie/src/app/auth/login/login.component.ts @@ -1,13 +1,4 @@ -import { - AfterViewInit, - ChangeDetectorRef, - Component, - ElementRef, - OnInit, - ViewChild, - inject, - signal, -} from '@angular/core'; +import { Component, afterNextRender, inject, input, signal } from '@angular/core'; import { form, FormField, required } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatDividerModule } from '@angular/material/divider'; @@ -15,7 +6,7 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { MatSnackBar } from '@angular/material/snack-bar'; -import { ActivatedRoute, Router } from '@angular/router'; +import { Router } from '@angular/router'; import { CookieService } from '../../shared/cookie.service'; import { AuthService } from '../auth.service'; @@ -31,14 +22,15 @@ export interface LoginFormData { styleUrls: ['./login.component.css'], imports: [MatButtonModule, MatDividerModule, MatFormFieldModule, MatIconModule, MatInputModule, FormField], }) -export class LoginComponent implements OnInit, AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; - private route = inject(ActivatedRoute); +export class LoginComponent { private auth = inject(AuthService); private router = inject(Router); private snackBar = inject(MatSnackBar); private cs = inject(CookieService); - private cd = inject(ChangeDetectorRef); + + returnUrl = input('/', { + transform: (v: string | null | undefined): string => v ?? '/', + }); formModel = signal({ username: '', @@ -50,28 +42,14 @@ export class LoginComponent implements OnInit, AfterViewInit { required(schemaPath.password); }); - hide: boolean; - unregisteredDevice = signal(undefined); - deviceName = signal(undefined); - private returnUrl: string; + hide = signal(true); + unregisteredDevice = signal(false); + deviceName = signal(''); constructor() { - this.hide = true; - this.unregisteredDevice.set(false); - this.deviceName.set(''); - this.returnUrl = ''; - } - - ngOnInit() { - this.returnUrl = this.route.snapshot.queryParams['returnUrl'] ?? '/'; - } - - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + afterNextRender(() => { + this.form().focusBoundControl(); + }); } login(): void { @@ -80,13 +58,12 @@ export class LoginComponent implements OnInit, AfterViewInit { const password = formModel.password ?? ''; this.auth.login(username.trim(), password.trim()).subscribe({ next: () => { - this.router.navigateByUrl(this.returnUrl); + this.router.navigateByUrl(this.returnUrl() ?? '/'); }, error: (error) => { if (error.status === 401 && error.error.detail === 'Device is not registered') { this.unregisteredDevice.set(true); this.deviceName.set(this.cs.getCookie('device')); - this.cd.detectChanges(); } this.snackBar.open(error.error.detail, 'Error'); }, diff --git a/bookie/src/app/auth/logout/logout.component.ts b/bookie/src/app/auth/logout/logout.component.ts index 5b9fab2..8425559 100644 --- a/bookie/src/app/auth/logout/logout.component.ts +++ b/bookie/src/app/auth/logout/logout.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { AuthService } from '../auth.service'; @@ -7,10 +7,10 @@ import { AuthService } from '../auth.service'; template: '', standalone: true, }) -export class LogoutComponent implements OnInit { +export class LogoutComponent { private auth = inject(AuthService); - ngOnInit() { + constructor() { this.auth.logout(); } } diff --git a/bookie/src/app/bundles/bundle-detail/bundle-detail-dialog.component.html b/bookie/src/app/bundles/bundle-detail/bundle-detail-dialog.component.html index d8337ca..8ee1cdc 100644 --- a/bookie/src/app/bundles/bundle-detail/bundle-detail-dialog.component.html +++ b/bookie/src/app/bundles/bundle-detail/bundle-detail-dialog.component.html @@ -5,7 +5,7 @@ Item - + @for (p of products(); track p) { {{ p.name }} } diff --git a/bookie/src/app/bundles/bundle-detail/bundle-detail-dialog.component.ts b/bookie/src/app/bundles/bundle-detail/bundle-detail-dialog.component.ts index aaf7198..dd10415 100644 --- a/bookie/src/app/bundles/bundle-detail/bundle-detail-dialog.component.ts +++ b/bookie/src/app/bundles/bundle-detail/bundle-detail-dialog.component.ts @@ -1,7 +1,7 @@ import { CommonModule } from '@angular/common'; -import { Component, OnInit, inject, signal, computed, effect, debounced } from '@angular/core'; +import { Component, inject, computed, debounced, linkedSignal } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; -import { MatAutocompleteModule, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; @@ -13,7 +13,7 @@ import { ProductService } from '../../product/product.service'; import { BundleItem } from '../bundle'; export interface BundleDetailDialogFormData { - product: ProductQuery | string; + product: BundleItem | ProductQuery | string; quantity: number; salePrice: number; printInBill: boolean; @@ -35,19 +35,20 @@ export interface BundleDetailDialogFormData { FormField, ], }) -export class BundleDetailDialogComponent implements OnInit { +export class BundleDetailDialogComponent { private readonly dialogRef = inject>(MatDialogRef); private readonly productSer = inject(ProductService); data = inject<{ item: BundleItem }>(MAT_DIALOG_DATA); - selectedProduct = signal(null); - - formModel = signal({ - product: '', - quantity: 1, - salePrice: 0, - printInBill: true, + formModel = linkedSignal({ + source: () => this.data.item, + computation: (item) => ({ + product: item, + quantity: Number(item.quantity ?? 1), + salePrice: Number(item.salePrice ?? 0), + printInBill: item.printInBill ?? false, + }), }); form = form(this.formModel); @@ -59,62 +60,35 @@ export class BundleDetailDialogComponent implements OnInit { debouncedProduct = debounced(this.productSignal, 150); - productsResource = this.productSer.query(computed(() => this.debouncedProduct.value())); + productsResource = this.productSer.query(this.debouncedProduct.value); products = computed(() => { if (!this.debouncedProduct.value()) return []; return this.productsResource.value() ?? []; }); - constructor() { - // typing after selecting invalidates prior selection - effect(() => { - const x = this.formModel().product; - if (typeof x === 'string') this.selectedProduct.set(null); - }); - } - - ngOnInit(): void { - // preload display text using existing name - this.formModel.set({ - product: this.data.item.name ?? '', - quantity: Number(this.data.item.quantity ?? 1), - salePrice: Number(this.data.item.salePrice ?? 0), - printInBill: this.data.item.printInBill, - }); - - this.selectedProduct.set(null); - } - displayFn(product?: ProductQuery | string): string { return !product ? '' : typeof product === 'string' ? product : product.name; } - productSelected(event: MatAutocompleteSelectedEvent): void { - const p = event.option.value as ProductQuery; - this.selectedProduct.set(p); - } - accept(): void { - const v = this.formModel(); + const formValue = this.form().value(); - const quantity = Number(v.quantity ?? 0); + const quantity = Number(formValue.quantity ?? 0); if (Number.isNaN(quantity) || quantity <= 0) return; - const salePrice = Number(v.salePrice ?? 0); + const salePrice = Number(formValue.salePrice ?? 0); if (Number.isNaN(salePrice) || salePrice < 0) return; - // If a new product was selected, update itemId + name - if (this.selectedProduct()?.id) { - this.data.item.itemId = this.selectedProduct()?.id ?? ''; - this.data.item.name = this.selectedProduct()?.name ?? ''; - } else { - // If no selection, don't allow changing SKU silently - // but still allow quantity/price edit + const product = typeof formValue.product === 'string' ? null : formValue.product; + if (!product || !product.id) { + return; } + this.data.item.itemId = product.id ?? ''; + this.data.item.name = product.name ?? ''; this.data.item.quantity = quantity; this.data.item.salePrice = salePrice; - this.data.item.printInBill = v.printInBill || false; + this.data.item.printInBill = formValue.printInBill ?? false; this.dialogRef.close(this.data.item); } diff --git a/bookie/src/app/bundles/bundle-detail/bundle-detail.component.html b/bookie/src/app/bundles/bundle-detail/bundle-detail.component.html index 7d47054..70d60ef 100644 --- a/bookie/src/app/bundles/bundle-detail/bundle-detail.component.html +++ b/bookie/src/app/bundles/bundle-detail/bundle-detail.component.html @@ -4,7 +4,7 @@
Name - + @@ -65,7 +65,7 @@ [matAutocomplete]="autoItem" [value]="displayFn(formModel().addRow.itemId)" /> - + @for (p of itemProducts(); track p) { {{ p.name }} } @@ -88,7 +88,7 @@
- + Item @@ -143,7 +143,7 @@
- @if (!!item.id) { + @if (!!item().id) { }
diff --git a/bookie/src/app/bundles/bundle-detail/bundle-detail.component.ts b/bookie/src/app/bundles/bundle-detail/bundle-detail.component.ts index 05834c2..9d6a518 100644 --- a/bookie/src/app/bundles/bundle-detail/bundle-detail.component.ts +++ b/bookie/src/app/bundles/bundle-detail/bundle-detail.component.ts @@ -1,19 +1,7 @@ import { CurrencyPipe } from '@angular/common'; -import { - AfterViewInit, - Component, - ElementRef, - ViewChild, - inject, - computed, - signal, - effect, - debounced, - linkedSignal, - input, -} from '@angular/core'; +import { Component, inject, computed, effect, debounced, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; -import { MatAutocompleteModule, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatOptionModule } from '@angular/material/core'; @@ -24,7 +12,7 @@ import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; import { MatSnackBar } from '@angular/material/snack-bar'; import { MatTableModule } from '@angular/material/table'; -import { ActivatedRoute, Router } from '@angular/router'; +import { Router } from '@angular/router'; import { MenuCategory } from '../../core/menu-category'; import { ProductQuery } from '../../core/product-query'; @@ -41,8 +29,8 @@ export interface BundleDetailFormData { name: string; units: string; salePrice: number; - menuCategory: string; - saleCategory: string; + menuCategory: MenuCategory | null; + saleCategory: SaleCategory | null; hasHappyHour: boolean; isNotAvailable: boolean; addRow: { @@ -51,6 +39,7 @@ export interface BundleDetailFormData { salePrice: number; printInBill: boolean; }; + items: BundleItem[]; } @Component({ @@ -71,53 +60,34 @@ export interface BundleDetailFormData { FormField, ], }) -export class BundleDetailComponent implements AfterViewInit { - @ViewChild('name', { static: true }) nameElement?: ElementRef; +export class BundleDetailComponent { private menuCategoryService = inject(MenuCategoryService); private saleCategoryService = inject(SaleCategoryService); - private route = inject(ActivatedRoute); private router = inject(Router); private dialog = inject(MatDialog); private snackBar = inject(MatSnackBar); private ser = inject(BundleService); private productSer = inject(ProductService); - id = input(null, { transform: (v: string | null | undefined) => v ?? null }); - - saleCategoriesResource = this.saleCategoryService.list(); - menuCategoriesResource = this.menuCategoryService.list(undefined); - + menuCategories = computed(() => this.menuCategoriesResource.value() ?? []); + saleCategoriesResource = this.saleCategoryService.list(); + saleCategories = computed(() => this.saleCategoriesResource.value() ?? []); + id = input(null, { transform: (v: string | null | undefined) => v ?? null }); itemResource = this.ser.get(this.id); - + item = computed(() => this.itemResource.value() ?? new Bundle()); formModel = linkedSignal({ - source: () => this.menuCategoriesResource.value(), - computation: (menuCategoriesVal): BundleDetailFormData => { - if (menuCategoriesVal) { - return { - name: this.item.name ?? '', - units: this.item.units ?? '', - salePrice: Number(this.item.salePrice ?? 0), - menuCategory: this.item.menuCategory?.id ?? '', - saleCategory: this.item.saleCategory?.id ?? '', - hasHappyHour: this.item.hasHappyHour ?? false, - isNotAvailable: this.item.isNotAvailable ?? false, - - addRow: { - itemId: '', - quantity: 1, - salePrice: 0, - printInBill: true, - }, - }; - } + source: this.item, + computation: (itemVal): BundleDetailFormData => { + const items = [...(itemVal.items ?? [])]; return { - name: '', - units: '', - salePrice: 0, - menuCategory: '', - saleCategory: '', - hasHappyHour: false, - isNotAvailable: false, + name: itemVal.name ?? '', + units: itemVal.units ?? '', + salePrice: Number(itemVal.salePrice ?? 0), + menuCategory: itemVal.menuCategory ?? null, + saleCategory: itemVal.saleCategory ?? null, + hasHappyHour: itemVal.hasHappyHour ?? false, + isNotAvailable: itemVal.isNotAvailable ?? false, + items, addRow: { itemId: '', quantity: 1, @@ -130,25 +100,15 @@ export class BundleDetailComponent implements AfterViewInit { form = form(this.formModel); - menuCategories = signal([]); - saleCategories = signal([]); - items = signal([]); - dataSource = computed(() => this.items()); - - item: Bundle = new Bundle(); - - itemProduct = signal(null); - - itemIdSignal = computed(() => { - const x = this.formModel().addRow?.itemId; - return typeof x === 'string' ? x.trim() : ''; + private itemProductSearch = computed(() => { + const v = this.form.addRow.itemId().value(); + return typeof v === 'string' ? v : null; }); - debouncedItemId = debounced(this.itemIdSignal, 150); + debouncedItemProduct = debounced(this.itemProductSearch, 150); - itemProductsResource = this.productSer.query(computed(() => this.debouncedItemId.value())); + itemProductsResource = this.productSer.query(this.debouncedItemProduct.value); itemProducts = computed(() => { - if (!this.debouncedItemId.value()) return []; return this.itemProductsResource.value() ?? []; }); @@ -156,25 +116,26 @@ export class BundleDetailComponent implements AfterViewInit { constructor() { effect(() => { - const x = this.formModel().addRow?.itemId; - if (typeof x === 'string') { - this.itemProduct.set(null); + const v = this.form.addRow.itemId().value(); + if (typeof v === 'object' && v !== null) { + this.formModel.update((f) => ({ + ...f, + addRow: { + ...f.addRow, + salePrice: v.price ?? 0, + }, + })); } }); effect(() => { - const menuCategoriesVal = this.menuCategoriesResource.value(); - if (menuCategoriesVal) this.menuCategories.set(menuCategoriesVal); - const saleCategoriesVal = this.saleCategoriesResource.value(); - if (saleCategoriesVal) this.saleCategories.set(saleCategoriesVal); - const itemVal = this.itemResource.value(); - if (itemVal) { - this.item = itemVal; - - this.itemProduct.set(null); - - this.items.set(this.item.items ?? []); - this.recalcBundleSalePrice(); - } + const items = this.form.items().value(); + this.formModel.update((f) => ({ + ...f, + salePrice: Number(items.reduce((sum, x) => sum + x.quantity * x.salePrice, 0).toFixed(2)), + })); + }); + afterNextRender(() => { + this.form().focusBoundControl(); }); } @@ -182,40 +143,6 @@ export class BundleDetailComponent implements AfterViewInit { return !product ? '' : typeof product === 'string' ? product : product.name; } - bundleSelected(event: MatAutocompleteSelectedEvent): void { - const product = event.option.value as ProductQuery; - this.itemProduct.set(product); - this.formModel.update((f) => ({ - ...f, - addRow: { - ...f.addRow, - salePrice: product.price ?? 0, - }, - })); - } - - private recalcBundleSalePrice(): void { - const total = (this.item.items ?? []).reduce((sum, x) => { - const qty = Number(x.quantity ?? 0); - const price = Number(x.salePrice ?? 0); - if (Number.isNaN(qty) || Number.isNaN(price)) return sum; - return sum + qty * price; - }, 0); - - // keep model + form in sync - this.item.salePrice = Number(total.toFixed(2)); - - this.formModel.update((f) => ({ ...f, salePrice: this.item.salePrice })); - } - - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); - } - resetAddRow() { this.formModel.update((f) => ({ ...f, @@ -226,47 +153,43 @@ export class BundleDetailComponent implements AfterViewInit { printInBill: true, }, })); - this.itemProduct.set(null); } addRow() { - const v = this.formModel().addRow; - if (!v) { - return; - } + const formValue = this.form().value().addRow; + if (!formValue) return; + const itemProduct = formValue.itemId as ProductQuery; - if (!this.itemProduct()?.id) { + if (!itemProduct || typeof itemProduct === 'string') { this.snackBar.open('Please select a product', 'Error'); return; } - const quantity = Number(v.quantity ?? 0); + const quantity = Number(formValue.quantity ?? 0); if (Number.isNaN(quantity) || quantity <= 0) { this.snackBar.open('Quantity has to be > 0', 'Error'); return; } - const salePrice = Number(v.salePrice ?? 0); + const salePrice = Number(formValue.salePrice ?? 0); if (Number.isNaN(salePrice) || salePrice < 0) { this.snackBar.open('Sale Price has to be >= 0', 'Error'); return; } - // name is expected from backend as "name (units)" on GET; - // for new rows we keep it blank (or you can set placeholder) const bi = new BundleItem({ - itemId: this.itemProduct()?.id, - name: this.itemProduct()?.name ?? '', + itemId: itemProduct.id, + name: itemProduct.name ?? '', quantity, salePrice, - printInBill: v.printInBill || false, + printInBill: formValue.printInBill || false, }); - this.item.items.push(bi); - this.items.set(this.item.items); + this.formModel.update((m) => ({ + ...m, + items: [...m.items, bi], + })); this.resetAddRow(); - - this.recalcBundleSalePrice(); } editRow(row: BundleItem) { @@ -281,25 +204,28 @@ export class BundleDetailComponent implements AfterViewInit { if (!result) { return; } - Object.assign(row, result as BundleItem); - this.items.set(this.item.items); + const updated = result as BundleItem; + this.formModel.update((m) => ({ + ...m, + items: m.items.map((item) => (item === row ? Object.assign(new BundleItem(item), updated) : item)), + })); this.resetAddRow(); - this.recalcBundleSalePrice(); }); } deleteRow(row: BundleItem) { - this.item.items.splice(this.item.items.indexOf(row), 1); - this.items.set(this.item.items); - this.recalcBundleSalePrice(); + this.formModel.update((m) => ({ + ...m, + items: m.items.filter((item) => item !== row), + })); } save() { - if (!this.item.items || this.item.items.length === 0) { - this.snackBar.open('Bundle must contain at least one item', 'Error'); + const item = this.getItem(); + if (!item) { return; } - this.ser.saveOrUpdate(this.getItem()).subscribe({ + this.ser.saveOrUpdate(item).subscribe({ next: () => { this.snackBar.open('', 'Success'); this.router.navigateByUrl('/bundles'); @@ -311,7 +237,7 @@ export class BundleDetailComponent implements AfterViewInit { } delete() { - this.ser.delete(this.item.id as string).subscribe({ + this.ser.delete(this.item().id as string).subscribe({ next: () => { this.snackBar.open('', 'Success'); this.router.navigateByUrl('/bundles'); @@ -335,47 +261,33 @@ export class BundleDetailComponent implements AfterViewInit { }); } - getItem(): Bundle { + getItem(): Bundle | null { const v = this.formModel(); - - this.item.name = v.name ?? ''; - this.item.units = v.units ?? ''; - this.item.salePrice = Number(v.salePrice ?? 0); - this.item.hasHappyHour = v.hasHappyHour ?? false; - this.item.isNotAvailable = v.isNotAvailable ?? false; - this.item.sortOrder = this.item.sortOrder ?? 0; - // menu category - const menuCategoryId = v.menuCategory ?? ''; - if (!menuCategoryId) { - // keep it as-is; backend will 422 anyway, but we can show UI error too + if (!v.menuCategory) { this.snackBar.open('Menu Category is required', 'Error'); - return this.item; + return null; } - - if (this.item.menuCategory === null || this.item.menuCategory === undefined) { - this.item.menuCategory = new MenuCategory(); - } - this.item.menuCategory.id = menuCategoryId; - // sale category - const saleCategoryId = v.saleCategory ?? ''; - if (!saleCategoryId) { - // keep it as-is; backend will 422 anyway, but we can show UI error too + if (!v.saleCategory) { this.snackBar.open('Menu Category is required', 'Error'); - return this.item; + return null; } - - if (this.item.saleCategory === null || this.item.saleCategory === undefined) { - this.item.saleCategory = new SaleCategory(); + if (!v.items.length) { + this.snackBar.open('Bundle must contain at least one item', 'Error'); + return null; } - this.item.saleCategory.id = saleCategoryId; - - // ensure items array exists - if (!this.item.items) { - this.item.items = []; - } - - return this.item; + return new Bundle({ + ...this.item(), + name: v.name ?? '', + units: v.units ?? '', + salePrice: Number(v.salePrice ?? 0), + hasHappyHour: v.hasHappyHour ?? false, + isNotAvailable: v.isNotAvailable ?? false, + sortOrder: this.item().sortOrder ?? 0, + menuCategory: v.menuCategory, + saleCategory: v.saleCategory, + items: v.items ?? [], + }); } } diff --git a/bookie/src/app/customers/customer-detail/customer-detail.component.html b/bookie/src/app/customers/customer-detail/customer-detail.component.html index 32c34d8..6c48a03 100644 --- a/bookie/src/app/customers/customer-detail/customer-detail.component.html +++ b/bookie/src/app/customers/customer-detail/customer-detail.component.html @@ -3,7 +3,7 @@
Name - +
diff --git a/bookie/src/app/customers/customer-detail/customer-detail.component.ts b/bookie/src/app/customers/customer-detail/customer-detail.component.ts index 6626737..1224106 100644 --- a/bookie/src/app/customers/customer-detail/customer-detail.component.ts +++ b/bookie/src/app/customers/customer-detail/customer-detail.component.ts @@ -1,5 +1,5 @@ import { PercentPipe } from '@angular/common'; -import { AfterViewInit, Component, ElementRef, ViewChild, computed, inject, linkedSignal, input } from '@angular/core'; +import { Component, computed, inject, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; @@ -39,8 +39,7 @@ export interface CustomerDetailFormData { FormField, ], }) -export class CustomerDetailComponent implements AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; +export class CustomerDetailComponent { private route = inject(ActivatedRoute); private router = inject(Router); private snackBar = inject(MatSnackBar); @@ -68,12 +67,10 @@ export class CustomerDetailComponent implements AfterViewInit { hide = true; - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + constructor() { + afterNextRender(() => { + this.form().focusBoundControl(); + }); } save() { diff --git a/bookie/src/app/customers/customer-list/customer-list.component.html b/bookie/src/app/customers/customer-list/customer-list.component.html index b45111d..051fff4 100644 --- a/bookie/src/app/customers/customer-list/customer-list.component.html +++ b/bookie/src/app/customers/customer-list/customer-list.component.html @@ -9,11 +9,11 @@
Filter - +
- + Name diff --git a/bookie/src/app/customers/customer-list/customer-list.component.ts b/bookie/src/app/customers/customer-list/customer-list.component.ts index 130485e..d05841e 100644 --- a/bookie/src/app/customers/customer-list/customer-list.component.ts +++ b/bookie/src/app/customers/customer-list/customer-list.component.ts @@ -1,21 +1,12 @@ +/* eslint-disable @angular-eslint/no-input-rename */ import { PercentPipe } from '@angular/common'; -import { - AfterViewInit, - Component, - ElementRef, - ViewChild, - inject, - signal, - effect, - computed, - debounced, -} from '@angular/core'; +import { Component, inject, signal, effect, computed, debounced, afterNextRender, input } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; -import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; -import { MatSort, MatSortModule } from '@angular/material/sort'; +import { MatPaginatorModule, PageEvent } from '@angular/material/paginator'; +import { MatSortModule, Sort } from '@angular/material/sort'; import { MatTableModule } from '@angular/material/table'; import { ActivatedRoute, Router, RouterLink } from '@angular/router'; @@ -42,13 +33,23 @@ export interface CustomerListFormData { FormField, ], }) -export class CustomerListComponent implements AfterViewInit { - @ViewChild('filterElement', { static: true }) filterElement!: ElementRef; - @ViewChild(MatPaginator, { static: true }) paginator!: MatPaginator; - @ViewChild(MatSort, { static: true }) sort!: MatSort; +export class CustomerListComponent { private route = inject(ActivatedRoute); private router = inject(Router); private customerService = inject(CustomerService); + q = input('', { transform: (v: string | null | undefined) => v ?? '' }); + pageSize = input(50, { + transform: (v: string | number | null | undefined): number => (v ? Number(v) : 50), + alias: 's', + }); + + pageIndex = input(0, { + transform: (v: string | number | null | undefined): number => (v ? Number(v) : 0), + alias: 'i', + }); + + sortInput = input('name', { alias: 'f' }); + direction = input('asc', { alias: 'd' }); formModel = signal({ filter: this.route.snapshot.queryParamMap.get('q') ?? '', @@ -56,23 +57,10 @@ export class CustomerListComponent implements AfterViewInit { form = form(this.formModel); - filterSignal = computed(() => this.formModel().filter); + filterSignal = computed(() => this.formModel().filter ?? null); debouncedFilter = debounced(this.filterSignal, 150); - pageIndex = signal(+(this.route.snapshot.queryParamMap.get('p') ?? '0')); - pageSize = signal(+(this.route.snapshot.queryParamMap.get('s') ?? '50')); - sortField = signal(this.route.snapshot.queryParamMap.get('f') ?? 'name'); - sortDirection = signal(this.route.snapshot.queryParamMap.get('d') ?? 'asc'); - - queryParams = computed(() => ({ - q: this.debouncedFilter.value() ?? '', - p: this.pageIndex(), - s: this.pageSize(), - f: this.sortField(), - d: this.sortDirection(), - })); - - listResource = this.customerService.query(this.queryParams); + listResource = this.customerService.query(this.q, this.pageIndex, this.pageSize, this.sortInput, this.direction); dataSource = computed(() => { const data = this.listResource.value(); @@ -84,32 +72,37 @@ export class CustomerListComponent implements AfterViewInit { displayedColumns = ['name', 'phone', 'address', 'printInBill', 'discounts']; constructor() { - // Sync query string whenever params change effect(() => { - const p = this.queryParams(); + const q = this.debouncedFilter.value(); this.router.navigate([], { relativeTo: this.route, - queryParams: { q: p.q, p: p.p, s: p.s, f: p.f, d: p.d }, + queryParams: { q: q }, queryParamsHandling: 'merge', replaceUrl: true, }); }); + afterNextRender(() => { + this.form().focusBoundControl(); + }); } - ngAfterViewInit() { - this.sort.sortChange.subscribe(() => { - this.sortField.set(this.sort.active); - this.sortDirection.set(this.sort.direction); - this.pageIndex.set(0); - }); + handlePageEvent(e: PageEvent) { + if (e.pageSize !== this.pageSize() || e.pageIndex !== this.pageIndex()) { + this.router.navigate([], { + relativeTo: this.route, + queryParams: { s: e.pageSize, p: e.pageIndex }, + queryParamsHandling: 'merge', + replaceUrl: true, + }); + } + } - this.paginator.page.subscribe(() => { - this.pageSize.set(this.paginator.pageSize); - this.pageIndex.set(this.paginator.pageIndex); + sortData(sort: Sort) { + this.router.navigate([], { + relativeTo: this.route, + queryParams: { f: sort.active || null, d: sort.direction || null }, + queryParamsHandling: 'merge', + replaceUrl: true, }); - - setTimeout(() => { - this.filterElement.nativeElement.focus(); - }, 0); } } diff --git a/bookie/src/app/customers/customer.service.ts b/bookie/src/app/customers/customer.service.ts index 36e7138..eece7ed 100644 --- a/bookie/src/app/customers/customer.service.ts +++ b/bookie/src/app/customers/customer.service.ts @@ -41,18 +41,21 @@ export class CustomerService { } query( - params: Signal<{ q: string; p: number; s: number; f: string; d: string }>, + q: Signal, + p: Signal, + s: Signal, + f: Signal, + d: Signal, ): HttpResourceRef | undefined> { return httpResource>(() => { - const p = params(); return { url: `${url}/list`, params: { - ...(p.q ? { q: p.q } : {}), - p: p.p, - s: p.s, - f: p.f, - d: p.d, + q: q(), + p: p(), + s: s(), + f: f(), + d: d(), }, }; }); diff --git a/bookie/src/app/devices/device-detail/device-detail.component.html b/bookie/src/app/devices/device-detail/device-detail.component.html index 75512c7..a1de46d 100644 --- a/bookie/src/app/devices/device-detail/device-detail.component.html +++ b/bookie/src/app/devices/device-detail/device-detail.component.html @@ -3,7 +3,7 @@
Name - +
diff --git a/bookie/src/app/devices/device-detail/device-detail.component.ts b/bookie/src/app/devices/device-detail/device-detail.component.ts index e2caf7b..562eec1 100644 --- a/bookie/src/app/devices/device-detail/device-detail.component.ts +++ b/bookie/src/app/devices/device-detail/device-detail.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, ViewChild, computed, inject, linkedSignal, input } from '@angular/core'; +import { Component, computed, inject, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; @@ -38,8 +38,7 @@ export interface DeviceDetailFormData { FormField, ], }) -export class DeviceDetailComponent implements AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; +export class DeviceDetailComponent { private sectionService = inject(SectionService); private route = inject(ActivatedRoute); private router = inject(Router); @@ -68,12 +67,10 @@ export class DeviceDetailComponent implements AfterViewInit { sections = computed(() => this.sectionsResource.value() ?? []); - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + constructor() { + afterNextRender(() => { + this.form().focusBoundControl(); + }); } save() { diff --git a/bookie/src/app/guest-book/guest-book-detail/guest-book-detail.component.html b/bookie/src/app/guest-book/guest-book-detail/guest-book-detail.component.html index 54798e6..b9ea107 100644 --- a/bookie/src/app/guest-book/guest-book-detail/guest-book-detail.component.html +++ b/bookie/src/app/guest-book/guest-book-detail/guest-book-detail.component.html @@ -3,13 +3,13 @@
Name - +
Phone - + { - if (this.phoneElement !== undefined) { - this.phoneElement.nativeElement.focus(); - } - }, 0); + constructor() { + afterNextRender(() => { + this.form().focusBoundControl(); + }); } save() { diff --git a/bookie/src/app/header-footer/header-footer.component.ts b/bookie/src/app/header-footer/header-footer.component.ts index a096df4..1bf1b31 100644 --- a/bookie/src/app/header-footer/header-footer.component.ts +++ b/bookie/src/app/header-footer/header-footer.component.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef, ViewChild, computed, inject, linkedSignal, input } from '@angular/core'; +import { Component, computed, inject, linkedSignal, input } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatOptionModule } from '@angular/material/core'; @@ -33,7 +33,6 @@ export interface HeaderFooterFormData { ], }) export class HeaderFooterComponent { - @ViewChild('section', { static: true }) sectionElement?: ElementRef; private route = inject(ActivatedRoute); private router = inject(Router); private snackBar = inject(MatSnackBar); diff --git a/bookie/src/app/menu-category/menu-category-detail/menu-category-detail.component.html b/bookie/src/app/menu-category/menu-category-detail/menu-category-detail.component.html index 34a668f..bb73daf 100644 --- a/bookie/src/app/menu-category/menu-category-detail/menu-category-detail.component.html +++ b/bookie/src/app/menu-category/menu-category-detail/menu-category-detail.component.html @@ -3,7 +3,7 @@
Name - +
diff --git a/bookie/src/app/menu-category/menu-category-detail/menu-category-detail.component.ts b/bookie/src/app/menu-category/menu-category-detail/menu-category-detail.component.ts index 59d754a..7520b49 100644 --- a/bookie/src/app/menu-category/menu-category-detail/menu-category-detail.component.ts +++ b/bookie/src/app/menu-category/menu-category-detail/menu-category-detail.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, ViewChild, computed, inject, linkedSignal, input } from '@angular/core'; +import { Component, computed, inject, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; @@ -23,8 +23,7 @@ export interface MenuCategoryDetailFormData { styleUrls: ['./menu-category-detail.component.css'], imports: [MatButtonModule, MatCheckboxModule, MatFormFieldModule, MatInputModule, FormField], }) -export class MenuCategoryDetailComponent implements AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; +export class MenuCategoryDetailComponent { private route = inject(ActivatedRoute); private router = inject(Router); private dialog = inject(MatDialog); @@ -47,12 +46,10 @@ export class MenuCategoryDetailComponent implements AfterViewInit { form = form(this.formModel); - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + constructor() { + afterNextRender(() => { + this.form().focusBoundControl(); + }); } save() { diff --git a/bookie/src/app/menu-engineering-report/menu-engineering-report.component.html b/bookie/src/app/menu-engineering-report/menu-engineering-report.component.html index 62e25fb..28e5931 100644 --- a/bookie/src/app/menu-engineering-report/menu-engineering-report.component.html +++ b/bookie/src/app/menu-engineering-report/menu-engineering-report.component.html @@ -40,7 +40,7 @@
Filter - + n: Name, sc: Sale Category, mc: Menu Category, q:(=/<=/>=/</>)Quantity, s:(=/<=/>=/</>)Sales this.formModel().filter); this.filter = toObservable(filterSignal).pipe(debounceTime(150), distinctUntilChanged()); + afterNextRender(() => { + this.form().focusBoundControl(); + }); } show() { diff --git a/bookie/src/app/modifier-categories/modifier-category-detail/modifier-category-detail.component.html b/bookie/src/app/modifier-categories/modifier-category-detail/modifier-category-detail.component.html index dfd9a69..5922f28 100644 --- a/bookie/src/app/modifier-categories/modifier-category-detail/modifier-category-detail.component.html +++ b/bookie/src/app/modifier-categories/modifier-category-detail/modifier-category-detail.component.html @@ -3,7 +3,7 @@
Name - +
diff --git a/bookie/src/app/modifier-categories/modifier-category-detail/modifier-category-detail.component.ts b/bookie/src/app/modifier-categories/modifier-category-detail/modifier-category-detail.component.ts index 2ab79e9..8e02dd9 100644 --- a/bookie/src/app/modifier-categories/modifier-category-detail/modifier-category-detail.component.ts +++ b/bookie/src/app/modifier-categories/modifier-category-detail/modifier-category-detail.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, ViewChild, effect, inject, input, signal } from '@angular/core'; +import { Component, effect, inject, input, signal, afterNextRender } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; @@ -48,8 +48,7 @@ export interface ModifierCategoryDetailFormData { FormField, ], }) -export class ModifierCategoryDetailComponent implements AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; +export class ModifierCategoryDetailComponent { private route = inject(ActivatedRoute); private router = inject(Router); private snackBar = inject(MatSnackBar); @@ -108,14 +107,9 @@ export class ModifierCategoryDetailComponent implements AfterViewInit { }); } }); - } - - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + afterNextRender(() => { + this.form().focusBoundControl(); + }); } // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/bookie/src/app/modifiers/modifier-detail/modifier-detail.component.html b/bookie/src/app/modifiers/modifier-detail/modifier-detail.component.html index 5916bfc..0f837ad 100644 --- a/bookie/src/app/modifiers/modifier-detail/modifier-detail.component.html +++ b/bookie/src/app/modifiers/modifier-detail/modifier-detail.component.html @@ -3,7 +3,7 @@
Name - +
diff --git a/bookie/src/app/modifiers/modifier-detail/modifier-detail.component.ts b/bookie/src/app/modifiers/modifier-detail/modifier-detail.component.ts index 9487636..7441cec 100644 --- a/bookie/src/app/modifiers/modifier-detail/modifier-detail.component.ts +++ b/bookie/src/app/modifiers/modifier-detail/modifier-detail.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, ViewChild, computed, inject, linkedSignal, input } from '@angular/core'; +import { Component, computed, inject, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField, required } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; @@ -38,8 +38,7 @@ export interface ModifierDetailFormData { FormField, ], }) -export class ModifierDetailComponent implements AfterViewInit { - @ViewChild('name', { static: true }) nameElement?: ElementRef; +export class ModifierDetailComponent { private modifierCategoryService = inject(ModifierCategoryService); private route = inject(ActivatedRoute); private router = inject(Router); @@ -71,12 +70,10 @@ export class ModifierDetailComponent implements AfterViewInit { required(schema.modifierCategory, { message: 'Modifier Category is required' }); }); - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + constructor() { + afterNextRender(() => { + this.form().focusBoundControl(); + }); } save() { diff --git a/bookie/src/app/printers/printer-detail/printer-detail.component.html b/bookie/src/app/printers/printer-detail/printer-detail.component.html index c77beb3..dcee6c1 100644 --- a/bookie/src/app/printers/printer-detail/printer-detail.component.html +++ b/bookie/src/app/printers/printer-detail/printer-detail.component.html @@ -3,7 +3,7 @@
Name - +
diff --git a/bookie/src/app/printers/printer-detail/printer-detail.component.ts b/bookie/src/app/printers/printer-detail/printer-detail.component.ts index d236ce1..4d55d94 100644 --- a/bookie/src/app/printers/printer-detail/printer-detail.component.ts +++ b/bookie/src/app/printers/printer-detail/printer-detail.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, ViewChild, computed, inject, linkedSignal, input } from '@angular/core'; +import { Component, computed, inject, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatDialog } from '@angular/material/dialog'; @@ -23,8 +23,7 @@ export interface PrinterDetailFormData { styleUrls: ['./printer-detail.component.css'], imports: [MatButtonModule, MatFormFieldModule, MatInputModule, FormField], }) -export class PrinterDetailComponent implements AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; +export class PrinterDetailComponent { private route = inject(ActivatedRoute); private router = inject(Router); private dialog = inject(MatDialog); @@ -48,12 +47,10 @@ export class PrinterDetailComponent implements AfterViewInit { form = form(this.formModel); - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + constructor() { + afterNextRender(() => { + this.form().focusBoundControl(); + }); } save() { diff --git a/bookie/src/app/product-sale-report/product-sale-report.component.html b/bookie/src/app/product-sale-report/product-sale-report.component.html index c6b1721..de47a00 100644 --- a/bookie/src/app/product-sale-report/product-sale-report.component.html +++ b/bookie/src/app/product-sale-report/product-sale-report.component.html @@ -9,7 +9,7 @@ -
+
Start Date diff --git a/bookie/src/app/product-sale-report/product-sale-report.component.ts b/bookie/src/app/product-sale-report/product-sale-report.component.ts index 303f208..03e4fa3 100644 --- a/bookie/src/app/product-sale-report/product-sale-report.component.ts +++ b/bookie/src/app/product-sale-report/product-sale-report.component.ts @@ -1,6 +1,6 @@ import { DecimalPipe } from '@angular/common'; import { Component, inject, computed, linkedSignal, input } from '@angular/core'; -import { form, FormField } from '@angular/forms/signals'; +import { form, FormField, FormRoot } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatDatepickerModule } from '@angular/material/datepicker'; import { MatFormFieldModule } from '@angular/material/form-field'; @@ -37,6 +37,7 @@ export interface ProductSaleReportFormData { MatSelectModule, MatTableModule, FormField, + FormRoot, ], }) export class ProductSaleReportComponent { diff --git a/bookie/src/app/product/product-detail/product-detail.component.html b/bookie/src/app/product/product-detail/product-detail.component.html index 4bcd12a..7341577 100644 --- a/bookie/src/app/product/product-detail/product-detail.component.html +++ b/bookie/src/app/product/product-detail/product-detail.component.html @@ -3,7 +3,7 @@
Name - + Fraction Units diff --git a/bookie/src/app/product/product-detail/product-detail.component.ts b/bookie/src/app/product/product-detail/product-detail.component.ts index 225b3e4..daca4e3 100644 --- a/bookie/src/app/product/product-detail/product-detail.component.ts +++ b/bookie/src/app/product/product-detail/product-detail.component.ts @@ -1,5 +1,5 @@ import { CurrencyPipe } from '@angular/common'; -import { AfterViewInit, Component, ElementRef, ViewChild, inject, computed, linkedSignal, input } from '@angular/core'; +import { Component, inject, computed, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField, required, min, max } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; @@ -57,8 +57,7 @@ export interface ProductDetailFormData { FormField, ], }) -export class ProductDetailComponent implements AfterViewInit { - @ViewChild('name', { static: true }) nameElement?: ElementRef; +export class ProductDetailComponent { private menuCategoryService = inject(MenuCategoryService); private saleCategoryService = inject(SaleCategoryService); private route = inject(ActivatedRoute); @@ -123,12 +122,10 @@ export class ProductDetailComponent implements AfterViewInit { 'action', ]; - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + constructor() { + afterNextRender(() => { + this.form().focusBoundControl(); + }); } addRow() { diff --git a/bookie/src/app/product/product.service.ts b/bookie/src/app/product/product.service.ts index a160247..28d9e6f 100644 --- a/bookie/src/app/product/product.service.ts +++ b/bookie/src/app/product/product.service.ts @@ -44,9 +44,9 @@ export class ProductService { }); } - query(query: Signal | string | null): HttpResourceRef { + query(query: Signal): HttpResourceRef { return httpResource(() => { - const qVal = typeof query === 'function' ? query() : query; + const qVal = query(); return `${url}/query?q=${qVal ?? ''}`; }); } diff --git a/bookie/src/app/regimes/regime-detail/regime-detail.component.html b/bookie/src/app/regimes/regime-detail/regime-detail.component.html index 99c81c5..1bfa513 100644 --- a/bookie/src/app/regimes/regime-detail/regime-detail.component.html +++ b/bookie/src/app/regimes/regime-detail/regime-detail.component.html @@ -3,7 +3,7 @@
Name - +
diff --git a/bookie/src/app/regimes/regime-detail/regime-detail.component.ts b/bookie/src/app/regimes/regime-detail/regime-detail.component.ts index 1f9689e..427cec4 100644 --- a/bookie/src/app/regimes/regime-detail/regime-detail.component.ts +++ b/bookie/src/app/regimes/regime-detail/regime-detail.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, ViewChild, computed, inject, linkedSignal, input } from '@angular/core'; +import { Component, computed, inject, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatDialog } from '@angular/material/dialog'; @@ -23,8 +23,7 @@ export interface RegimeDetailFormData { styleUrls: ['./regime-detail.component.css'], imports: [MatButtonModule, MatFormFieldModule, MatInputModule, FormField], }) -export class RegimeDetailComponent implements AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; +export class RegimeDetailComponent { private route = inject(ActivatedRoute); private router = inject(Router); private dialog = inject(MatDialog); @@ -48,12 +47,10 @@ export class RegimeDetailComponent implements AfterViewInit { form = form(this.formModel); - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + constructor() { + afterNextRender(() => { + this.form().focusBoundControl(); + }); } save() { diff --git a/bookie/src/app/roles/role-detail/role-detail.component.html b/bookie/src/app/roles/role-detail/role-detail.component.html index 4784fa9..c365902 100644 --- a/bookie/src/app/roles/role-detail/role-detail.component.html +++ b/bookie/src/app/roles/role-detail/role-detail.component.html @@ -3,7 +3,7 @@
Name - +
diff --git a/bookie/src/app/roles/role-detail/role-detail.component.ts b/bookie/src/app/roles/role-detail/role-detail.component.ts index 045757b..20e4d2e 100644 --- a/bookie/src/app/roles/role-detail/role-detail.component.ts +++ b/bookie/src/app/roles/role-detail/role-detail.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, ViewChild, computed, inject, linkedSignal, input } from '@angular/core'; +import { Component, computed, inject, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; @@ -24,8 +24,7 @@ export interface RoleDetailFormData { styleUrls: ['./role-detail.component.css'], imports: [MatButtonModule, MatCheckboxModule, MatFormFieldModule, MatInputModule, FormField], }) -export class RoleDetailComponent implements AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; +export class RoleDetailComponent { private route = inject(ActivatedRoute); private router = inject(Router); private snackBar = inject(MatSnackBar); @@ -60,12 +59,10 @@ export class RoleDetailComponent implements AfterViewInit { return implied; }); - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + constructor() { + afterNextRender(() => { + this.form().focusBoundControl(); + }); } save() { diff --git a/bookie/src/app/sale-category/sale-category-detail/sale-category-detail.component.html b/bookie/src/app/sale-category/sale-category-detail/sale-category-detail.component.html index 99bb478..7b093b3 100644 --- a/bookie/src/app/sale-category/sale-category-detail/sale-category-detail.component.html +++ b/bookie/src/app/sale-category/sale-category-detail/sale-category-detail.component.html @@ -3,7 +3,7 @@
Name - +
diff --git a/bookie/src/app/sale-category/sale-category-detail/sale-category-detail.component.ts b/bookie/src/app/sale-category/sale-category-detail/sale-category-detail.component.ts index 0a8796b..9f1f33e 100644 --- a/bookie/src/app/sale-category/sale-category-detail/sale-category-detail.component.ts +++ b/bookie/src/app/sale-category/sale-category-detail/sale-category-detail.component.ts @@ -1,5 +1,5 @@ import { CurrencyPipe } from '@angular/common'; -import { AfterViewInit, Component, ElementRef, ViewChild, inject, computed, linkedSignal, input } from '@angular/core'; +import { Component, inject, computed, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatOptionModule } from '@angular/material/core'; @@ -43,8 +43,7 @@ export interface SaleCategoryDetailFormData { RouterLink, ], }) -export class SaleCategoryDetailComponent implements AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; +export class SaleCategoryDetailComponent { private taxService = inject(TaxService); private productService = inject(ProductService); private route = inject(ActivatedRoute); @@ -80,12 +79,10 @@ export class SaleCategoryDetailComponent implements AfterViewInit { dataSource = computed(() => this.products()); displayedColumns = ['name', 'price', 'menuCategory']; - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + constructor() { + afterNextRender(() => { + this.form().focusBoundControl(); + }); } save() { diff --git a/bookie/src/app/sale-category/sale-category-list/sale-category-list.component.ts b/bookie/src/app/sale-category/sale-category-list/sale-category-list.component.ts index 97417d0..103ba1b 100644 --- a/bookie/src/app/sale-category/sale-category-list/sale-category-list.component.ts +++ b/bookie/src/app/sale-category/sale-category-list/sale-category-list.component.ts @@ -20,7 +20,6 @@ export class SaleCategoryListComponent { private ser = inject(SaleCategoryService); listResource = this.ser.list(); - // @ViewChild('table', { static: true }) table?: MatTable; dataSource = computed(() => this.listResource.value() ?? []); /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ diff --git a/bookie/src/app/sales/reason/reason.component.ts b/bookie/src/app/sales/reason/reason.component.ts index b6f5c5d..72cf15b 100644 --- a/bookie/src/app/sales/reason/reason.component.ts +++ b/bookie/src/app/sales/reason/reason.component.ts @@ -1,5 +1,5 @@ import { CdkScrollableModule } from '@angular/cdk/scrolling'; -import { Component, ElementRef, ViewChild, inject, computed, signal } from '@angular/core'; +import { Component, inject, computed, signal } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MAT_DIALOG_DATA, MatDialogRef, MatDialogModule } from '@angular/material/dialog'; @@ -26,7 +26,6 @@ export interface ReasonFormData { ], }) export class ReasonComponent { - @ViewChild('son', { static: true }) son?: ElementRef; dialogRef = inject>(MatDialogRef); private data = inject<{ title: string; diff --git a/bookie/src/app/sales/receive-payment/receive-payment.component.ts b/bookie/src/app/sales/receive-payment/receive-payment.component.ts index b54e099..a0fc0de 100644 --- a/bookie/src/app/sales/receive-payment/receive-payment.component.ts +++ b/bookie/src/app/sales/receive-payment/receive-payment.component.ts @@ -1,6 +1,6 @@ import { CdkScrollableModule } from '@angular/cdk/scrolling'; import { CurrencyPipe } from '@angular/common'; -import { Component, ElementRef, ViewChild, inject, signal, computed } from '@angular/core'; +import { Component, inject, signal, computed } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MAT_DIALOG_DATA, MatDialogRef, MatDialogModule } from '@angular/material/dialog'; @@ -38,7 +38,6 @@ export interface ReceivePaymentFormData { ], }) export class ReceivePaymentComponent { - @ViewChild('son', { static: true }) son?: ElementRef; private ser = inject(SettleOptionService); dialogRef = inject>(MatDialogRef); data = inject<{ diff --git a/bookie/src/app/section-printers/section-printer.component.ts b/bookie/src/app/section-printers/section-printer.component.ts index 0f5b834..7ff314c 100644 --- a/bookie/src/app/section-printers/section-printer.component.ts +++ b/bookie/src/app/section-printers/section-printer.component.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef, ViewChild, computed, inject, linkedSignal, input } from '@angular/core'; +import { Component, computed, inject, linkedSignal, input } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatOptionModule } from '@angular/material/core'; @@ -43,7 +43,6 @@ export interface SectionPrinterFormData { ], }) export class SectionPrinterComponent { - @ViewChild('section', { static: true }) sectionElement?: ElementRef; private printerService = inject(PrinterService); private sectionService = inject(SectionService); private route = inject(ActivatedRoute); diff --git a/bookie/src/app/sections/section-detail/section-detail.component.html b/bookie/src/app/sections/section-detail/section-detail.component.html index 8032256..4ba3097 100644 --- a/bookie/src/app/sections/section-detail/section-detail.component.html +++ b/bookie/src/app/sections/section-detail/section-detail.component.html @@ -3,7 +3,7 @@
Name - +
diff --git a/bookie/src/app/sections/section-detail/section-detail.component.ts b/bookie/src/app/sections/section-detail/section-detail.component.ts index 9529ca7..98ded58 100644 --- a/bookie/src/app/sections/section-detail/section-detail.component.ts +++ b/bookie/src/app/sections/section-detail/section-detail.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, ViewChild, computed, inject, linkedSignal, input } from '@angular/core'; +import { Component, computed, inject, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatDialog } from '@angular/material/dialog'; @@ -21,8 +21,7 @@ export interface SectionDetailFormData { styleUrls: ['./section-detail.component.css'], imports: [MatButtonModule, MatFormFieldModule, MatInputModule, FormField], }) -export class SectionDetailComponent implements AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; +export class SectionDetailComponent { private route = inject(ActivatedRoute); private router = inject(Router); private dialog = inject(MatDialog); @@ -44,12 +43,10 @@ export class SectionDetailComponent implements AfterViewInit { form = form(this.formModel); - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + constructor() { + afterNextRender(() => { + this.form().focusBoundControl(); + }); } save() { diff --git a/bookie/src/app/settle-option/settle-option-detail/settle-option-detail.component.html b/bookie/src/app/settle-option/settle-option-detail/settle-option-detail.component.html index 7c47ad8..d40ad10 100644 --- a/bookie/src/app/settle-option/settle-option-detail/settle-option-detail.component.html +++ b/bookie/src/app/settle-option/settle-option-detail/settle-option-detail.component.html @@ -3,7 +3,7 @@
Name - +
diff --git a/bookie/src/app/settle-option/settle-option-detail/settle-option-detail.component.ts b/bookie/src/app/settle-option/settle-option-detail/settle-option-detail.component.ts index 569135e..559d959 100644 --- a/bookie/src/app/settle-option/settle-option-detail/settle-option-detail.component.ts +++ b/bookie/src/app/settle-option/settle-option-detail/settle-option-detail.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, ViewChild, computed, inject, linkedSignal, input } from '@angular/core'; +import { Component, computed, inject, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; @@ -37,8 +37,7 @@ export interface SettleOptionDetailFormData { FormField, ], }) -export class SettleOptionDetailComponent implements AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; +export class SettleOptionDetailComponent { private route = inject(ActivatedRoute); private router = inject(Router); private dialog = inject(MatDialog); @@ -73,14 +72,9 @@ export class SettleOptionDetailComponent implements AfterViewInit { this.reportingLevel = Object.keys(ReportingLevel) .filter((e) => !isNaN(+e)) .map((o) => ({ id: +o, name: ReportingLevel[+o] as string })); - } - - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + afterNextRender(() => { + this.form().focusBoundControl(); + }); } save() { diff --git a/bookie/src/app/tables/table-detail/table-detail.component.html b/bookie/src/app/tables/table-detail/table-detail.component.html index b93f337..be7795b 100644 --- a/bookie/src/app/tables/table-detail/table-detail.component.html +++ b/bookie/src/app/tables/table-detail/table-detail.component.html @@ -3,7 +3,7 @@
Name - +
diff --git a/bookie/src/app/tables/table-detail/table-detail.component.ts b/bookie/src/app/tables/table-detail/table-detail.component.ts index 95abafb..052acfd 100644 --- a/bookie/src/app/tables/table-detail/table-detail.component.ts +++ b/bookie/src/app/tables/table-detail/table-detail.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, ViewChild, computed, inject, linkedSignal, input } from '@angular/core'; +import { Component, computed, inject, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; @@ -37,8 +37,7 @@ export interface TableDetailFormData { FormField, ], }) -export class TableDetailComponent implements AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; +export class TableDetailComponent { private sectionService = inject(SectionService); private route = inject(ActivatedRoute); private router = inject(Router); @@ -68,12 +67,10 @@ export class TableDetailComponent implements AfterViewInit { sections = computed(() => this.sectionsResource.value() ?? []); - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + constructor() { + afterNextRender(() => { + this.form().focusBoundControl(); + }); } save() { diff --git a/bookie/src/app/taxes/tax-detail/tax-detail.component.html b/bookie/src/app/taxes/tax-detail/tax-detail.component.html index 74f92ec..644738f 100644 --- a/bookie/src/app/taxes/tax-detail/tax-detail.component.html +++ b/bookie/src/app/taxes/tax-detail/tax-detail.component.html @@ -3,7 +3,7 @@
Name - + Format for GST: ST GST @ x% (1/2) ; CGST @ x% (1/2)
diff --git a/bookie/src/app/taxes/tax-detail/tax-detail.component.ts b/bookie/src/app/taxes/tax-detail/tax-detail.component.ts index fae8b77..65b1232 100644 --- a/bookie/src/app/taxes/tax-detail/tax-detail.component.ts +++ b/bookie/src/app/taxes/tax-detail/tax-detail.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, ViewChild, computed, inject, linkedSignal, input } from '@angular/core'; +import { Component, computed, inject, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatOptionModule } from '@angular/material/core'; @@ -28,8 +28,7 @@ export interface TaxDetailFormData { styleUrls: ['./tax-detail.component.css'], imports: [MatButtonModule, MatFormFieldModule, MatInputModule, MatOptionModule, MatSelectModule, FormField], }) -export class TaxDetailComponent implements AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; +export class TaxDetailComponent { private regimeService = inject(RegimeService); private route = inject(ActivatedRoute); private router = inject(Router); @@ -58,12 +57,10 @@ export class TaxDetailComponent implements AfterViewInit { regimes = computed(() => this.regimesResource.value() ?? []); - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + constructor() { + afterNextRender(() => { + this.form().focusBoundControl(); + }); } save() { diff --git a/bookie/src/app/temporal-product/temporal-product-detail/temporal-product-detail.component.html b/bookie/src/app/temporal-product/temporal-product-detail/temporal-product-detail.component.html index f94fdbc..db5a769 100644 --- a/bookie/src/app/temporal-product/temporal-product-detail/temporal-product-detail.component.html +++ b/bookie/src/app/temporal-product/temporal-product-detail/temporal-product-detail.component.html @@ -6,7 +6,7 @@
Name - + Fraction Units diff --git a/bookie/src/app/temporal-product/temporal-product-detail/temporal-product-detail.component.ts b/bookie/src/app/temporal-product/temporal-product-detail/temporal-product-detail.component.ts index 7d35b4e..91b24f7 100644 --- a/bookie/src/app/temporal-product/temporal-product-detail/temporal-product-detail.component.ts +++ b/bookie/src/app/temporal-product/temporal-product-detail/temporal-product-detail.component.ts @@ -1,14 +1,4 @@ -import { - AfterViewInit, - Component, - ElementRef, - ViewChild, - computed, - inject, - signal, - linkedSignal, - input, -} from '@angular/core'; +import { Component, computed, inject, signal, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; @@ -74,8 +64,7 @@ export interface TemporalSkuFormData { FormField, ], }) -export class TemporalProductDetailComponent implements AfterViewInit { - @ViewChild('name', { static: true }) nameElement?: ElementRef; +export class TemporalProductDetailComponent { private menuCategoryService = inject(MenuCategoryService); private saleCategoryService = inject(SaleCategoryService); private route = inject(ActivatedRoute); @@ -175,12 +164,10 @@ export class TemporalProductDetailComponent implements AfterViewInit { // // // } - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + constructor() { + afterNextRender(() => { + this.productForm().focusBoundControl(); + }); } editProduct(p: Product) { @@ -188,7 +175,7 @@ export class TemporalProductDetailComponent implements AfterViewInit { console.log(p); - setTimeout(() => this.nameElement?.nativeElement?.focus?.(), 0); + this.productForm().focusBoundControl(); } updateProduct() { diff --git a/bookie/src/app/users/user-detail/user-detail.component.html b/bookie/src/app/users/user-detail/user-detail.component.html index 81390d7..b764eb7 100644 --- a/bookie/src/app/users/user-detail/user-detail.component.html +++ b/bookie/src/app/users/user-detail/user-detail.component.html @@ -3,7 +3,7 @@
Name - +
diff --git a/bookie/src/app/users/user-detail/user-detail.component.ts b/bookie/src/app/users/user-detail/user-detail.component.ts index 595069b..2905693 100644 --- a/bookie/src/app/users/user-detail/user-detail.component.ts +++ b/bookie/src/app/users/user-detail/user-detail.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, ViewChild, computed, inject, linkedSignal, input } from '@angular/core'; +import { Component, computed, inject, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; @@ -35,8 +35,7 @@ export interface UserDetailFormData { FormField, ], }) -export class UserDetailComponent implements AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; +export class UserDetailComponent { private route = inject(ActivatedRoute); private router = inject(Router); private snackBar = inject(MatSnackBar); @@ -64,15 +63,10 @@ export class UserDetailComponent implements AfterViewInit { hide = true; constructor() { - this.hide = true; - } - - ngAfterViewInit() { - setTimeout(() => { - if (this.nameElement !== undefined) { - this.nameElement.nativeElement.focus(); - } - }, 0); + afterNextRender(() => { + this.form().focusBoundControl(); + // this.formModel().root.focus("name"); + }); } save() { diff --git a/bookie/yarn.lock b/bookie/yarn.lock index d4c497c..9d3dc80 100644 --- a/bookie/yarn.lock +++ b/bookie/yarn.lock @@ -10,18 +10,18 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" -"@angular-devkit/architect@0.2201.3", "@angular-devkit/architect@>= 0.2200.0 < 0.2300.0": - version "0.2201.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.2201.3.tgz#c885e6d229db2cb4d34295899a8e47d277421d00" - integrity sha512-5WX6rooTQZCh+yE9k3O5hc7nnQtzy1nw6fQpaTuCzIgPG8teQuVtdxegBsM3OcjJac1r+qJLo+KmTRfnqcfsyg== +"@angular-devkit/architect@0.2201.4", "@angular-devkit/architect@>= 0.2200.0 < 0.2300.0": + version "0.2201.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.2201.4.tgz#55784db27897aaeaed48b1d93fce1a0007542a62" + integrity sha512-a2J9hdBYFobhMx9G0KwCdo6+LrWIOOyIeijrA/QSZiPOjg8dAprhMh7BEQkF3eT6R1q7wDGP+IElVR9LsBlXQw== dependencies: - "@angular-devkit/core" "22.1.3" + "@angular-devkit/core" "22.1.4" rxjs "7.8.2" -"@angular-devkit/core@22.1.3", "@angular-devkit/core@>= 22.0.0 < 23.0.0": - version "22.1.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-22.1.3.tgz#460714465203f95c7c92054de46647515021f8f8" - integrity sha512-ASK8oZVElt/Zpz5FrzJjLnnUbzp/fW57eFFSRgpA+n9KRnuFi6YvNdSS3HkG5049Jcukce+PiMBdfzw/jBVkEw== +"@angular-devkit/core@22.1.4", "@angular-devkit/core@>= 22.0.0 < 23.0.0": + version "22.1.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-22.1.4.tgz#ac3401d204e761e7cb7f22f02d31bc9cf5d1e161" + integrity sha512-40jG/6chng9fQuWtpg1kadPO17sRTurNh0aav6Uxebn65PfNpTpvhPIYVIcRgv4tCKdMd++YH95A8SiaIOwqig== dependencies: ajv "8.20.0" ajv-formats "3.0.1" @@ -30,12 +30,12 @@ rxjs "7.8.2" source-map "0.7.6" -"@angular-devkit/schematics@22.1.3", "@angular-devkit/schematics@>= 22.0.0 < 23.0.0": - version "22.1.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-22.1.3.tgz#4cd8083a395470a1b58e2456af1ebef985a99d96" - integrity sha512-ebY5bwZVB0onxxyTbJch//VidVVV8jo/F13n+TV5s/3ZywsC3/XZsfMHaxlFmpvP/G17+/C9JVoEXT+uwjT+/Q== +"@angular-devkit/schematics@22.1.4", "@angular-devkit/schematics@>= 22.0.0 < 23.0.0": + version "22.1.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-22.1.4.tgz#087ef5b69e3d52d458d44fb0738584f53badef41" + integrity sha512-UBJ7jc7B0vRfmrVwlvpmuudo1D7AfpO6ugf1BxvkM4sw5m8cJpZtaIJFKBorv0QZo78CyDOroQfQdXaijjB2ZA== dependencies: - "@angular-devkit/core" "22.1.3" + "@angular-devkit/core" "22.1.4" jsonc-parser "3.3.1" magic-string "1.0.0" ora "9.4.1" @@ -102,12 +102,12 @@ "@angular-eslint/bundled-angular-compiler" "22.1.0" "@angular/build@^22.1.3": - version "22.1.3" - resolved "https://registry.yarnpkg.com/@angular/build/-/build-22.1.3.tgz#31277362e8caabeb53ba0cf81114ff0b2e873022" - integrity sha512-Hjen3LcVZUCNZy+epgO+/PMUpD/L8Y4vODS+Q8F0Lkva7YWQwycbJtrEr6xvFfMxp6xexxxIwB9+5b8voKSihQ== + version "22.1.4" + resolved "https://registry.yarnpkg.com/@angular/build/-/build-22.1.4.tgz#99fff97ee69d1bd912fc901e335f60dc06a7576b" + integrity sha512-y5wxiyUu1DjYNG5jiFjjgFp7O5bkyYjWzy2kfyTGq+DjKMEveTzNH3tBkZrE33EJ4wYyfx+rQ01IG9nZbhfdvA== dependencies: "@ampproject/remapping" "2.3.0" - "@angular-devkit/architect" "0.2201.3" + "@angular-devkit/architect" "0.2201.4" "@babel/core" "8.0.1" "@babel/helper-annotate-as-pure" "8.0.0" "@babel/helper-split-export-declaration" "7.24.7" @@ -115,7 +115,7 @@ "@vitejs/plugin-basic-ssl" "2.3.0" beasties "0.4.3" browserslist "^4.26.0" - esbuild "0.28.1" + esbuild "0.28.2" https-proxy-agent "9.1.0" jsonc-parser "3.3.1" listr2 "10.2.2" @@ -136,44 +136,44 @@ lmdb "3.5.6" "@angular/cdk@^22.1.1": - version "22.1.1" - resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-22.1.1.tgz#1cd02f6831f30324171eb575e1875d278c62c689" - integrity sha512-P8YuW/r5MS8aeKF0NruktKGHQShOMctvhs3H/51BOwJrMZi5qtWJ40t1yqTrNnewSJIKI0/AroUEmEOqA9Ml9Q== + version "22.1.2" + resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-22.1.2.tgz#660037c01a024584eb26269e1062421860f5ffb8" + integrity sha512-YwTzVnTgZIQDLq3lnnPLINIB24e0SiDn7XxBxHSrOzD/+Y0zLAid5XIiMALXWOqa7rfdhfVh1kEeM93RRLnllQ== dependencies: parse5 "^8.0.0" tslib "^2.3.0" "@angular/cli@^22.1.3": - version "22.1.3" - resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-22.1.3.tgz#0a0647abfe30ab9c76990e93f5e8d15bb9b78f9d" - integrity sha512-GB1Pv8CXAHXE2/hqiwSGD6JRIyT4wswadjH1j3DH2+6os1zc7CBm28/YtlKPPIHZKVOZLDqV6uW+bRQTtdOw2A== + version "22.1.4" + resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-22.1.4.tgz#2d143bb4eed672efa2b69c1ade9fd0215b4ecc72" + integrity sha512-Yt6q7a1vXh0ICFHnRdUOmx/gEXZ87zpkvE1eUWREUqeQ3ARkwqNZVzF3IP+s9NpDDrnc+EB9cqel9SnGZ/0z2Q== dependencies: - "@angular-devkit/architect" "0.2201.3" - "@angular-devkit/core" "22.1.3" - "@angular-devkit/schematics" "22.1.3" + "@angular-devkit/architect" "0.2201.4" + "@angular-devkit/core" "22.1.4" + "@angular-devkit/schematics" "22.1.4" "@inquirer/prompts" "8.5.2" "@listr2/prompt-adapter-inquirer" "4.2.4" - "@modelcontextprotocol/sdk" "1.29.0" - "@schematics/angular" "22.1.3" + "@modelcontextprotocol/sdk" "1.30.0" + "@schematics/angular" "22.1.4" jsonc-parser "3.3.1" listr2 "10.2.2" npm-package-arg "14.0.0" parse5-html-rewriting-stream "8.0.1" semver "7.8.5" - yargs "18.0.0" + yargs "18.1.0" zod "4.4.3" "@angular/common@^22.1.1": - version "22.1.1" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-22.1.1.tgz#b061ad0b07bf6a74e8dec62b28f4cf717cb7a79c" - integrity sha512-5iiyPWqO3acpOPMcJWYtVbXF5z9wy43MFQQdd7wZPHfYOIC7c3KRnziWrRpELae+SkEB4srAYr6XIu9rQ743nw== + version "22.1.2" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-22.1.2.tgz#da972b75818a8985bc464f39b0ceb1e14997e189" + integrity sha512-8TzyYPBDvSItV8Vqq8k5u8a9fWaomC9bMEr8z1vVLRZDIPhNQ/UcCyuTYbC7GZkeqrrKGu5m8tjUrA09RCwuaQ== dependencies: tslib "^2.3.0" "@angular/compiler-cli@^22.1.1": - version "22.1.1" - resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-22.1.1.tgz#6d64294f8bdb32b40f5e6b085ad0ded1d9e53d5b" - integrity sha512-GLcwWqUg4i2eru3nKy989Me7483+ZPofnwgw9aMc96MWl8y8CD9CTrSff+fwh2/crUsQIqGg/uehIZRjISMD0A== + version "22.1.2" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-22.1.2.tgz#eb9d27221decdf25cc39bc3d2bc5acc8f29b4c41" + integrity sha512-GWRtvQQz/LvKejF/Zpls+hGnnJkvaPPtd3TZnxfZQ1fYCs7b7gpi0YM9PP02TJz51vhlsgkPYJwgtJAKDJEHNQ== dependencies: "@babel/core" "8.0.1" "@jridgewell/sourcemap-codec" "^1.4.14" @@ -185,53 +185,53 @@ yargs "^18.0.0" "@angular/compiler@^22.1.1": - version "22.1.1" - resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-22.1.1.tgz#9743248279c5769d1ba0d866fb674ffb0744f9b7" - integrity sha512-UfQZALwewk+WyE5fqrXT3CK0sxWXre4XojAvUdFQSZsVHTZEM1QD4FncuePa44I6BQMhfqQUvYNlqFnev4WOQg== + version "22.1.2" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-22.1.2.tgz#e57b92326ff025ede2d372195177a601a72cc83f" + integrity sha512-aQv0p5MeXuguCeftUUxK4H8Hbw1hC5Zyu+cFsGbsi025LZ9Ngw+BW+iUHDQZAcqHvWDw2wgGOdKh4e7IkcfRyQ== dependencies: tslib "^2.3.0" "@angular/core@^22.1.1": - version "22.1.1" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-22.1.1.tgz#3bdae393c3c977596b60fb5b19c9e35b7ea3cdce" - integrity sha512-QFZNFzyFw9l1B1D7NCEU3YiLLBnMSejyp9mzJrzZ9vzc70BsewikcLFwuj+qqleqFmi5VW3f9GFNgwUq8dWGAg== + version "22.1.2" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-22.1.2.tgz#bfaa88718aac9ec195014ee80807cdd71ba6af0e" + integrity sha512-t7BrgfdeqbdSbFe3CsGX8ySMeKDlZNBPxFMCOanAAqd6W0H1Kh1WFILBs3DIg0NfjpybfSRJAzKcagOFQWNtiw== dependencies: tslib "^2.3.0" "@angular/forms@^22.1.1": - version "22.1.1" - resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-22.1.1.tgz#daacbc654285e7b4b1ad3bfca4a23878e5976144" - integrity sha512-6c5IJaCw6hAsBYl+LeQARwV4eGxfHwHTlTWfCB5dOYjMSgCCjaivkNTCUepYXFo5Fkdvw1qDiWIpAfgusAxmww== + version "22.1.2" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-22.1.2.tgz#4ba15aec5c11c9d80107881b34930a8252aea125" + integrity sha512-pKDYSNKje/jox74KzswBdX4sL7kJ8OFkJwLnqng8oc7a/NVl/Vf4/Xq4kyowRAdtPcZfLTUnZG6s0qbegfV5mg== dependencies: "@standard-schema/spec" "^1.0.0" tslib "^2.3.0" zod "^4.0.10" "@angular/material-moment-adapter@^22.1.1": - version "22.1.1" - resolved "https://registry.yarnpkg.com/@angular/material-moment-adapter/-/material-moment-adapter-22.1.1.tgz#91f445960442408e4d03b3a9cc3b0bf8b8acb0ae" - integrity sha512-nTxGXXs97zwv5o6dd+Go3IsDoY3I8G4Z6K8EKa8CpWH9Z+yL/P1zsy6q5Wo3g5naIQr/XETexKBMgihZBxe3mg== + version "22.1.2" + resolved "https://registry.yarnpkg.com/@angular/material-moment-adapter/-/material-moment-adapter-22.1.2.tgz#7d3901323311ef572186d37a9c5963bae9dedb82" + integrity sha512-huMm6Ev7UlVJYMie6VmkP0/Xkk+8HnoCJXblfLM0untw+7YDVTQKnft0SHCBjgjlqU6SAlOr27U2MqjBTz6/DQ== dependencies: tslib "^2.3.0" "@angular/material@^22.1.1": - version "22.1.1" - resolved "https://registry.yarnpkg.com/@angular/material/-/material-22.1.1.tgz#611eb06eb36a20b52fa4100a6b2b193c751de92e" - integrity sha512-wXNNstkLrUJwmP/cZl+C64chL5qH0WbnHIeYbiXrPwgriAD10prbVBoSq2CWbBrAhQ691pDdFKVSLG5tC224jg== + version "22.1.2" + resolved "https://registry.yarnpkg.com/@angular/material/-/material-22.1.2.tgz#18439da01958a4fae93364b133e58c1a49c05d46" + integrity sha512-KX0bVUppfwjDfUepsjpG1CAQGUGHI0l5e0QYpFcskB+1wNRCocBGsIO1br5z6neYu0rzsbhtWocjCeH05gwi7w== dependencies: tslib "^2.3.0" "@angular/platform-browser@^22.1.1": - version "22.1.1" - resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-22.1.1.tgz#7fca2545d5f23a2dccc1ed8ef02c895921adb496" - integrity sha512-u1HMINw++YTUzMbJB9zVhqch1iEiEl5vA88HjZYzoDagBcnIev30GRWI+QEy4Dy9GRg64hrCOl9Fke78dLQgYQ== + version "22.1.2" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-22.1.2.tgz#0026cf8d0222dc63de306b1cac0bee1a383568d2" + integrity sha512-MQO735ve/tk4gLsWbw8NyBD/DxPfbbmf1pM/vp6K7tZz2xyysMXilqF/k8PBdQBZVOofST8S13inZHQ35nHuRA== dependencies: tslib "^2.3.0" "@angular/router@^22.1.1": - version "22.1.1" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-22.1.1.tgz#40a112823c402519cbb47c6d0d038a1d90aee21e" - integrity sha512-sD+dN+UOAhdrqnOp3OWuR+O50msXFt+16OGL6RrM9af40iATkUbEAgU62N4KITKl4ACDisg8yhyb9J3dwCEyzQ== + version "22.1.2" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-22.1.2.tgz#7f89569d73b7450b747800c86d3c9caedd1c2a13" + integrity sha512-C2c6NJ9HZUfb1L07M554Zpgvi0TvpOBO6Og9L36v/jsv42m7tpOenvqQVPa8R3va7eqLEszCL7wLFcWeJ8naew== dependencies: tslib "^2.3.0" @@ -441,135 +441,135 @@ dependencies: tslib "^2.4.0" -"@esbuild/aix-ppc64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz#7a01a8d2ec2fbb2dac78adad09b0fa781e4082be" - integrity sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ== +"@esbuild/aix-ppc64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz#bf6e10303bcf2e7c686975fa52f937ec2728d8bc" + integrity sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ== -"@esbuild/android-arm64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz#b540a27d14e4afd058496a4dbec4d3f414db110a" - integrity sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg== +"@esbuild/android-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz#0c6246bc8d2c4d172aac2db3fb1190d72bd65504" + integrity sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A== -"@esbuild/android-arm@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.28.1.tgz#704bd297de6d762de54eabbeafbf55f6756abe2f" - integrity sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ== +"@esbuild/android-arm@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.28.2.tgz#2d84ece6a4e2684d92be26ee13d42757d831c381" + integrity sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg== -"@esbuild/android-x64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.28.1.tgz#d1cb166d34b0fbf0fe8ab460a5594f24a378701e" - integrity sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng== +"@esbuild/android-x64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.28.2.tgz#fc38d4d6358d8dc1cf53f09f7589fe436eb64801" + integrity sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q== -"@esbuild/darwin-arm64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz#1034b26457fc886368fe61bbd09f653f6afa8e54" - integrity sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q== +"@esbuild/darwin-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz#f83afeeac1d7dac01c7a2fd012b3e451a0591fcc" + integrity sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw== -"@esbuild/darwin-x64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz#65556a432a1e4d72032d8218c1932fcca1a49772" - integrity sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ== +"@esbuild/darwin-x64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz#510147c055a795588dbbe14fd6b1b8ad0a2f30de" + integrity sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw== -"@esbuild/freebsd-arm64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz#2e61e0592f9030d7e3dae18ee25ebc535918aef6" - integrity sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw== +"@esbuild/freebsd-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz#093b9200ecf0b115ba4e5e248a7485c9c5f8bd5e" + integrity sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw== -"@esbuild/freebsd-x64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz#c95ec289959ef8079c4dca817a1e2c4be66b9bd3" - integrity sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ== +"@esbuild/freebsd-x64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz#0be22b6df925d213e841ea87123af5df80b0faf7" + integrity sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg== -"@esbuild/linux-arm64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz#40b22175dda06182f3ee8141186c5ff304c4a717" - integrity sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g== +"@esbuild/linux-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz#1bdbc651cda9ba9995c53ed9c71ceaa65094762d" + integrity sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug== -"@esbuild/linux-arm@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz#c09a0f67917592ac0de892a9be4d3814debd2a6c" - integrity sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ== +"@esbuild/linux-arm@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz#beb12ad72b84f72d28488cc1b8ee9f7eb141d753" + integrity sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w== -"@esbuild/linux-ia32@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz#a580f9c676797833891e519fc7a1337c8afd8db3" - integrity sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w== +"@esbuild/linux-ia32@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz#b81f9d55529b45c206a46a138214b1aa6879696b" + integrity sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ== -"@esbuild/linux-loong64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz#46452cf321dc7f9e91c2fa780a56bb56e79cd68b" - integrity sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg== +"@esbuild/linux-loong64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz#598667241a04c99b76ed6ef940ac50038c419f98" + integrity sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ== -"@esbuild/linux-mips64el@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz#4211b3184dd6608f53dcb22e39f5d34ee08852c8" - integrity sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ== +"@esbuild/linux-mips64el@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz#1c51eb9cea903f53d97b5af3b1841db70f5596ca" + integrity sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA== -"@esbuild/linux-ppc64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz#697857c2a61cb9b0b6bb6652e40c1dc5e1ca8e5d" - integrity sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ== +"@esbuild/linux-ppc64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz#63dd61f17ceb31a81227f413feac8a71bc2c51f2" + integrity sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ== -"@esbuild/linux-riscv64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz#d192943eb146a40ac4c6497d0cf7be35b986bf08" - integrity sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ== +"@esbuild/linux-riscv64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz#3763b08fde5cf25ab1facb8e7752edfe45fbfc27" + integrity sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA== -"@esbuild/linux-s390x@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz#acea0356da0e0ebc08f97cf7b9c2e401e1e648dc" - integrity sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag== +"@esbuild/linux-s390x@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz#1a137ff293a82906eb3176385bd7e8e0e5cfb7cb" + integrity sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg== -"@esbuild/linux-x64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz#6f0c3ce0cb64c534b70c4c45ecb2c16d34e35dfd" - integrity sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA== +"@esbuild/linux-x64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz#268b36211c146ca54f8fe12c578a8d6ef8979485" + integrity sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ== -"@esbuild/netbsd-arm64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz#8bcd77077a0dce3378b574fedb26d2a253b73d36" - integrity sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw== +"@esbuild/netbsd-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz#22571ad951d62bb6accc82d8d1fad5c8c1ac0ba1" + integrity sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw== -"@esbuild/netbsd-x64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz#e7fb2a01e99c830c94e6623cd9fefb4c8fb58347" - integrity sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg== +"@esbuild/netbsd-x64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz#42fcc57297eb0a0ca3f5fc475291f4c1a3f7c0de" + integrity sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw== -"@esbuild/openbsd-arm64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz#c52909372db8b86e2c55e05a8940033b5660a3b2" - integrity sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q== +"@esbuild/openbsd-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz#9eb32af104ac3dacf4edca01f596664aab0c73ef" + integrity sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ== -"@esbuild/openbsd-x64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz#c427b9be5a64c262ff9a7eb70b5fbbaadf446c6c" - integrity sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw== +"@esbuild/openbsd-x64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz#febed2402d6088225e91f20fb4ce2522ad0a4efd" + integrity sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw== -"@esbuild/openharmony-arm64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz#dc9b147baca2e6c4b3c85571741ef4860a489097" - integrity sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg== +"@esbuild/openharmony-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz#85641c3d466428bfbccea5f21c26836663fef5ce" + integrity sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q== -"@esbuild/sunos-x64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz#ce866d12df13c15e4c99f073a3d466f6e0649b3a" - integrity sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ== +"@esbuild/sunos-x64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz#a736f9d8962481045fc4c3e54f5479f22c870fb4" + integrity sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g== -"@esbuild/win32-arm64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz#7468e3692d01d629d5941e5d83817bb80f9e39b4" - integrity sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA== +"@esbuild/win32-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz#ee5ab40fad186201b652a33f8a5eb149e9e42532" + integrity sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ== -"@esbuild/win32-ia32@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz#a5bc0063fb2bcab6d0ed63f2a1537958bc269ec6" - integrity sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg== +"@esbuild/win32-ia32@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz#c40d28a6d99a127da6711f2afd74b11cb63b06a7" + integrity sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA== -"@esbuild/win32-x64@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz#10064ee44f4347b90c9a02b446bbf80a91632b12" - integrity sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A== +"@esbuild/win32-x64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz#b21affb804cc167c133d95f45b3a1dc1323b9a87" + integrity sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g== "@eslint-community/eslint-utils@^4.8.0", "@eslint-community/eslint-utils@^4.9.1": version "4.10.1" @@ -629,10 +629,10 @@ resolved "https://registry.yarnpkg.com/@harperfast/extended-iterable/-/extended-iterable-1.0.3.tgz#471489c5058331017e821bf6c33de70fc2c073ee" integrity sha512-sSAYhQca3rDWtQUHSAPeO7axFIUJOI6hn1gjRC5APVE1a90tuyT8f5WIgRsFhhWA7htNkju2veB9eWL6YHi/Lw== -"@hono/node-server@^1.19.9": - version "1.19.17" - resolved "https://registry.yarnpkg.com/@hono/node-server/-/node-server-1.19.17.tgz#99bd8625cdbae82652a135c71363cd6322fae483" - integrity sha512-dSneS5qhiauZWGDCeK4o695Xd9nUNjviSZCMQrj10eetr8Uln1ucn6bbphOM6UynAMMtNIzZNSpL9vnASJwrPQ== +"@hono/node-server@^1.19.9 || ^2.0.5": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@hono/node-server/-/node-server-2.1.1.tgz#9cfa8649e9ecbcd48edf505b103002402ea51e70" + integrity sha512-ELuehkj5VCBdgEw9zs+ivkKwyzzUCSQuE96YmiPvn1ECBoZCczbFXJLeEGMTYjphP6gydh4pHMqEYPVMYUVgQg== "@humanfs/core@^0.19.2": version "0.19.2" @@ -877,12 +877,12 @@ resolved "https://registry.yarnpkg.com/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.5.6.tgz#8e26cbb62abb1454130fe73bd475df3b24a97567" integrity sha512-1g7G0knRX2iV/voDu54yxrGqw5Dk0w2oIYb7dgJq8IkOi+m7wbD8Q3QpPFjh0C01G58S88dqGn03len6UPCXsg== -"@modelcontextprotocol/sdk@1.29.0": - version "1.29.0" - resolved "https://registry.yarnpkg.com/@modelcontextprotocol/sdk/-/sdk-1.29.0.tgz#79786d8b525e269de850ac82b1f1f757f3915f44" - integrity sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ== +"@modelcontextprotocol/sdk@1.30.0": + version "1.30.0" + resolved "https://registry.yarnpkg.com/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz#dfa8a48347ec2d2c0d47917d7dc57f754e37f5ff" + integrity sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA== dependencies: - "@hono/node-server" "^1.19.9" + "@hono/node-server" "^1.19.9 || ^2.0.5" ajv "^8.17.1" ajv-formats "^3.0.1" content-type "^1.0.5" @@ -1039,9 +1039,9 @@ "@napi-rs/nice-win32-x64-msvc" "1.1.1" "@napi-rs/wasm-runtime@^1.1.6": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.2.tgz#c70706532e5827c0932ca6bf43ee2c512f29c639" - integrity sha512-JfB4kuJQjaoHuCTseIINHtHWeJnvgEcxjwA5t/Y00ZgaOO1Crz3fjT/p8kT28zA/Caz7oiUMn3d6H2yOVCVwuw== + version "1.2.3" + resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.3.tgz#97e3d45d7424dc5da1d4e32f3bf3b292f6c1b44c" + integrity sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q== dependencies: "@tybys/wasm-util" "^0.10.3" @@ -1159,10 +1159,10 @@ resolved "https://registry.yarnpkg.com/@oxc-project/types/-/types-0.140.0.tgz#2acc1bd45ff24951059d01ce7552d26e1574c5ac" integrity sha512-h5LUOzGArYemnW1NMz/DuuQhBi96J6JL2Bk8zE4kvqxB5Sg3jxmCiH4uyOWHDkiKSt5vWlG4FIwCR/DbstcNRQ== -"@oxc-project/types@=0.143.0": - version "0.143.0" - resolved "https://registry.yarnpkg.com/@oxc-project/types/-/types-0.143.0.tgz#c3e4f3178b7b54e4dd194eac6d45258a60f0092b" - integrity sha512-u6JZdLBTLotrNC9Vd6vPssINdzcCzleKAH6EJKImQb7GtYvX5keN2dxkoK44stCc4tffE6QQRtZTXVSzsLUlWA== +"@oxc-project/types@=0.144.0": + version "0.144.0" + resolved "https://registry.yarnpkg.com/@oxc-project/types/-/types-0.144.0.tgz#7dfbfbfbbb9c24d4abeb6f9856a1eca02aff6468" + integrity sha512-nuhZIOLuI6TFQ32I/WnUx+SCPY7SdSKwgnFHydAuoS1+Z4BRcaP+RRJmGzl9lw+0OFF7UmaESf7KQRXaNLHypg== "@oxc-project/types@^0.142.0": version "0.142.0" @@ -1262,10 +1262,10 @@ resolved "https://registry.yarnpkg.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.0.tgz#18b16c76ef035d88a12905e84a5875fd39a869b4" integrity sha512-9yB1l95IrJuNGDFdOYe79vdApdz6WWBCObE+rQ2LUliYUlcyFwSYIb2xb5/Ifw7dAtMy2ZqNyd8QTSOc7duAKw== -"@rolldown/binding-android-arm64@1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.3.tgz#001b8b0b01844701efda1bb6bed84b681c4a488b" - integrity sha512-zrJtHDcaZJ1Fp7xf4hNl+7seH9Cn/N5TwLYkhgXREtBwAd/jaqW3uqeHxpDugJLVICWg4eW44kOQEGJ1r6jCGw== +"@rolldown/binding-android-arm64@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.4.tgz#9ac390255ded738672ad1425bed6423453ff71fd" + integrity sha512-jHC2cnyKz5xU2fhECtFl8OZ83cYNt13GZQD+0uMJ/X3o+ijmd56okHhTUwxVSHPx1IRVIJEZ1/1pPzeLCU6XKA== "@rolldown/binding-darwin-arm64@1.1.5": version "1.1.5" @@ -1277,10 +1277,10 @@ resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.0.tgz#2d66d02ade26d1ef79f98f65d7598fd9dae0a77b" integrity sha512-pexNaW9ACLUOaBITOpU6qVu4VrsOFIjTv6bzgu0YUATo4eUJx0V605PxwZfndpPOn0ilqGqvGQ0M8UW0IE24jg== -"@rolldown/binding-darwin-arm64@1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.3.tgz#5e87c602ed634a6fef092e2162e24fbfb881c4ec" - integrity sha512-ieIiibVCp0tX7TLu2cafoNPv8wJyYi01ekXpbf8q2j7F4rGAhhXb/eQh7ge9DRBY78GwmRQtvjZDux7EDbA8kA== +"@rolldown/binding-darwin-arm64@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.4.tgz#c63cad2f656b672782dd70894af895af9cba35c8" + integrity sha512-Dc5mPD8F5F/FS8i01syd7FTF6yB2fVthH/TRkjwJkzUK6EpoxHtqvZQP5Zwq80/5z19TWYHIg1KOHboCgVx/aQ== "@rolldown/binding-darwin-x64@1.1.5": version "1.1.5" @@ -1292,10 +1292,10 @@ resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.0.tgz#2f8a8beecd275e4291730c3f5b21b45399c81c4d" integrity sha512-NqKYaq0355ZmNMG4QGpxtEDxsc7tGDhjhCm4PpE0cwnBW+5Il95LJyq414niEiaKLVjnVHBEjSo1wngKxJNiFw== -"@rolldown/binding-darwin-x64@1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.3.tgz#f32e0b286714bd03a421d693415d05d97d265b77" - integrity sha512-Zh9tCon19eDXJoihx0rqKhMUlMYqzwj3aPsSuHmI4RWZh62dWUL+DJN4C5YQya5TcQBJU/Fe8+rY0jhXTQITqA== +"@rolldown/binding-darwin-x64@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.4.tgz#54f6305d6785793c63c1521a4da4412bf7d8e089" + integrity sha512-fpDm4oBo6SqLvWUYCmFhdde3U9KH2fRNNMeAnAPAIwxRL345xutL0EtEUcuoxsoazdJGv/MuDBQHlCDrtbvqOg== "@rolldown/binding-freebsd-x64@1.1.5": version "1.1.5" @@ -1307,10 +1307,10 @@ resolved "https://registry.yarnpkg.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.0.tgz#2b66b88e282ea2ebd2ab721ea88d209d600508c0" integrity sha512-3vPoHzh6eBTz9IbB0/qZdSr0Qeks2echn+I4cHu2joV74VriPDdldswksEDzrl1mBB+oPRi+67+3Ib59paxIPQ== -"@rolldown/binding-freebsd-x64@1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.3.tgz#5f38ad5761b6b7b21b57a99566bb52634c60ab19" - integrity sha512-nGbJWewA1wrXXZiQhjAT5rhibGfns5ZNkDVqxsO6zJ3f3YvpoDNNmGMSbbhLuXKjNScaBJVOAboztAWVespQMg== +"@rolldown/binding-freebsd-x64@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.4.tgz#c069a3ebd4a5dcfffd79a00f33c06bc242d9566b" + integrity sha512-rSJoreDE/HoIzoaib6MTp5jQtCTdMHKIvItAKT/ImS6Y6Ww76oUaeMyp4Vc/fAgd/ehji068IxetHXAnqUwN9A== "@rolldown/binding-linux-arm-gnueabihf@1.1.5": version "1.1.5" @@ -1322,10 +1322,10 @@ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.0.tgz#e3c3a54ab4b7855dd7b1388bd564344e78f2a9d8" integrity sha512-E6NNefZ1bUVmKJq2tJkf45J4Zyczj7qm9rUT7NY+Xo2474Y13qWAwc2tvBt0BAVbmtXR1llkxXg0Ou1jbDf2SQ== -"@rolldown/binding-linux-arm-gnueabihf@1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.3.tgz#ab4dcd07f1bd88e8d659ae0c3bb9d2f290adb897" - integrity sha512-QNniJr5Kml0kDEB98jiDOJjXNroxIIi0IXIbdYzY26Xt1pVbeP62+KnoIZLwirOymX/0jDk/2gI/bNUv7A7OIw== +"@rolldown/binding-linux-arm-gnueabihf@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.4.tgz#cff0d05a56e19f02443313f2abf73cf693173867" + integrity sha512-/jm8OGHgn7oGaJu3i/qZI9spUGcJ+y/lk43ttQ/iO1tOd9NissG6o97bighBCiL+BKRngmcDuR6ikfwYdJmVuQ== "@rolldown/binding-linux-arm64-gnu@1.1.5": version "1.1.5" @@ -1337,10 +1337,10 @@ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.0.tgz#1af753d6af0db3e408193d945f592f328947fd39" integrity sha512-D+TgkdgM1vu+7/Fpf8+v0ARW+RXEP9Ccazgm8zQ4JFFd9Q7SrYQ2TakU5S5ihazQDgpKyAgZDOcIFsvoHmTZ8w== -"@rolldown/binding-linux-arm64-gnu@1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.3.tgz#d279b7016039a725fb66d82784b9841f42df83da" - integrity sha512-TkqEAcmmvH3I/q4114NB4RVt6241Dao48pF45uLcFGrwAaIn0iITgTAKP/dLjbN0R4buJjGb91+UHSoFmpgIWw== +"@rolldown/binding-linux-arm64-gnu@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.4.tgz#267605366ba2bf3146609417a6db99253943c96f" + integrity sha512-tIP06BeD9EqvECBrPZ+sqdPlYrT+aYaAiu1wYziVx5elRK/ftm33JxVDy2bXGbr6J0CrtirCkR87/X5a2euEng== "@rolldown/binding-linux-arm64-musl@1.1.5": version "1.1.5" @@ -1352,10 +1352,10 @@ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.0.tgz#1caa273824312871204d2b58747425ea49739ef1" integrity sha512-wUqdwJBbAv0APN87GecstdMUtLjjNTs0hBALpxETD73mccFxdmt/XeizXDtN5RAlBwNKmI+Tg+blect2G+8IeQ== -"@rolldown/binding-linux-arm64-musl@1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.3.tgz#d08bbc93d2742214548c5adf7df7788944e5a89a" - integrity sha512-NHqjnxpsndf4MPymxteFAWHHfkTL8HjWh1KB7z23ofZ6QO2euONuxDXjat69dKZRALnGypg8k8SsK8vZJoXv1Q== +"@rolldown/binding-linux-arm64-musl@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.4.tgz#73d47bfdba2a72c16bfb271c23efb8949b2c2018" + integrity sha512-Ql1Q0EQqVThvn9VAVlwNzsUvbSFtCMGjLpRRi4pk5i7NZZ4n5ISiLMjHYtus4VQ2PvkSw24zyaCVsiS+sXPj1w== "@rolldown/binding-linux-ppc64-gnu@1.1.5": version "1.1.5" @@ -1367,10 +1367,10 @@ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.0.tgz#95a1a48e3051f1f8d9cab3703de62ea418c9924e" integrity sha512-9DtF35qR9/NrfhM4oxLplCzVVjE+KKm8Pjemi0i/sdhAWkUasjmSo8WTTubNJClhSHCfyk2yeyoXDQEDPtDAAw== -"@rolldown/binding-linux-ppc64-gnu@1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.3.tgz#6418e63745b3193f26ab3bb88744b3a4a1356d7c" - integrity sha512-6tbrbwfz5GB9DQ4Jwo6hy9v+vR31xZlvzZ6n5Xut6Hhx5PvrA9q/HsK8KMaYQp063iqZGXwNvZtYNLD7EM/x0w== +"@rolldown/binding-linux-ppc64-gnu@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.4.tgz#3ba455c72d3e9efd973df59689d48e75ca6f7559" + integrity sha512-GjbjXD4XXfN19D0LZNbmiCBUoDiRACsYHr0yaIbbn8aFsXjHZifcYqu/W5Er5X2X990WjHXFrxarn5chzItorQ== "@rolldown/binding-linux-s390x-gnu@1.1.5": version "1.1.5" @@ -1382,10 +1382,10 @@ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.0.tgz#2d3f7543b193f8462a4c12e9aefd2ad72fbbe518" integrity sha512-RzuHrBh8X8Hntd2N4VR02QGEciq/9JhcZoTpR/Cee6otRrlILGCf3cg2ygHuih+ZebUnWmMrDX6ITI85btO6rQ== -"@rolldown/binding-linux-s390x-gnu@1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.3.tgz#77ec30d0704cf4eb1cb4a63f501c9852c6728cf4" - integrity sha512-oyuXxXmoZHjXC917IAPFAAv4wWAa0cM9afk8nx1+9/jNNOX1uPf8yDA6p7G0RypOfw/X0PQt5IfoquY1um+zSg== +"@rolldown/binding-linux-s390x-gnu@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.4.tgz#2fddcb48eee12a620735c83a0056307b6ede2edb" + integrity sha512-p5WR0NOwaRmJ/B1b6IjEFLLivwEsf3PrdBIhRbhTCQisbo2SvHHpG4ELB/+FgQNnB88LTOF86upmJmbvZdQ2lw== "@rolldown/binding-linux-x64-gnu@1.1.5": version "1.1.5" @@ -1397,10 +1397,10 @@ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.0.tgz#0d428b854214bcaf0c8b81fc668c59932b20283b" integrity sha512-MK7L0018jjh1jR3mh21G2j1zAVcpscJBlPo2z19pRjv2XOYGRhaV4LyiD8HO6nCDdZln9IFgCMIV5yt4E3klGQ== -"@rolldown/binding-linux-x64-gnu@1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.3.tgz#3b9b6e0dd3e86c597f42858748ca25f1dfd58ed8" - integrity sha512-TytMwF2KVGqP2tgd0I1OY0PAv78dZRAYcF5ssDzjM34SUXCED3uXvSd5+lHoC0bTD6eEdFz7LdQNCO1y0oVk9w== +"@rolldown/binding-linux-x64-gnu@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.4.tgz#97fb91430f78e46f81d4fe82a049a8c47f4ece96" + integrity sha512-4/GyVjmhR+Tc6HLJvwc1sOhPqAZtySiSMesOZyX6JQ5XBxoTDEMKQzvo07NIK6nTon/SivlZqvhzvuVBNQhObQ== "@rolldown/binding-linux-x64-musl@1.1.5": version "1.1.5" @@ -1412,10 +1412,10 @@ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.0.tgz#3ef09dc3980913b3db489e5b568db3f51b7c02f8" integrity sha512-gyrxLQ9NfGb/9LoVnC4kb9miUghw1mghnkfYvNHSnVIXriabnfgGPUP4RLcJm87q3KgYz4FYUG8IDiWUT+CpSw== -"@rolldown/binding-linux-x64-musl@1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.3.tgz#f78033c592c8bd2af48284a45f8e4baaa0befbf5" - integrity sha512-/E9m3qstrJFVPoULV25mVQblSNExY2+kBsYe4sy0Tn0yOOgJ8wZbZt3KnRbF/XeU2Gl1STKUQnDNTqhIE5MD4A== +"@rolldown/binding-linux-x64-musl@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.4.tgz#71ec9967b5ff546a6d5dda16d1c7a97e50bf647a" + integrity sha512-l9eeLsCNvPpmSXUej0etw/J1eqV0Jj1D5G/xG6YTijmE6dkv6E2QezgWbTfQk63v952DPqrjOCoiqxq7Bw0YUQ== "@rolldown/binding-openharmony-arm64@1.1.5": version "1.1.5" @@ -1427,10 +1427,10 @@ resolved "https://registry.yarnpkg.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.0.tgz#bc2afd9513b85fd3cc176e3d0cb32727f4611598" integrity sha512-/6VFMQGRmrhP77KXDC+StIxGzcNp5JOIyYtw0CQ8gPlzhpiIRucYfoM5FaFamHd5BJYIdH86yfP46l1p3WdrFA== -"@rolldown/binding-openharmony-arm64@1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.3.tgz#36e951f5a6fca922a5205e283d0a82b9f98199ca" - integrity sha512-Kr0OcsoQI816i6HOl3vFHpd1K0eZyh76zgfj4c1nTyaTsd5r2Mj1lwM4R90y/qaCfmTn9eHy0SKwi98eitRxug== +"@rolldown/binding-openharmony-arm64@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.4.tgz#1e19ab28fbdb009cb6d9503e3ff6cbeffd7225ae" + integrity sha512-e0F355MSTMm3+UOqtV3L24gFUp2N5m1f8L/7d56deik6va+AXdrt9F8LbzGpeWGWRbZEDq4m8NVnJDeBtf9DZg== "@rolldown/binding-wasm32-wasi@1.1.5": version "1.1.5" @@ -1460,10 +1460,10 @@ resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.0.tgz#548e33a9362f50ca326e49bdfd35d4e1aaa68d9a" integrity sha512-+5suHwRiKGmhwyUaNT8a5QbrBvLFh2DbO910TEmGRH1aSxwrCezodvGQnulv4uiWEIv1Kq4ypRsJ5+O+ry1DiA== -"@rolldown/binding-win32-arm64-msvc@1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.3.tgz#c1e494ac47e13bd857fca0b3ad59c33580241f7e" - integrity sha512-hOtMwTqnME+/gJcH/PCZ0wn0zPUjiWOgkHpxbSJpfGKMezHltx1S7/k1SitzVa7Ww2cqrDDaFbZEhcJZO8o+Jw== +"@rolldown/binding-win32-arm64-msvc@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.4.tgz#9fad167d015c699f4375c2a1d04d1e52e4a32de4" + integrity sha512-AWLi0uBRYh6QlE7OKhiz+phZC0qwtij2QZmhmOdsLdFn64m7oMpooE9ICE3lhm9xMb4SpDo2WbHcxX1iFLFtqw== "@rolldown/binding-win32-x64-msvc@1.1.5": version "1.1.5" @@ -1475,10 +1475,10 @@ resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.0.tgz#7a655b9b4cac46a46eb18a0fae6bbc9ca22db4e4" integrity sha512-WfFv6/qGufotqBSBzBYwgpCkJBk8Nj7697LL9vTz/XWc67e0r3oewu8iMRwQj3AUL45GVD7wVsPjCsAAtW66Wg== -"@rolldown/binding-win32-x64-msvc@1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.3.tgz#b0effffcd6872f8a021373eb437916b1b52283a4" - integrity sha512-ekcqMMkI2PlhYnfzQnB/cEdYUVVJViWvoUyLrbzgDoi3Snfc1mVBwdnc306ufA5ejy8JSPjT2RlW1nQSjW7efg== +"@rolldown/binding-win32-x64-msvc@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.4.tgz#7a5f2d3e886c357029332b53f38ad2042e4615c4" + integrity sha512-UwSDJOg3dqCAejWdxclJjCsh3Qq4vLYMDxmyHqo1btz3stK2VqgwNd3mm5tuIwzSlGIQ/1H9Hr+Zn09mrezNqQ== "@rolldown/pluginutils@^1.0.0": version "1.0.1" @@ -1490,13 +1490,13 @@ resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== -"@schematics/angular@22.1.3": - version "22.1.3" - resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-22.1.3.tgz#a118272c3e2686dc434cae57da034812e92beed6" - integrity sha512-5f5f0tKp3d25hjNGkvw2dtGgTN4wxPNhv1AXnhFkh+mLinQK9Qwzr2iEXDDrAuJEkvz1ACHq631IURWph0lqew== +"@schematics/angular@22.1.4": + version "22.1.4" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-22.1.4.tgz#38c29eae18e735f85cd531a4c641ebabcf791839" + integrity sha512-uiYKuiCnkTEbs4eOU1QJlM5NPw6BR1qgpct8VlrhS4n861WCCjTy5cxiAWJ3Doc0R72d44j3uoBfAEp7KEVn2w== dependencies: - "@angular-devkit/core" "22.1.3" - "@angular-devkit/schematics" "22.1.3" + "@angular-devkit/core" "22.1.4" + "@angular-devkit/schematics" "22.1.4" jsonc-parser "3.3.1" typescript "6.0.3" @@ -1565,100 +1565,100 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== -"@typescript-eslint/eslint-plugin@8.66.0": - version "8.66.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.66.0.tgz#76e86aa5a2459fbf5bbd7a839c0dc0cce1d56224" - integrity sha512-p088eaGrzYz1s+7cov0aMOCkNGTJlVxF4jgubf28c8L0Cv9Rloj8YBHnv4hXLq6IIEE1AsjNWavO+k+8kP2Y0A== +"@typescript-eslint/eslint-plugin@8.67.0": + version "8.67.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.67.0.tgz#52f9f0e47d5a7571c4336e69bfeea581509ef2cf" + integrity sha512-Un7Heoyj65NREbKAyIrFxeM143NZpExWmy1Nep4DLeQOeLlTeumPjoNKnBrU5D5moWXbPJgRa5Uwcdu0faVNGQ== dependencies: "@eslint-community/regexpp" "^4.12.2" - "@typescript-eslint/scope-manager" "8.66.0" - "@typescript-eslint/type-utils" "8.66.0" - "@typescript-eslint/utils" "8.66.0" - "@typescript-eslint/visitor-keys" "8.66.0" + "@typescript-eslint/scope-manager" "8.67.0" + "@typescript-eslint/type-utils" "8.67.0" + "@typescript-eslint/utils" "8.67.0" + "@typescript-eslint/visitor-keys" "8.67.0" ignore "^7.0.5" natural-compare "^1.4.0" ts-api-utils "^2.5.0" -"@typescript-eslint/parser@8.66.0": - version "8.66.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.66.0.tgz#88e3865ecf73b0118134e7cb831da87a961a57a1" - integrity sha512-X6ypGChaWYk6PBtUg2BwuTZEFFcHJAtGTVJ9/lCTOufhZ4i9fNolQNnktq+kkMCwMj7V8Svsq7+TxSDslmhE0g== +"@typescript-eslint/parser@8.67.0": + version "8.67.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.67.0.tgz#0158022ec9927e0afcd58a8cc2ad57e01d892f5c" + integrity sha512-fUBfTuuEulWqX6V8+O3PtScV01tzYYRUDTAirHFKoRAt7nOzoGiPt0M/bB47wWNy0coOOcgEwAMUtBpykMxl6w== dependencies: - "@typescript-eslint/scope-manager" "8.66.0" - "@typescript-eslint/types" "8.66.0" - "@typescript-eslint/typescript-estree" "8.66.0" - "@typescript-eslint/visitor-keys" "8.66.0" + "@typescript-eslint/scope-manager" "8.67.0" + "@typescript-eslint/types" "8.67.0" + "@typescript-eslint/typescript-estree" "8.67.0" + "@typescript-eslint/visitor-keys" "8.67.0" debug "^4.4.3" -"@typescript-eslint/project-service@8.66.0": - version "8.66.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.66.0.tgz#828f788895df52d9eb2b543445a3a5a13e35ab4e" - integrity sha512-7MthGPTt4BP69lSryqpqq8HQqxuzynssckL/jyDyk3+TNMQ3y2jFWkptCrktWvBrP+EH787Nl5N5Qpw7WZg+5g== +"@typescript-eslint/project-service@8.67.0": + version "8.67.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.67.0.tgz#1552db007ca9206a1c6c7acf49e210bd17a8c56f" + integrity sha512-cvE8c7ulYeXN9fYuszhCeCsbzyVEXuhrRCybnBre7TUmqb5nRmBfQAwCj0O3WJFDeyAZt4VYv51vMCC9LHSdYw== dependencies: - "@typescript-eslint/tsconfig-utils" "^8.66.0" - "@typescript-eslint/types" "^8.66.0" + "@typescript-eslint/tsconfig-utils" "^8.67.0" + "@typescript-eslint/types" "^8.67.0" debug "^4.4.3" -"@typescript-eslint/scope-manager@8.66.0": - version "8.66.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.66.0.tgz#4fffcc6ebd0df9fe7983c0256967567ea6f5ac63" - integrity sha512-8TGcH25j9zqJ/IULB/ppyhRvxA8QYfFEZ7nfbg6/BN9spDgb8fPWQXlE5l8TWBL50EtUx007uZ1o9VOwrq2/9g== +"@typescript-eslint/scope-manager@8.67.0": + version "8.67.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.67.0.tgz#4d4c2da09560d10dd7d947cba2d29d14d25af16d" + integrity sha512-EgvsleTwS4E+WzzSvem8fAUubLwatMNF1B5hHSLQxcvs7q2dtRhGyujHwLJSYlG41niJ7GP24Aha2+0mb1b2kg== dependencies: - "@typescript-eslint/types" "8.66.0" - "@typescript-eslint/visitor-keys" "8.66.0" + "@typescript-eslint/types" "8.67.0" + "@typescript-eslint/visitor-keys" "8.67.0" -"@typescript-eslint/tsconfig-utils@8.66.0", "@typescript-eslint/tsconfig-utils@^8.66.0": - version "8.66.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.66.0.tgz#3a89066c507aa30541dc176804685b4b444e1e52" - integrity sha512-9D5gLYZG4rOjcoag8MQ/fWI8WqA9wcPDyOGyWtWFhvM1lHRbliqUSPIY5J3zqCU1tvSwzXxnnjhQhz5Ne7mJ4g== +"@typescript-eslint/tsconfig-utils@8.67.0", "@typescript-eslint/tsconfig-utils@^8.67.0": + version "8.67.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.67.0.tgz#f45a3eba6b9132fb47141ec03ce2f275f1ea991d" + integrity sha512-vV+LUSv5njUWsknE71fqKTlXUva+R76SaeORd6Zojcunk/6DvKFXONU3BrAs2H49mbygUXt6gbYunzwqNwlhdg== -"@typescript-eslint/type-utils@8.66.0": - version "8.66.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.66.0.tgz#b2315303eca72fad9afa7be4f58f053c8f2a0479" - integrity sha512-LG2dWfjZQQp0ADtAu/EWJVayefGL2UEZ3CDeI44D9v3rXB/WYUqE/jpO28KrEKul5AySrmI+Zh1v6v+xW2U9+g== +"@typescript-eslint/type-utils@8.67.0": + version "8.67.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.67.0.tgz#96bed105275559df3bcf0449b73a6414d35c59ce" + integrity sha512-aVWDXbRmdXO9siTfX4ditQI1T9+zVcNazT48EJCD0v40/9RIFoUgZ05CmGEq9H2gixRpjUn/iplwvlcvutJW/Q== dependencies: - "@typescript-eslint/types" "8.66.0" - "@typescript-eslint/typescript-estree" "8.66.0" - "@typescript-eslint/utils" "8.66.0" + "@typescript-eslint/types" "8.67.0" + "@typescript-eslint/typescript-estree" "8.67.0" + "@typescript-eslint/utils" "8.67.0" debug "^4.4.3" ts-api-utils "^2.5.0" -"@typescript-eslint/types@8.66.0", "@typescript-eslint/types@^8.0.0", "@typescript-eslint/types@^8.66.0": - version "8.66.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.66.0.tgz#3cacab94d3b564c1d48c56eb37b89f89a6d48479" - integrity sha512-H6gcYaSDOyvL3AD/jHUtUFo2jqGgn/F6nuyuZSu0QTesxL+cP4dQoIMrODRofuJC09g64+WgZ6tE19Y1N2YIFQ== +"@typescript-eslint/types@8.67.0", "@typescript-eslint/types@^8.0.0", "@typescript-eslint/types@^8.67.0": + version "8.67.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.67.0.tgz#4a8d00cc1faba5c14feabc60f85b7a32652f34b6" + integrity sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww== -"@typescript-eslint/typescript-estree@8.66.0": - version "8.66.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.66.0.tgz#1a38c3a97dc6c669b66d585d7f90ebc4fbb32a50" - integrity sha512-8/x4INiiQb10jGgXYD7116/zQ+OL84ZIFn0za68wwFHCanT/VLbBEroWht8RV8fn0/ZCAoazHLQgwUC0UQcDfg== +"@typescript-eslint/typescript-estree@8.67.0": + version "8.67.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.67.0.tgz#116c3a47c06119c5a050e8851861d6497dd64bc2" + integrity sha512-EKQBCE9yNlRJYm7jdTW5AhDacDUmSwQb0FAJAmK2EKYrNXIsa2vxcSZx6PvJ/dEdI6lS+Y9W+EXckLj0iPFGcw== dependencies: - "@typescript-eslint/project-service" "8.66.0" - "@typescript-eslint/tsconfig-utils" "8.66.0" - "@typescript-eslint/types" "8.66.0" - "@typescript-eslint/visitor-keys" "8.66.0" + "@typescript-eslint/project-service" "8.67.0" + "@typescript-eslint/tsconfig-utils" "8.67.0" + "@typescript-eslint/types" "8.67.0" + "@typescript-eslint/visitor-keys" "8.67.0" debug "^4.4.3" minimatch "^10.2.2" semver "^7.7.3" tinyglobby "^0.2.15" ts-api-utils "^2.5.0" -"@typescript-eslint/utils@8.66.0", "@typescript-eslint/utils@^8.0.0", "@typescript-eslint/utils@^8.65.0": - version "8.66.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.66.0.tgz#e277d67427043cdca2580ee91aa62921e4689969" - integrity sha512-jasearZPolBw5NJNYGMwxzHMF83niVWmMU1VdHzG1CyfI2VS7f7nZltnKtHcg20hW+7Uo5GfK4MeDPoU3qI8EA== +"@typescript-eslint/utils@8.67.0", "@typescript-eslint/utils@^8.0.0", "@typescript-eslint/utils@^8.65.0": + version "8.67.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.67.0.tgz#3e478a3d69d330a1fc50c12746cc2ee0732ccfcd" + integrity sha512-U9D1FdwEWBwok3hxxSdhclMb0twvt9QnjIQ0VfQ1AiX2epnpSgv2ubVDsayOFyY8K6FX+AQ7E0FKWVG3iKsj1A== dependencies: "@eslint-community/eslint-utils" "^4.9.1" - "@typescript-eslint/scope-manager" "8.66.0" - "@typescript-eslint/types" "8.66.0" - "@typescript-eslint/typescript-estree" "8.66.0" + "@typescript-eslint/scope-manager" "8.67.0" + "@typescript-eslint/types" "8.67.0" + "@typescript-eslint/typescript-estree" "8.67.0" -"@typescript-eslint/visitor-keys@8.66.0": - version "8.66.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.66.0.tgz#4c494e94745fb2724a4f37a310091e56b644d18a" - integrity sha512-dkKR8q+lKciskj1Y3vthHktl+3cMLWGyVUP23bRiPZ5O9BRT++4EqDDV+TVeIKBL1VXVEqrJlz8MYbcnvJcAlg== +"@typescript-eslint/visitor-keys@8.67.0": + version "8.67.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.67.0.tgz#601d40af9acf82a28da2286f3edafc69bba9017f" + integrity sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA== dependencies: - "@typescript-eslint/types" "8.66.0" + "@typescript-eslint/types" "8.67.0" eslint-visitor-keys "^5.0.0" "@vitejs/plugin-basic-ssl@2.3.0": @@ -1666,63 +1666,63 @@ resolved "https://registry.yarnpkg.com/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.3.0.tgz#f505b1c197d8cb4fd6e213a78847574ecc51e2f9" integrity sha512-bdyo8rB3NnQbikdMpHaML9Z1OZPBu6fFOBo+OtxsBlvMJtysWskmBcnbIDhUqgC8tcxNv/a+BcV5U+2nQMm1OQ== -"@vitest/expect@4.1.10": - version "4.1.10" - resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-4.1.10.tgz#799c06fc44bb0cf7e2784137b627c5cc173285d4" - integrity sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA== +"@vitest/expect@4.1.11": + version "4.1.11" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-4.1.11.tgz#5f580d1f9cdbba314dbf23b2d911f8eb23878f5f" + integrity sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw== dependencies: "@standard-schema/spec" "^1.1.0" "@types/chai" "^5.2.2" - "@vitest/spy" "4.1.10" - "@vitest/utils" "4.1.10" + "@vitest/spy" "4.1.11" + "@vitest/utils" "4.1.11" chai "^6.2.2" tinyrainbow "^3.1.0" -"@vitest/mocker@4.1.10": - version "4.1.10" - resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-4.1.10.tgz#2413987ab4cd7fa1c2b614b404c407bf6ad1ead1" - integrity sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow== +"@vitest/mocker@4.1.11": + version "4.1.11" + resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-4.1.11.tgz#8e2906361bc5dfa271757a858ae80643118fcbb4" + integrity sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ== dependencies: - "@vitest/spy" "4.1.10" + "@vitest/spy" "4.1.11" estree-walker "^3.0.3" magic-string "^0.30.21" -"@vitest/pretty-format@4.1.10": - version "4.1.10" - resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-4.1.10.tgz#75542e7273a08cc10fd4d8dad4e3eb1f16cd958c" - integrity sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q== +"@vitest/pretty-format@4.1.11": + version "4.1.11" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-4.1.11.tgz#8b28eb8240771d6ea970e33beaeb41384b51868e" + integrity sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw== dependencies: tinyrainbow "^3.1.0" -"@vitest/runner@4.1.10": - version "4.1.10" - resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-4.1.10.tgz#febf0a21a9168421422d1955370e606feab60355" - integrity sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg== +"@vitest/runner@4.1.11": + version "4.1.11" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-4.1.11.tgz#bfbad98c8d6c3f1fb4df12056ad569821ff77f21" + integrity sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw== dependencies: - "@vitest/utils" "4.1.10" + "@vitest/utils" "4.1.11" pathe "^2.0.3" -"@vitest/snapshot@4.1.10": - version "4.1.10" - resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-4.1.10.tgz#7e3e9fec7d4d47232e493cfdcbd2170de4371c04" - integrity sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw== +"@vitest/snapshot@4.1.11": + version "4.1.11" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-4.1.11.tgz#df461eb165924a3155986dde68e13360f53f3d4c" + integrity sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog== dependencies: - "@vitest/pretty-format" "4.1.10" - "@vitest/utils" "4.1.10" + "@vitest/pretty-format" "4.1.11" + "@vitest/utils" "4.1.11" magic-string "^0.30.21" pathe "^2.0.3" -"@vitest/spy@4.1.10": - version "4.1.10" - resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-4.1.10.tgz#5c0bfa97b56bba9e37403c976db776ff6ab56f65" - integrity sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw== +"@vitest/spy@4.1.11": + version "4.1.11" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-4.1.11.tgz#0add45cae953afed9c88f98e2f6fc9164558c32a" + integrity sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA== -"@vitest/utils@4.1.10": - version "4.1.10" - resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-4.1.10.tgz#ffc71055f18bfccb1fd0586365ebc2824892e403" - integrity sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA== +"@vitest/utils@4.1.11": + version "4.1.11" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-4.1.11.tgz#9b27a4293b827942b223539bfab1bd9f7eada31b" + integrity sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ== dependencies: - "@vitest/pretty-format" "4.1.10" + "@vitest/pretty-format" "4.1.11" convert-source-map "^2.0.0" tinyrainbow "^3.1.0" @@ -1817,9 +1817,9 @@ ansi-regex@^5.0.1: integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-regex@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.2.tgz#60216eea464d864597ce2832000738a0589650c1" - integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg== + version "6.3.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.3.0.tgz#247c8e7b70a1a43b10ce14c0226fcbf58e8815d5" + integrity sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ== ansi-styles@^3.2.1: version "3.2.1" @@ -1956,9 +1956,9 @@ balanced-match@^4.0.2: integrity sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA== baseline-browser-mapping@^2.11.12: - version "2.11.13" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.11.13.tgz#660073103c1bee93e54df55f117b7528adf6af19" - integrity sha512-k9HNuUVMlqVjQ9UHzfPjIqiDbWw7WqT1AoT7GL8VwvF3r0ZfArtgiSPAlmupyNquNgOJHTuH4CKYf8ttMTWBTQ== + version "2.11.15" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.11.15.tgz#9c0cac93d7d304f3d61bb41088a102cd62e68676" + integrity sha512-FwMjJJ7HnyZpWe+oWxegG0fezZyBZUagI5LZEoO3GCbtbKNwRfMH9Ue5d5v01PNePBy1QSfPSDTTeVL0Hb9EzA== beasties@0.4.3: version "0.4.3" @@ -2213,9 +2213,9 @@ content-type@^1.0.5: integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== content-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-2.0.0.tgz#2fb3ede69dffa0af78ca7c4ce7589680638b56df" - integrity sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ== + version "2.1.0" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-2.1.0.tgz#d9389c43c0a8cf6a355db464d21e07092a40493a" + integrity sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag== conventional-changelog-angular@^5.0.12: version "5.0.13" @@ -2617,9 +2617,9 @@ ee-first@1.1.1: integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== electron-to-chromium@^1.5.402: - version "1.5.403" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.403.tgz#8a6e422bc68c5d2fa4d8c5fa2ba9a583c3d4452c" - integrity sha512-MQsYmdaLzvaCX5j+ZZBr5Fm6uCCnPQcRtlvmvRlWqrXy+BH2O4ffXIAScF+JQznQWB9brWp4lSD9Z4yNmaf2BA== + version "1.5.409" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.409.tgz#3d514dd82b2d181d8ade96c53242f4b8c94ab4ed" + integrity sha512-ChI4N44d0B4A6C8prnNjMOaGgE59fUyEVYcRYm2XEXIjMbbvF5i9UL1cblDbpGqiU0uS8FE8UcKxqZqTXdmzbQ== emoji-regex@^10.3.0: version "10.6.0" @@ -2749,9 +2749,9 @@ es-errors@^1.3.0: integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== es-module-lexer@^2.0.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.3.1.tgz#5bf2df06999dbbe5f006a5f46a11fb9f5b7b391b" - integrity sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA== + version "2.3.2" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.3.2.tgz#311fa4f40168c1975c505477c51b23234d41ad55" + integrity sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw== es-object-atoms@^1.0.0, es-object-atoms@^1.1.1, es-object-atoms@^1.1.2: version "1.1.2" @@ -2789,37 +2789,37 @@ es-to-primitive@^1.3.0: is-date-object "^1.1.0" is-symbol "^1.1.1" -esbuild@0.28.1: - version "0.28.1" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.28.1.tgz#ef45b4634c9c9d97a296aea4114a5f9840f95578" - integrity sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw== +esbuild@0.28.2: + version "0.28.2" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.28.2.tgz#0f43bd1bad955b72d24e2261e3abe5957ccf0816" + integrity sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA== optionalDependencies: - "@esbuild/aix-ppc64" "0.28.1" - "@esbuild/android-arm" "0.28.1" - "@esbuild/android-arm64" "0.28.1" - "@esbuild/android-x64" "0.28.1" - "@esbuild/darwin-arm64" "0.28.1" - "@esbuild/darwin-x64" "0.28.1" - "@esbuild/freebsd-arm64" "0.28.1" - "@esbuild/freebsd-x64" "0.28.1" - "@esbuild/linux-arm" "0.28.1" - "@esbuild/linux-arm64" "0.28.1" - "@esbuild/linux-ia32" "0.28.1" - "@esbuild/linux-loong64" "0.28.1" - "@esbuild/linux-mips64el" "0.28.1" - "@esbuild/linux-ppc64" "0.28.1" - "@esbuild/linux-riscv64" "0.28.1" - "@esbuild/linux-s390x" "0.28.1" - "@esbuild/linux-x64" "0.28.1" - "@esbuild/netbsd-arm64" "0.28.1" - "@esbuild/netbsd-x64" "0.28.1" - "@esbuild/openbsd-arm64" "0.28.1" - "@esbuild/openbsd-x64" "0.28.1" - "@esbuild/openharmony-arm64" "0.28.1" - "@esbuild/sunos-x64" "0.28.1" - "@esbuild/win32-arm64" "0.28.1" - "@esbuild/win32-ia32" "0.28.1" - "@esbuild/win32-x64" "0.28.1" + "@esbuild/aix-ppc64" "0.28.2" + "@esbuild/android-arm" "0.28.2" + "@esbuild/android-arm64" "0.28.2" + "@esbuild/android-x64" "0.28.2" + "@esbuild/darwin-arm64" "0.28.2" + "@esbuild/darwin-x64" "0.28.2" + "@esbuild/freebsd-arm64" "0.28.2" + "@esbuild/freebsd-x64" "0.28.2" + "@esbuild/linux-arm" "0.28.2" + "@esbuild/linux-arm64" "0.28.2" + "@esbuild/linux-ia32" "0.28.2" + "@esbuild/linux-loong64" "0.28.2" + "@esbuild/linux-mips64el" "0.28.2" + "@esbuild/linux-ppc64" "0.28.2" + "@esbuild/linux-riscv64" "0.28.2" + "@esbuild/linux-s390x" "0.28.2" + "@esbuild/linux-x64" "0.28.2" + "@esbuild/netbsd-arm64" "0.28.2" + "@esbuild/netbsd-x64" "0.28.2" + "@esbuild/openbsd-arm64" "0.28.2" + "@esbuild/openbsd-x64" "0.28.2" + "@esbuild/openharmony-arm64" "0.28.2" + "@esbuild/sunos-x64" "0.28.2" + "@esbuild/win32-arm64" "0.28.2" + "@esbuild/win32-ia32" "0.28.2" + "@esbuild/win32-x64" "0.28.2" escalade@^3.1.1, escalade@^3.2.0: version "3.2.0" @@ -3012,9 +3012,9 @@ eventemitter3@^5.0.4: integrity sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw== eventsource-parser@^3.0.0, eventsource-parser@^3.0.1: - version "3.1.0" - resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-3.1.0.tgz#4e198eb91cd333d0a8ddcc036502b3618a25f449" - integrity sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg== + version "3.1.1" + resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-3.1.1.tgz#b96cbb7dace4f3774f58a9e3b1ae9a4a524872e2" + integrity sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ== eventsource@^3.0.2: version "3.0.7" @@ -3418,9 +3418,9 @@ hasown@^2.0.2, hasown@^2.0.3, hasown@^2.0.4: function-bind "^1.1.2" hono@^4.11.4: - version "4.13.1" - resolved "https://registry.yarnpkg.com/hono/-/hono-4.13.1.tgz#d4a606b792954d07a6215d12c01b7cf59da03cbc" - integrity sha512-kdJoFVv2xmayw6cY09H7AbMJMt8Jn5jdlEdXsP7AGBdF2DIptVlKlOLKXP41yPip4/a3yQPv9gVcJYI8YY04dw== + version "4.13.3" + resolved "https://registry.yarnpkg.com/hono/-/hono-4.13.3.tgz#9715a35f637115f7455287ce6fdddcab21653d6b" + integrity sha512-r8AO2mYHoLxSHkgafNeC/BXyb2vWRxD3jem4Ts+ptav8oTG5FIRifAjuJEmZI4bSvvc2ns0GxmIYiZnHqN3mMw== hosted-git-info@^10.1.0: version "10.1.1" @@ -3802,9 +3802,9 @@ javascript-natural-sort@^0.7.1: integrity sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw== jose@^6.1.3: - version "6.2.8" - resolved "https://registry.yarnpkg.com/jose/-/jose-6.2.8.tgz#39c1459fe5eac84eb39b1623b8077dcf9ca6c506" - integrity sha512-Bsdjwm3Qsd/P0jR+BHDe3LytDfY7WBq2HmCCLIwuVRHMuEC9ae7/R474GIUdF1NgCyZjzVo/A9DOiOBtXq8ZoQ== + version "6.2.9" + resolved "https://registry.yarnpkg.com/jose/-/jose-6.2.9.tgz#344fa11af928f8000a4f81972c4d567d587170f0" + integrity sha512-XrchZOFZUl/T3vTwRe8XK+cJrGtMF4th1ARnDfwbBXFKThGhlsxEE4Zu03AD/bjJSt/9jT/mxrOCkJWOg77aPA== js-tokens@^10.0.0: version "10.0.0" @@ -4992,27 +4992,27 @@ rolldown@~1.1.5: "@rolldown/binding-win32-x64-msvc" "1.1.5" rolldown@~1.2.1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/rolldown/-/rolldown-1.2.3.tgz#103bdcbbd575d51265277b8b510f080827b6eb6f" - integrity sha512-rn9wpmxplLf7NLNyCk9FyWh3FM43DbY8jOzCdEPzH7uflhTftRbCEpqi6Ly2osgoU8OwObtmavMbWLaWy4LX7A== + version "1.2.4" + resolved "https://registry.yarnpkg.com/rolldown/-/rolldown-1.2.4.tgz#a70655fdd305b829bbc0fc598b3dd1765b4a87dc" + integrity sha512-rSr7irW0K7QRWzjdJXqZowkcRdDtjRduh43rBltnVKd0VFq839l1lJoDvGJb6gl7+4rTTCrPWu+YfujUL8Ug7w== dependencies: - "@oxc-project/types" "=0.143.0" + "@oxc-project/types" "=0.144.0" "@rolldown/pluginutils" "^1.0.0" optionalDependencies: - "@rolldown/binding-android-arm64" "1.2.3" - "@rolldown/binding-darwin-arm64" "1.2.3" - "@rolldown/binding-darwin-x64" "1.2.3" - "@rolldown/binding-freebsd-x64" "1.2.3" - "@rolldown/binding-linux-arm-gnueabihf" "1.2.3" - "@rolldown/binding-linux-arm64-gnu" "1.2.3" - "@rolldown/binding-linux-arm64-musl" "1.2.3" - "@rolldown/binding-linux-ppc64-gnu" "1.2.3" - "@rolldown/binding-linux-s390x-gnu" "1.2.3" - "@rolldown/binding-linux-x64-gnu" "1.2.3" - "@rolldown/binding-linux-x64-musl" "1.2.3" - "@rolldown/binding-openharmony-arm64" "1.2.3" - "@rolldown/binding-win32-arm64-msvc" "1.2.3" - "@rolldown/binding-win32-x64-msvc" "1.2.3" + "@rolldown/binding-android-arm64" "1.2.4" + "@rolldown/binding-darwin-arm64" "1.2.4" + "@rolldown/binding-darwin-x64" "1.2.4" + "@rolldown/binding-freebsd-x64" "1.2.4" + "@rolldown/binding-linux-arm-gnueabihf" "1.2.4" + "@rolldown/binding-linux-arm64-gnu" "1.2.4" + "@rolldown/binding-linux-arm64-musl" "1.2.4" + "@rolldown/binding-linux-ppc64-gnu" "1.2.4" + "@rolldown/binding-linux-s390x-gnu" "1.2.4" + "@rolldown/binding-linux-x64-gnu" "1.2.4" + "@rolldown/binding-linux-x64-musl" "1.2.4" + "@rolldown/binding-openharmony-arm64" "1.2.4" + "@rolldown/binding-win32-arm64-msvc" "1.2.4" + "@rolldown/binding-win32-x64-msvc" "1.2.4" router@^2.2.0: version "2.2.0" @@ -5654,14 +5654,14 @@ typedarray@^0.0.6: integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== typescript-eslint@^8.33.1: - version "8.66.0" - resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.66.0.tgz#0809b6d25c8a0924690ba30dc1f05607093c11fb" - integrity sha512-QlEbBPz/RuJ1XUHj29nm3t0F/O/cSlEnntozqPOYHnnTGAXFamnMBu5i9Vn6vhUPHGAjR+Vl+5J8vPN/BMUrJw== + version "8.67.0" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.67.0.tgz#1e92de09ee0ff2d96cc0848f5e9f345ea930d963" + integrity sha512-S2udFs8tCKEKffuJ4TB1idGUZiXdCPGi3IPBGWXarbLQ5UPXORV8QEVzJ4gCRduURMb5EkpNCdjbk0eDIuI8Yg== dependencies: - "@typescript-eslint/eslint-plugin" "8.66.0" - "@typescript-eslint/parser" "8.66.0" - "@typescript-eslint/typescript-estree" "8.66.0" - "@typescript-eslint/utils" "8.66.0" + "@typescript-eslint/eslint-plugin" "8.67.0" + "@typescript-eslint/parser" "8.67.0" + "@typescript-eslint/typescript-estree" "8.67.0" + "@typescript-eslint/utils" "8.67.0" typescript@6.0.3, typescript@~6.0.3: version "6.0.3" @@ -5689,9 +5689,9 @@ unpipe@~1.0.0: integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== update-browserslist-db@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.3.0.tgz#9ff2604d5b949051639c01a223a16619f8a2b2c7" - integrity sha512-x/M6q3w4Ybp91CNaS4S69UnliqR3BzRpOT6LWbksjth0S/+jhfaPJsWjt/TewpT8j9eLIojUf5jr29WextHroA== + version "1.3.1" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.3.1.tgz#a71c28dd22f505481dbc4689087b18d933e90afd" + integrity sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ== dependencies: escalade "^3.2.0" picocolors "^1.1.1" @@ -5753,17 +5753,17 @@ vite@8.1.5: fsevents "~2.3.3" vitest@^4.0.8: - version "4.1.10" - resolved "https://registry.yarnpkg.com/vitest/-/vitest-4.1.10.tgz#7e9285efe264b1167050b7a3a7ff34788e1b7afc" - integrity sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw== + version "4.1.11" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-4.1.11.tgz#1653c1521ae917f960d9b21877797c47dfd8bf21" + integrity sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw== dependencies: - "@vitest/expect" "4.1.10" - "@vitest/mocker" "4.1.10" - "@vitest/pretty-format" "4.1.10" - "@vitest/runner" "4.1.10" - "@vitest/snapshot" "4.1.10" - "@vitest/spy" "4.1.10" - "@vitest/utils" "4.1.10" + "@vitest/expect" "4.1.11" + "@vitest/mocker" "4.1.11" + "@vitest/pretty-format" "4.1.11" + "@vitest/runner" "4.1.11" + "@vitest/snapshot" "4.1.11" + "@vitest/spy" "4.1.11" + "@vitest/utils" "4.1.11" es-module-lexer "^2.0.0" expect-type "^1.3.0" magic-string "^0.30.21" @@ -5869,13 +5869,12 @@ wordwrap@^1.0.0: integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== wrap-ansi@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-10.0.0.tgz#b83ddcc14dbc5596f1b07e153bf6f863c1acbb57" - integrity sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ== + version "10.0.1" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-10.0.1.tgz#59b821b7987d36a87a367bc9517284ff974086ea" + integrity sha512-M0N4xzyzosiIok3svYlEo1sdLZts/8FPgYH/GPC3wvlmPoRvnoManGMrE54waYj3tISA8w6lsdesfVv67qSr8Q== dependencies: ansi-styles "^6.2.3" string-width "^8.2.0" - strip-ansi "^7.1.2" wrap-ansi@^7.0.0: version "7.0.0" @@ -5930,15 +5929,15 @@ yargs-parser@^22.0.0: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-22.0.0.tgz#87b82094051b0567717346ecd00fd14804b357c8" integrity sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw== -yargs@18.0.0: - version "18.0.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-18.0.0.tgz#6c84259806273a746b09f579087b68a3c2d25bd1" - integrity sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg== +yargs@18.1.0, yargs@^18.0.0: + version "18.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-18.1.0.tgz#cd7e98c703ef51695bbbf062ed58f28e94291b56" + integrity sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg== dependencies: cliui "^9.0.1" escalade "^3.1.1" get-caller-file "^2.0.5" - string-width "^7.2.0" + string-width "^8.2.1" y18n "^5.0.5" yargs-parser "^22.0.0" @@ -5955,18 +5954,6 @@ yargs@^16.0.0, yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@^18.0.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-18.1.0.tgz#cd7e98c703ef51695bbbf062ed58f28e94291b56" - integrity sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg== - dependencies: - cliui "^9.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - string-width "^8.2.1" - y18n "^5.0.5" - yargs-parser "^22.0.0" - yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"