diff --git a/api/app.py b/api/app.py index 1d611eac58..714a60b34c 100644 --- a/api/app.py +++ b/api/app.py @@ -1,5 +1,13 @@ +from __future__ import annotations + import os import sys +from typing import TYPE_CHECKING, cast + +if TYPE_CHECKING: + from celery import Celery + + celery: Celery def is_db_command() -> bool: @@ -30,7 +38,7 @@ else: socketio_app, flask_app = create_app() app = flask_app - celery = flask_app.extensions["celery"] + celery = cast("Celery", flask_app.extensions["celery"]) if __name__ == "__main__": from gevent import pywsgi diff --git a/api/app_factory.py b/api/app_factory.py index ab50165a24..a8752e3d5e 100644 --- a/api/app_factory.py +++ b/api/app_factory.py @@ -155,7 +155,7 @@ def initialize_extensions(app: DifyApp): logger.info("Loaded %s (%s ms)", short_name, round((end_time - start_time) * 1000, 2)) -def create_migrations_app(): +def create_migrations_app() -> DifyApp: app = create_flask_app_with_configs() from extensions import ext_database, ext_migrate diff --git a/api/controllers/console/app/generator.py b/api/controllers/console/app/generator.py index d14dd52e4e..f4c58f510f 100644 --- a/api/controllers/console/app/generator.py +++ b/api/controllers/console/app/generator.py @@ -12,6 +12,7 @@ from controllers.console.app.error import ( ProviderQuotaExceededError, ) from controllers.console.wraps import account_initialization_required, setup_required +from core.app.app_config.entities import ModelConfig from core.errors.error import ModelCurrentlyNotSupportError, ProviderTokenNotInitError, QuotaExceededError from core.helper.code_executor.code_node_provider import CodeNodeProvider from core.helper.code_executor.javascript.javascript_code_provider import JavascriptCodeProvider @@ -21,6 +22,7 @@ from core.llm_generator.context_models import ( CodeContextPayload, ParameterInfoPayload, ) +from core.llm_generator.entities import RuleCodeGeneratePayload, RuleGeneratePayload, RuleStructuredOutputPayload from core.llm_generator.llm_generator import LLMGenerator from core.model_runtime.errors.invoke import InvokeError from extensions.ext_database import db @@ -31,28 +33,13 @@ from services.workflow_service import WorkflowService DEFAULT_REF_TEMPLATE_SWAGGER_2_0 = "#/definitions/{model}" -class RuleGeneratePayload(BaseModel): - instruction: str = Field(..., description="Rule generation instruction") - model_config_data: dict[str, Any] = Field(..., alias="model_config", description="Model configuration") - no_variable: bool = Field(default=False, description="Whether to exclude variables") - - -class RuleCodeGeneratePayload(RuleGeneratePayload): - code_language: str = Field(default="javascript", description="Programming language for code generation") - - -class RuleStructuredOutputPayload(BaseModel): - instruction: str = Field(..., description="Structured output generation instruction") - model_config_data: dict[str, Any] = Field(..., alias="model_config", description="Model configuration") - - class InstructionGeneratePayload(BaseModel): flow_id: str = Field(..., description="Workflow/Flow ID") node_id: str = Field(default="", description="Node ID for workflow context") current: str = Field(default="", description="Current instruction text") language: str = Field(default="javascript", description="Programming language (javascript/python)") instruction: str = Field(..., description="Instruction for generation") - model_config_data: dict[str, Any] = Field(..., alias="model_config", description="Model configuration") + model_config_data: ModelConfig = Field(..., alias="model_config", description="Model configuration") ideal_output: str = Field(default="", description="Expected ideal output") @@ -99,6 +86,7 @@ reg(InstructionGeneratePayload) reg(InstructionTemplatePayload) reg(ContextGeneratePayload) reg(SuggestedQuestionsPayload) +reg(ModelConfig) @console_ns.route("/rule-generate") @@ -117,12 +105,7 @@ class RuleGenerateApi(Resource): _, current_tenant_id = current_account_with_tenant() try: - rules = LLMGenerator.generate_rule_config( - tenant_id=current_tenant_id, - instruction=args.instruction, - model_config=args.model_config_data, - no_variable=args.no_variable, - ) + rules = LLMGenerator.generate_rule_config(tenant_id=current_tenant_id, args=args) except ProviderTokenNotInitError as ex: raise ProviderNotInitializeError(ex.description) except QuotaExceededError: @@ -153,9 +136,7 @@ class RuleCodeGenerateApi(Resource): try: code_result = LLMGenerator.generate_code( tenant_id=current_tenant_id, - instruction=args.instruction, - model_config=args.model_config_data, - code_language=args.code_language, + args=args, ) except ProviderTokenNotInitError as ex: raise ProviderNotInitializeError(ex.description) @@ -187,8 +168,7 @@ class RuleStructuredOutputGenerateApi(Resource): try: structured_output = LLMGenerator.generate_structured_output( tenant_id=current_tenant_id, - instruction=args.instruction, - model_config=args.model_config_data, + args=args, ) except ProviderTokenNotInitError as ex: raise ProviderNotInitializeError(ex.description) @@ -239,23 +219,29 @@ class InstructionGenerateApi(Resource): case "llm": return LLMGenerator.generate_rule_config( current_tenant_id, - instruction=args.instruction, - model_config=args.model_config_data, - no_variable=True, + args=RuleGeneratePayload( + instruction=args.instruction, + model_config=args.model_config_data, + no_variable=True, + ), ) case "agent": return LLMGenerator.generate_rule_config( current_tenant_id, - instruction=args.instruction, - model_config=args.model_config_data, - no_variable=True, + args=RuleGeneratePayload( + instruction=args.instruction, + model_config=args.model_config_data, + no_variable=True, + ), ) case "code": return LLMGenerator.generate_code( tenant_id=current_tenant_id, - instruction=args.instruction, - model_config=args.model_config_data, - code_language=args.language, + args=RuleCodeGeneratePayload( + instruction=args.instruction, + model_config=args.model_config_data, + code_language=args.language, + ), ) case _: return {"error": f"invalid node type: {node_type}"} diff --git a/api/controllers/console/feature.py b/api/controllers/console/feature.py index d3811e2d1b..1e98d622fe 100644 --- a/api/controllers/console/feature.py +++ b/api/controllers/console/feature.py @@ -1,60 +1,58 @@ -from flask_restx import Resource, fields +from pydantic import BaseModel, Field from werkzeug.exceptions import Unauthorized +from controllers.fastopenapi import console_router from libs.login import current_account_with_tenant, current_user, login_required -from services.feature_service import FeatureService +from services.feature_service import FeatureModel, FeatureService, SystemFeatureModel -from . import console_ns from .wraps import account_initialization_required, cloud_utm_record, setup_required -@console_ns.route("/features") -class FeatureApi(Resource): - @console_ns.doc("get_tenant_features") - @console_ns.doc(description="Get feature configuration for current tenant") - @console_ns.response( - 200, - "Success", - console_ns.model("FeatureResponse", {"features": fields.Raw(description="Feature configuration object")}), - ) - @setup_required - @login_required - @account_initialization_required - @cloud_utm_record - def get(self): - """Get feature configuration for current tenant""" - _, current_tenant_id = current_account_with_tenant() - - return FeatureService.get_features(current_tenant_id).model_dump() +class FeatureResponse(BaseModel): + features: FeatureModel = Field(description="Feature configuration object") -@console_ns.route("/system-features") -class SystemFeatureApi(Resource): - @console_ns.doc("get_system_features") - @console_ns.doc(description="Get system-wide feature configuration") - @console_ns.response( - 200, - "Success", - console_ns.model( - "SystemFeatureResponse", {"features": fields.Raw(description="System feature configuration object")} - ), - ) - def get(self): - """Get system-wide feature configuration +class SystemFeatureResponse(BaseModel): + features: SystemFeatureModel = Field(description="System feature configuration object") - NOTE: This endpoint is unauthenticated by design, as it provides system features - data required for dashboard initialization. - Authentication would create circular dependency (can't login without dashboard loading). +@console_router.get( + "/features", + response_model=FeatureResponse, + tags=["console"], +) +@setup_required +@login_required +@account_initialization_required +@cloud_utm_record +def get_tenant_features() -> FeatureResponse: + """Get feature configuration for current tenant.""" + _, current_tenant_id = current_account_with_tenant() - Only non-sensitive configuration data should be returned by this endpoint. - """ - # NOTE(QuantumGhost): ideally we should access `current_user.is_authenticated` - # without a try-catch. However, due to the implementation of user loader (the `load_user_from_request` - # in api/extensions/ext_login.py), accessing `current_user.is_authenticated` will - # raise `Unauthorized` exception if authentication token is not provided. - try: - is_authenticated = current_user.is_authenticated - except Unauthorized: - is_authenticated = False - return FeatureService.get_system_features(is_authenticated=is_authenticated).model_dump() + return FeatureResponse(features=FeatureService.get_features(current_tenant_id)) + + +@console_router.get( + "/system-features", + response_model=SystemFeatureResponse, + tags=["console"], +) +def get_system_features() -> SystemFeatureResponse: + """Get system-wide feature configuration + + NOTE: This endpoint is unauthenticated by design, as it provides system features + data required for dashboard initialization. + + Authentication would create circular dependency (can't login without dashboard loading). + + Only non-sensitive configuration data should be returned by this endpoint. + """ + # NOTE(QuantumGhost): ideally we should access `current_user.is_authenticated` + # without a try-catch. However, due to the implementation of user loader (the `load_user_from_request` + # in api/extensions/ext_login.py), accessing `current_user.is_authenticated` will + # raise `Unauthorized` exception if authentication token is not provided. + try: + is_authenticated = current_user.is_authenticated + except Unauthorized: + is_authenticated = False + return SystemFeatureResponse(features=FeatureService.get_system_features(is_authenticated=is_authenticated)) diff --git a/api/controllers/console/remote_files.py b/api/controllers/console/remote_files.py index 70c7b80ffa..88a9ce3a79 100644 --- a/api/controllers/console/remote_files.py +++ b/api/controllers/console/remote_files.py @@ -1,7 +1,6 @@ import urllib.parse import httpx -from flask_restx import Resource from pydantic import BaseModel, Field import services @@ -11,7 +10,7 @@ from controllers.common.errors import ( RemoteFileUploadError, UnsupportedFileTypeError, ) -from controllers.common.schema import register_schema_models +from controllers.fastopenapi import console_router from core.file import helpers as file_helpers from core.helper import ssrf_proxy from extensions.ext_database import db @@ -19,84 +18,74 @@ from fields.file_fields import FileWithSignedUrl, RemoteFileInfo from libs.login import current_account_with_tenant from services.file_service import FileService -from . import console_ns - -register_schema_models(console_ns, RemoteFileInfo, FileWithSignedUrl) - - -@console_ns.route("/remote-files/") -class RemoteFileInfoApi(Resource): - @console_ns.response(200, "Remote file info", console_ns.models[RemoteFileInfo.__name__]) - def get(self, url): - decoded_url = urllib.parse.unquote(url) - resp = ssrf_proxy.head(decoded_url) - if resp.status_code != httpx.codes.OK: - # failed back to get method - resp = ssrf_proxy.get(decoded_url, timeout=3) - resp.raise_for_status() - info = RemoteFileInfo( - file_type=resp.headers.get("Content-Type", "application/octet-stream"), - file_length=int(resp.headers.get("Content-Length", 0)), - ) - return info.model_dump(mode="json") - class RemoteFileUploadPayload(BaseModel): url: str = Field(..., description="URL to fetch") -console_ns.schema_model( - RemoteFileUploadPayload.__name__, - RemoteFileUploadPayload.model_json_schema(ref_template="#/definitions/{model}"), +@console_router.get( + "/remote-files/", + response_model=RemoteFileInfo, + tags=["console"], ) +def get_remote_file_info(url: str) -> RemoteFileInfo: + decoded_url = urllib.parse.unquote(url) + resp = ssrf_proxy.head(decoded_url) + if resp.status_code != httpx.codes.OK: + resp = ssrf_proxy.get(decoded_url, timeout=3) + resp.raise_for_status() + return RemoteFileInfo( + file_type=resp.headers.get("Content-Type", "application/octet-stream"), + file_length=int(resp.headers.get("Content-Length", 0)), + ) -@console_ns.route("/remote-files/upload") -class RemoteFileUploadApi(Resource): - @console_ns.expect(console_ns.models[RemoteFileUploadPayload.__name__]) - @console_ns.response(201, "Remote file uploaded", console_ns.models[FileWithSignedUrl.__name__]) - def post(self): - args = RemoteFileUploadPayload.model_validate(console_ns.payload) - url = args.url +@console_router.post( + "/remote-files/upload", + response_model=FileWithSignedUrl, + tags=["console"], + status_code=201, +) +def upload_remote_file(payload: RemoteFileUploadPayload) -> FileWithSignedUrl: + url = payload.url - try: - resp = ssrf_proxy.head(url=url) - if resp.status_code != httpx.codes.OK: - resp = ssrf_proxy.get(url=url, timeout=3, follow_redirects=True) - if resp.status_code != httpx.codes.OK: - raise RemoteFileUploadError(f"Failed to fetch file from {url}: {resp.text}") - except httpx.RequestError as e: - raise RemoteFileUploadError(f"Failed to fetch file from {url}: {str(e)}") + try: + resp = ssrf_proxy.head(url=url) + if resp.status_code != httpx.codes.OK: + resp = ssrf_proxy.get(url=url, timeout=3, follow_redirects=True) + if resp.status_code != httpx.codes.OK: + raise RemoteFileUploadError(f"Failed to fetch file from {url}: {resp.text}") + except httpx.RequestError as e: + raise RemoteFileUploadError(f"Failed to fetch file from {url}: {str(e)}") - file_info = helpers.guess_file_info_from_response(resp) + file_info = helpers.guess_file_info_from_response(resp) - if not FileService.is_file_size_within_limit(extension=file_info.extension, file_size=file_info.size): - raise FileTooLargeError + if not FileService.is_file_size_within_limit(extension=file_info.extension, file_size=file_info.size): + raise FileTooLargeError - content = resp.content if resp.request.method == "GET" else ssrf_proxy.get(url).content + content = resp.content if resp.request.method == "GET" else ssrf_proxy.get(url).content - try: - user, _ = current_account_with_tenant() - upload_file = FileService(db.engine).upload_file( - filename=file_info.filename, - content=content, - mimetype=file_info.mimetype, - user=user, - source_url=url, - ) - except services.errors.file.FileTooLargeError as file_too_large_error: - raise FileTooLargeError(file_too_large_error.description) - except services.errors.file.UnsupportedFileTypeError: - raise UnsupportedFileTypeError() - - payload = FileWithSignedUrl( - id=upload_file.id, - name=upload_file.name, - size=upload_file.size, - extension=upload_file.extension, - url=file_helpers.get_signed_file_url(upload_file_id=upload_file.id), - mime_type=upload_file.mime_type, - created_by=upload_file.created_by, - created_at=int(upload_file.created_at.timestamp()), + try: + user, _ = current_account_with_tenant() + upload_file = FileService(db.engine).upload_file( + filename=file_info.filename, + content=content, + mimetype=file_info.mimetype, + user=user, + source_url=url, ) - return payload.model_dump(mode="json"), 201 + except services.errors.file.FileTooLargeError as file_too_large_error: + raise FileTooLargeError(file_too_large_error.description) + except services.errors.file.UnsupportedFileTypeError: + raise UnsupportedFileTypeError() + + return FileWithSignedUrl( + id=upload_file.id, + name=upload_file.name, + size=upload_file.size, + extension=upload_file.extension, + url=file_helpers.get_signed_file_url(upload_file_id=upload_file.id), + mime_type=upload_file.mime_type, + created_by=upload_file.created_by, + created_at=int(upload_file.created_at.timestamp()), + ) diff --git a/api/core/llm_generator/entities.py b/api/core/llm_generator/entities.py new file mode 100644 index 0000000000..3bb8d2c899 --- /dev/null +++ b/api/core/llm_generator/entities.py @@ -0,0 +1,20 @@ +"""Shared payload models for LLM generator helpers and controllers.""" + +from pydantic import BaseModel, Field + +from core.app.app_config.entities import ModelConfig + + +class RuleGeneratePayload(BaseModel): + instruction: str = Field(..., description="Rule generation instruction") + model_config_data: ModelConfig = Field(..., alias="model_config", description="Model configuration") + no_variable: bool = Field(default=False, description="Whether to exclude variables") + + +class RuleCodeGeneratePayload(RuleGeneratePayload): + code_language: str = Field(default="javascript", description="Programming language for code generation") + + +class RuleStructuredOutputPayload(BaseModel): + instruction: str = Field(..., description="Structured output generation instruction") + model_config_data: ModelConfig = Field(..., alias="model_config", description="Model configuration") diff --git a/api/core/llm_generator/llm_generator.py b/api/core/llm_generator/llm_generator.py index 23ba87c031..51b3a332c1 100644 --- a/api/core/llm_generator/llm_generator.py +++ b/api/core/llm_generator/llm_generator.py @@ -6,11 +6,13 @@ from typing import Protocol import json_repair +from core.app.app_config.entities import ModelConfig from core.llm_generator.context_models import ( AvailableVarPayload, CodeContextPayload, ParameterInfoPayload, ) +from core.llm_generator.entities import RuleCodeGeneratePayload, RuleGeneratePayload, RuleStructuredOutputPayload from core.llm_generator.output_models import ( CodeNodeStructuredOutput, InstructionModifyOutput, @@ -158,19 +160,19 @@ class LLMGenerator: return questions @classmethod - def generate_rule_config(cls, tenant_id: str, instruction: str, model_config: dict, no_variable: bool): + def generate_rule_config(cls, tenant_id: str, args: RuleGeneratePayload): output_parser = RuleConfigGeneratorOutputParser() error = "" error_step = "" rule_config = {"prompt": "", "variables": [], "opening_statement": "", "error": ""} - model_parameters = model_config.get("completion_params", {}) - if no_variable: + model_parameters = args.model_config_data.completion_params + if args.no_variable: prompt_template = PromptTemplateParser(WORKFLOW_RULE_CONFIG_PROMPT_GENERATE_TEMPLATE) prompt_generate = prompt_template.format( inputs={ - "TASK_DESCRIPTION": instruction, + "TASK_DESCRIPTION": args.instruction, }, remove_template_variables=False, ) @@ -182,8 +184,8 @@ class LLMGenerator: model_instance = model_manager.get_model_instance( tenant_id=tenant_id, model_type=ModelType.LLM, - provider=model_config.get("provider", ""), - model=model_config.get("name", ""), + provider=args.model_config_data.provider, + model=args.model_config_data.name, ) try: @@ -197,7 +199,7 @@ class LLMGenerator: error = str(e) error_step = "generate rule config" except Exception as e: - logger.exception("Failed to generate rule config, model: %s", model_config.get("name")) + logger.exception("Failed to generate rule config, model: %s", args.model_config_data.name) rule_config["error"] = str(e) rule_config["error"] = f"Failed to {error_step}. Error: {error}" if error else "" @@ -216,7 +218,7 @@ class LLMGenerator: # format the prompt_generate_prompt prompt_generate_prompt = prompt_template.format( inputs={ - "TASK_DESCRIPTION": instruction, + "TASK_DESCRIPTION": args.instruction, }, remove_template_variables=False, ) @@ -227,8 +229,8 @@ class LLMGenerator: model_instance = model_manager.get_model_instance( tenant_id=tenant_id, model_type=ModelType.LLM, - provider=model_config.get("provider", ""), - model=model_config.get("name", ""), + provider=args.model_config_data.provider, + model=args.model_config_data.name, ) try: @@ -257,7 +259,7 @@ class LLMGenerator: # the second step to generate the task_parameter and task_statement statement_generate_prompt = statement_template.format( inputs={ - "TASK_DESCRIPTION": instruction, + "TASK_DESCRIPTION": args.instruction, "INPUT_TEXT": prompt_content.message.get_text_content(), }, remove_template_variables=False, @@ -283,7 +285,7 @@ class LLMGenerator: error_step = "generate conversation opener" except Exception as e: - logger.exception("Failed to generate rule config, model: %s", model_config.get("name")) + logger.exception("Failed to generate rule config, model: %s", args.model_config_data.name) rule_config["error"] = str(e) rule_config["error"] = f"Failed to {error_step}. Error: {error}" if error else "" @@ -291,16 +293,20 @@ class LLMGenerator: return rule_config @classmethod - def generate_code(cls, tenant_id: str, instruction: str, model_config: dict, code_language: str = "javascript"): - if code_language == "python": + def generate_code( + cls, + tenant_id: str, + args: RuleCodeGeneratePayload, + ): + if args.code_language == "python": prompt_template = PromptTemplateParser(PYTHON_CODE_GENERATOR_PROMPT_TEMPLATE) else: prompt_template = PromptTemplateParser(JAVASCRIPT_CODE_GENERATOR_PROMPT_TEMPLATE) prompt = prompt_template.format( inputs={ - "INSTRUCTION": instruction, - "CODE_LANGUAGE": code_language, + "INSTRUCTION": args.instruction, + "CODE_LANGUAGE": args.code_language, }, remove_template_variables=False, ) @@ -309,28 +315,28 @@ class LLMGenerator: model_instance = model_manager.get_model_instance( tenant_id=tenant_id, model_type=ModelType.LLM, - provider=model_config.get("provider", ""), - model=model_config.get("name", ""), + provider=args.model_config_data.provider, + model=args.model_config_data.name, ) prompt_messages = [UserPromptMessage(content=prompt)] - model_parameters = model_config.get("completion_params", {}) + model_parameters = args.model_config_data.completion_params try: response: LLMResult = model_instance.invoke_llm( prompt_messages=list(prompt_messages), model_parameters=model_parameters, stream=False ) generated_code = response.message.get_text_content() - return {"code": generated_code, "language": code_language, "error": ""} + return {"code": generated_code, "language": args.code_language, "error": ""} except InvokeError as e: error = str(e) - return {"code": "", "language": code_language, "error": f"Failed to generate code. Error: {error}"} + return {"code": "", "language": args.code_language, "error": f"Failed to generate code. Error: {error}"} except Exception as e: logger.exception( - "Failed to invoke LLM model, model: %s, language: %s", model_config.get("name"), code_language + "Failed to invoke LLM model, model: %s, language: %s", args.model_config_data.name, args.code_language ) - return {"code": "", "language": code_language, "error": f"An unexpected error occurred: {str(e)}"} + return {"code": "", "language": args.code_language, "error": f"An unexpected error occurred: {str(e)}"} @classmethod def generate_qa_document(cls, tenant_id: str, query, document_language: str): @@ -360,20 +366,20 @@ class LLMGenerator: return answer.strip() @classmethod - def generate_structured_output(cls, tenant_id: str, instruction: str, model_config: dict): + def generate_structured_output(cls, tenant_id: str, args: RuleStructuredOutputPayload): model_manager = ModelManager() model_instance = model_manager.get_model_instance( tenant_id=tenant_id, model_type=ModelType.LLM, - provider=model_config.get("provider", ""), - model=model_config.get("name", ""), + provider=args.model_config_data.provider, + model=args.model_config_data.name, ) prompt_messages = [ SystemPromptMessage(content=SYSTEM_STRUCTURED_OUTPUT_GENERATE), - UserPromptMessage(content=instruction), + UserPromptMessage(content=args.instruction), ] - model_parameters = model_config.get("model_parameters", {}) + model_parameters = args.model_config_data.completion_params try: response: LLMResult = model_instance.invoke_llm( @@ -397,7 +403,7 @@ class LLMGenerator: error = str(e) return {"output": "", "error": f"Failed to generate JSON Schema. Error: {error}"} except Exception as e: - logger.exception("Failed to invoke LLM model, model: %s", model_config.get("name")) + logger.exception("Failed to invoke LLM model, model: %s", args.model_config_data.name) return {"output": "", "error": f"An unexpected error occurred: {str(e)}"} @classmethod @@ -670,7 +676,12 @@ Generate {language} code to extract/transform available variables for the target @staticmethod def instruction_modify_legacy( - tenant_id: str, flow_id: str, current: str, instruction: str, model_config: dict, ideal_output: str | None + tenant_id: str, + flow_id: str, + current: str, + instruction: str, + model_config: ModelConfig, + ideal_output: str | None, ): last_run: Message | None = ( db.session.query(Message).where(Message.app_id == flow_id).order_by(Message.created_at.desc()).first() @@ -709,7 +720,7 @@ Generate {language} code to extract/transform available variables for the target node_id: str, current: str, instruction: str, - model_config: dict, + model_config: ModelConfig, ideal_output: str | None, workflow_service: WorkflowServiceInterface, ): @@ -782,7 +793,7 @@ Generate {language} code to extract/transform available variables for the target @staticmethod def __instruction_modify_common( tenant_id: str, - model_config: dict, + model_config: ModelConfig, last_run: dict | None, current: str | None, error_message: str | None, @@ -803,8 +814,8 @@ Generate {language} code to extract/transform available variables for the target model_instance = ModelManager().get_model_instance( tenant_id=tenant_id, model_type=ModelType.LLM, - provider=model_config.get("provider", ""), - model=model_config.get("name", ""), + provider=model_config.provider, + model=model_config.name, ) model_name = model_config.get("name", "") model_schema = model_instance.model_type_instance.get_model_schema(model_name, model_instance.credentials) @@ -845,7 +856,5 @@ Generate {language} code to extract/transform available variables for the target error = str(e) return {"error": f"Failed to generate code. Error: {error}"} except Exception as e: - logger.exception( - "Failed to invoke LLM model, model: %s", json.dumps(model_config.get("name")), exc_info=True - ) + logger.exception("Failed to invoke LLM model, model: %s", json.dumps(model_config.name), exc_info=True) return {"error": f"An unexpected error occurred: {str(e)}"} diff --git a/api/core/mcp/session/base_session.py b/api/core/mcp/session/base_session.py index 84a6fd0d1f..e1a40593e7 100644 --- a/api/core/mcp/session/base_session.py +++ b/api/core/mcp/session/base_session.py @@ -347,7 +347,7 @@ class BaseSession( message.message.root.model_dump(by_alias=True, mode="json", exclude_none=True) ) - responder = RequestResponder( + responder = RequestResponder[ReceiveRequestT, SendResultT]( request_id=message.message.root.id, request_meta=validated_request.root.params.meta if validated_request.root.params else None, request=validated_request, diff --git a/api/core/model_runtime/model_providers/__base/large_language_model.py b/api/core/model_runtime/model_providers/__base/large_language_model.py index 7a0757f219..bbbdec61d1 100644 --- a/api/core/model_runtime/model_providers/__base/large_language_model.py +++ b/api/core/model_runtime/model_providers/__base/large_language_model.py @@ -92,6 +92,10 @@ def _build_llm_result_from_first_chunk( Build a single `LLMResult` from the first returned chunk. This is used for `stream=False` because the plugin side may still implement the response via a chunked stream. + + Note: + This function always drains the `chunks` iterator after reading the first chunk to ensure any underlying + streaming resources are released (e.g., HTTP connections owned by the plugin runtime). """ content = "" content_list: list[PromptMessageContentUnionTypes] = [] @@ -99,18 +103,25 @@ def _build_llm_result_from_first_chunk( system_fingerprint: str | None = None tools_calls: list[AssistantPromptMessage.ToolCall] = [] - first_chunk = next(chunks, None) - if first_chunk is not None: - if isinstance(first_chunk.delta.message.content, str): - content += first_chunk.delta.message.content - elif isinstance(first_chunk.delta.message.content, list): - content_list.extend(first_chunk.delta.message.content) + try: + first_chunk = next(chunks, None) + if first_chunk is not None: + if isinstance(first_chunk.delta.message.content, str): + content += first_chunk.delta.message.content + elif isinstance(first_chunk.delta.message.content, list): + content_list.extend(first_chunk.delta.message.content) - if first_chunk.delta.message.tool_calls: - _increase_tool_call(first_chunk.delta.message.tool_calls, tools_calls) + if first_chunk.delta.message.tool_calls: + _increase_tool_call(first_chunk.delta.message.tool_calls, tools_calls) - usage = first_chunk.delta.usage or LLMUsage.empty_usage() - system_fingerprint = first_chunk.system_fingerprint + usage = first_chunk.delta.usage or LLMUsage.empty_usage() + system_fingerprint = first_chunk.system_fingerprint + finally: + try: + for _ in chunks: + pass + except Exception: + logger.debug("Failed to drain non-stream plugin chunk iterator.", exc_info=True) return LLMResult( model=model, @@ -283,7 +294,7 @@ class LargeLanguageModel(AIModel): # TODO raise self._transform_invoke_error(e) - if stream and isinstance(result, Generator): + if stream and not isinstance(result, LLMResult): return self._invoke_result_generator( model=model, result=result, diff --git a/api/core/model_runtime/model_providers/model_provider_factory.py b/api/core/model_runtime/model_providers/model_provider_factory.py index 64538a6779..9cfc6889ac 100644 --- a/api/core/model_runtime/model_providers/model_provider_factory.py +++ b/api/core/model_runtime/model_providers/model_provider_factory.py @@ -314,6 +314,8 @@ class ModelProviderFactory: elif model_type == ModelType.TTS: return TTSModel.model_validate(init_params) + raise ValueError(f"Unsupported model type: {model_type}") + def get_provider_icon(self, provider: str, icon_type: str, lang: str) -> tuple[bytes, str]: """ Get provider icon diff --git a/api/core/trigger/debug/event_bus.py b/api/core/trigger/debug/event_bus.py index 9d10e1a0e0..e3fb6a13d9 100644 --- a/api/core/trigger/debug/event_bus.py +++ b/api/core/trigger/debug/event_bus.py @@ -23,8 +23,8 @@ class TriggerDebugEventBus: """ # LUA_SELECT: Atomic poll or register for event - # KEYS[1] = trigger_debug_inbox:{tenant_id}:{address_id} - # KEYS[2] = trigger_debug_waiting_pool:{tenant_id}:... + # KEYS[1] = trigger_debug_inbox:{}: + # KEYS[2] = trigger_debug_waiting_pool:{}:... # ARGV[1] = address_id LUA_SELECT = ( "local v=redis.call('GET',KEYS[1]);" @@ -35,7 +35,7 @@ class TriggerDebugEventBus: ) # LUA_DISPATCH: Dispatch event to all waiting addresses - # KEYS[1] = trigger_debug_waiting_pool:{tenant_id}:... + # KEYS[1] = trigger_debug_waiting_pool:{}:... # ARGV[1] = tenant_id # ARGV[2] = event_json LUA_DISPATCH = ( @@ -43,7 +43,7 @@ class TriggerDebugEventBus: "if #a==0 then return 0 end;" "redis.call('DEL',KEYS[1]);" "for i=1,#a do " - f"redis.call('SET','trigger_debug_inbox:'..ARGV[1]..':'..a[i],ARGV[2],'EX',{TRIGGER_DEBUG_EVENT_TTL});" + f"redis.call('SET','trigger_debug_inbox:{{'..ARGV[1]..'}}'..':'..a[i],ARGV[2],'EX',{TRIGGER_DEBUG_EVENT_TTL});" "end;" "return #a" ) @@ -108,7 +108,7 @@ class TriggerDebugEventBus: Event object if available, None otherwise """ address_id: str = hashlib.sha256(f"{user_id}|{app_id}|{node_id}".encode()).hexdigest() - address: str = f"trigger_debug_inbox:{tenant_id}:{address_id}" + address: str = f"trigger_debug_inbox:{{{tenant_id}}}:{address_id}" try: event_data = redis_client.eval( diff --git a/api/core/trigger/debug/events.py b/api/core/trigger/debug/events.py index 9f7bab5e49..9aec342ed1 100644 --- a/api/core/trigger/debug/events.py +++ b/api/core/trigger/debug/events.py @@ -42,7 +42,7 @@ def build_webhook_pool_key(tenant_id: str, app_id: str, node_id: str) -> str: app_id: App ID node_id: Node ID """ - return f"{TriggerDebugPoolKey.WEBHOOK}:{tenant_id}:{app_id}:{node_id}" + return f"{TriggerDebugPoolKey.WEBHOOK}:{{{tenant_id}}}:{app_id}:{node_id}" class PluginTriggerDebugEvent(BaseDebugEvent): @@ -64,4 +64,4 @@ def build_plugin_pool_key(tenant_id: str, provider_id: str, subscription_id: str provider_id: Provider ID subscription_id: Subscription ID """ - return f"{TriggerDebugPoolKey.PLUGIN}:{tenant_id}:{str(provider_id)}:{subscription_id}:{name}" + return f"{TriggerDebugPoolKey.PLUGIN}:{{{tenant_id}}}:{str(provider_id)}:{subscription_id}:{name}" diff --git a/api/extensions/ext_fastopenapi.py b/api/extensions/ext_fastopenapi.py index e6c1bc6bee..719456803a 100644 --- a/api/extensions/ext_fastopenapi.py +++ b/api/extensions/ext_fastopenapi.py @@ -28,9 +28,10 @@ def init_app(app: DifyApp) -> None: # Ensure route decorators are evaluated. import controllers.console.ping as ping_module - from controllers.console import setup + from controllers.console import remote_files, setup _ = ping_module + _ = remote_files _ = setup router.include_router(console_router, prefix="/console/api") diff --git a/api/libs/gmpy2_pkcs10aep_cipher.py b/api/libs/gmpy2_pkcs10aep_cipher.py index 23eb8dca05..ef26699fb3 100644 --- a/api/libs/gmpy2_pkcs10aep_cipher.py +++ b/api/libs/gmpy2_pkcs10aep_cipher.py @@ -136,7 +136,7 @@ class PKCS1OAepCipher: # Step 3a (OS2IP) em_int = bytes_to_long(em) # Step 3b (RSAEP) - m_int = gmpy2.powmod(em_int, self._key.e, self._key.n) + m_int: int = gmpy2.powmod(em_int, self._key.e, self._key.n) # type: ignore[attr-defined] # Step 3c (I2OSP) c = long_to_bytes(m_int, k) return c @@ -169,7 +169,7 @@ class PKCS1OAepCipher: ct_int = bytes_to_long(ciphertext) # Step 2b (RSADP) # m_int = self._key._decrypt(ct_int) - m_int = gmpy2.powmod(ct_int, self._key.d, self._key.n) + m_int: int = gmpy2.powmod(ct_int, self._key.d, self._key.n) # type: ignore[attr-defined] # Complete step 2c (I2OSP) em = long_to_bytes(m_int, k) # Step 3a diff --git a/api/migrations/versions/2026_01_27_1815-788d3099ae3a_add_summary_index_feature.py b/api/migrations/versions/2026_01_27_1815-788d3099ae3a_add_summary_index_feature.py index 3c2e0822e1..c6c72859dc 100644 --- a/api/migrations/versions/2026_01_27_1815-788d3099ae3a_add_summary_index_feature.py +++ b/api/migrations/versions/2026_01_27_1815-788d3099ae3a_add_summary_index_feature.py @@ -51,7 +51,7 @@ def upgrade(): batch_op.add_column(sa.Column('summary_index_setting', models.types.AdjustedJSON(), nullable=True)) with op.batch_alter_table('documents', schema=None) as batch_op: - batch_op.add_column(sa.Column('need_summary', sa.Boolean(), server_default=sa.text('false'), nullable=True)) + batch_op.add_column(sa.Column('need_summary', sa.Boolean(), server_default=sa.text('false'), nullable=False)) else: # MySQL: Use compatible syntax op.create_table( @@ -83,7 +83,7 @@ def upgrade(): batch_op.add_column(sa.Column('summary_index_setting', models.types.AdjustedJSON(), nullable=True)) with op.batch_alter_table('documents', schema=None) as batch_op: - batch_op.add_column(sa.Column('need_summary', sa.Boolean(), server_default=sa.text('false'), nullable=True)) + batch_op.add_column(sa.Column('need_summary', sa.Boolean(), server_default=sa.text('false'), nullable=False)) # ### end Alembic commands ### diff --git a/api/models/dataset.py b/api/models/dataset.py index 6ab8f372bf..e7da2961bc 100644 --- a/api/models/dataset.py +++ b/api/models/dataset.py @@ -420,7 +420,7 @@ class Document(Base): doc_metadata = mapped_column(AdjustedJSON, nullable=True) doc_form = mapped_column(String(255), nullable=False, server_default=sa.text("'text_model'")) doc_language = mapped_column(String(255), nullable=True) - need_summary: Mapped[bool | None] = mapped_column(sa.Boolean, nullable=True, server_default=sa.text("false")) + need_summary: Mapped[bool] = mapped_column(sa.Boolean, nullable=False, server_default=sa.text("false")) DATA_SOURCES = ["upload_file", "notion_import", "website_crawl"] diff --git a/api/pyproject.toml b/api/pyproject.toml index 40a598629f..0b4cba1c7e 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "dify-api" -version = "1.11.4" +version = "1.12.0" requires-python = ">=3.11,<3.13" dependencies = [ diff --git a/api/tests/unit_tests/controllers/console/test_fastopenapi_feature.py b/api/tests/unit_tests/controllers/console/test_fastopenapi_feature.py new file mode 100644 index 0000000000..68495dd979 --- /dev/null +++ b/api/tests/unit_tests/controllers/console/test_fastopenapi_feature.py @@ -0,0 +1,291 @@ +import builtins +import contextlib +import importlib +import sys +from unittest.mock import MagicMock, PropertyMock, patch + +import pytest +from flask import Flask +from flask.views import MethodView +from werkzeug.exceptions import Unauthorized + +from extensions import ext_fastopenapi +from extensions.ext_database import db +from services.feature_service import FeatureModel, SystemFeatureModel + + +@pytest.fixture +def app(): + """ + Creates a Flask application instance configured for testing. + """ + app = Flask(__name__) + app.config["TESTING"] = True + app.config["SECRET_KEY"] = "test-secret" + app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///:memory:" + + # Initialize the database with the app + db.init_app(app) + + return app + + +@pytest.fixture(autouse=True) +def fix_method_view_issue(monkeypatch): + """ + Automatic fixture to patch 'builtins.MethodView'. + + Why this is needed: + The official legacy codebase contains a global patch in its initialization logic: + if not hasattr(builtins, "MethodView"): + builtins.MethodView = MethodView + + Some dependencies (like ext_fastopenapi or older Flask extensions) might implicitly + rely on 'MethodView' being available in the global builtins namespace. + + Refactoring Note: + While patching builtins is generally discouraged due to global side effects, + this fixture reproduces the production environment's state to ensure tests are realistic. + We use 'monkeypatch' to ensure that this change is undone after the test finishes, + keeping other tests isolated. + """ + if not hasattr(builtins, "MethodView"): + # 'raising=False' allows us to set an attribute that doesn't exist yet + monkeypatch.setattr(builtins, "MethodView", MethodView, raising=False) + + +# ------------------------------------------------------------------------------ +# Helper Functions for Fixture Complexity Reduction +# ------------------------------------------------------------------------------ + + +def _create_isolated_router(): + """ + Creates a fresh, isolated router instance to prevent route pollution. + """ + import controllers.fastopenapi + + # Dynamically get the class type (e.g., FlaskRouter) to avoid hardcoding dependencies + RouterClass = type(controllers.fastopenapi.console_router) + return RouterClass() + + +@contextlib.contextmanager +def _patch_auth_and_router(temp_router): + """ + Context manager that applies all necessary patches for: + 1. The console_router (redirecting to our isolated temp_router) + 2. Authentication decorators (disabling them with no-ops) + 3. User/Account loaders (mocking authenticated state) + """ + + def noop(f): + return f + + # We patch the SOURCE of the decorators/functions, not the destination module. + # This ensures that when 'controllers.console.feature' imports them, it gets the mocks. + with ( + patch("controllers.fastopenapi.console_router", temp_router), + patch("extensions.ext_fastopenapi.console_router", temp_router), + patch("controllers.console.wraps.setup_required", side_effect=noop), + patch("libs.login.login_required", side_effect=noop), + patch("controllers.console.wraps.account_initialization_required", side_effect=noop), + patch("controllers.console.wraps.cloud_utm_record", side_effect=noop), + patch("libs.login.current_account_with_tenant", return_value=(MagicMock(), "tenant-id")), + patch("libs.login.current_user", MagicMock(is_authenticated=True)), + ): + # Explicitly reload ext_fastopenapi to ensure it uses the patched console_router + import extensions.ext_fastopenapi + + importlib.reload(extensions.ext_fastopenapi) + + yield + + +def _force_reload_module(target_module: str, alias_module: str): + """ + Forces a reload of the specified module and handles sys.modules aliasing. + + Why reload? + Python decorators (like @route, @login_required) run at IMPORT time. + To apply our patches (mocks/no-ops) to these decorators, we must re-import + the module while the patches are active. + + Why alias? + If 'ext_fastopenapi' imports the controller as 'api.controllers...', but we import + it as 'controllers...', Python treats them as two separate modules. This causes: + 1. Double execution of decorators (registering routes twice -> AssertionError). + 2. Type mismatch errors (Class A from module X is not Class A from module Y). + + This function ensures both names point to the SAME loaded module instance. + """ + # 1. Clean existing entries to force re-import + if target_module in sys.modules: + del sys.modules[target_module] + if alias_module in sys.modules: + del sys.modules[alias_module] + + # 2. Import the module (triggering decorators with active patches) + module = importlib.import_module(target_module) + + # 3. Alias the module in sys.modules to prevent double loading + sys.modules[alias_module] = sys.modules[target_module] + + return module + + +def _cleanup_modules(target_module: str, alias_module: str): + """ + Removes the module and its alias from sys.modules to prevent side effects + on other tests. + """ + if target_module in sys.modules: + del sys.modules[target_module] + if alias_module in sys.modules: + del sys.modules[alias_module] + + +@pytest.fixture +def mock_feature_module_env(): + """ + Sets up a mocked environment for the feature module. + + This fixture orchestrates: + 1. Creating an isolated router. + 2. Patching authentication and global dependencies. + 3. Reloading the controller module to apply patches to decorators. + 4. cleaning up sys.modules afterwards. + """ + target_module = "controllers.console.feature" + alias_module = "api.controllers.console.feature" + + # 1. Prepare isolated router + temp_router = _create_isolated_router() + + # 2. Apply patches + try: + with _patch_auth_and_router(temp_router): + # 3. Reload module to register routes on the temp_router + feature_module = _force_reload_module(target_module, alias_module) + + yield feature_module + + finally: + # 4. Teardown: Clean up sys.modules + _cleanup_modules(target_module, alias_module) + + +# ------------------------------------------------------------------------------ +# Test Cases +# ------------------------------------------------------------------------------ + + +@pytest.mark.parametrize( + ("url", "service_mock_path", "mock_model_instance", "json_key"), + [ + ( + "/console/api/features", + "controllers.console.feature.FeatureService.get_features", + FeatureModel(can_replace_logo=True), + "features", + ), + ( + "/console/api/system-features", + "controllers.console.feature.FeatureService.get_system_features", + SystemFeatureModel(enable_marketplace=True), + "features", + ), + ], +) +def test_console_features_success(app, mock_feature_module_env, url, service_mock_path, mock_model_instance, json_key): + """ + Tests that the feature APIs return a 200 OK status and correct JSON structure. + """ + # Patch the service layer to return our mock model instance + with patch(service_mock_path, return_value=mock_model_instance): + # Initialize the API extension + ext_fastopenapi.init_app(app) + + client = app.test_client() + response = client.get(url) + + # Assertions + assert response.status_code == 200, f"Request failed with status {response.status_code}: {response.text}" + + # Verify the JSON response matches the Pydantic model dump + expected_data = mock_model_instance.model_dump(mode="json") + assert response.get_json() == {json_key: expected_data} + + +@pytest.mark.parametrize( + ("url", "service_mock_path"), + [ + ("/console/api/features", "controllers.console.feature.FeatureService.get_features"), + ("/console/api/system-features", "controllers.console.feature.FeatureService.get_system_features"), + ], +) +def test_console_features_service_error(app, mock_feature_module_env, url, service_mock_path): + """ + Tests how the application handles Service layer errors. + + Note: When an exception occurs in the view, it is typically caught by the framework + (Flask or the OpenAPI wrapper) and converted to a 500 error response. + This test verifies that the application returns a 500 status code. + """ + # Simulate a service failure + with patch(service_mock_path, side_effect=ValueError("Service Failure")): + ext_fastopenapi.init_app(app) + client = app.test_client() + + # When an exception occurs in the view, it is typically caught by the framework + # (Flask or the OpenAPI wrapper) and converted to a 500 error response. + response = client.get(url) + + assert response.status_code == 500 + # Check if the error details are exposed in the response (depends on error handler config) + # We accept either generic 500 or the specific error message + assert "Service Failure" in response.text or "Internal Server Error" in response.text + + +def test_system_features_unauthenticated(app, mock_feature_module_env): + """ + Tests that /console/api/system-features endpoint works without authentication. + + This test verifies the try-except block in get_system_features that handles + unauthenticated requests by passing is_authenticated=False to the service layer. + """ + feature_module = mock_feature_module_env + + # Override the behavior of the current_user mock + # The fixture patched 'libs.login.current_user', so 'controllers.console.feature.current_user' + # refers to that same Mock object. + mock_user = feature_module.current_user + + # Simulate property access raising Unauthorized + # Note: We must reset side_effect if it was set, or set it here. + # The fixture initialized it as MagicMock(is_authenticated=True). + # We want type(mock_user).is_authenticated to raise Unauthorized. + type(mock_user).is_authenticated = PropertyMock(side_effect=Unauthorized) + + # Patch the service layer for this specific test + with patch("controllers.console.feature.FeatureService.get_system_features") as mock_service: + # Setup mock service return value + mock_model = SystemFeatureModel(enable_marketplace=True) + mock_service.return_value = mock_model + + # Initialize app + ext_fastopenapi.init_app(app) + client = app.test_client() + + # Act + response = client.get("/console/api/system-features") + + # Assert + assert response.status_code == 200, f"Request failed: {response.text}" + + # Verify service was called with is_authenticated=False + mock_service.assert_called_once_with(is_authenticated=False) + + # Verify response body + expected_data = mock_model.model_dump(mode="json") + assert response.get_json() == {"features": expected_data} diff --git a/api/tests/unit_tests/controllers/console/test_fastopenapi_remote_files.py b/api/tests/unit_tests/controllers/console/test_fastopenapi_remote_files.py new file mode 100644 index 0000000000..cb2604cf1c --- /dev/null +++ b/api/tests/unit_tests/controllers/console/test_fastopenapi_remote_files.py @@ -0,0 +1,92 @@ +import builtins +from datetime import datetime +from types import SimpleNamespace +from unittest.mock import patch + +import httpx +import pytest +from flask import Flask +from flask.views import MethodView + +from extensions import ext_fastopenapi + +if not hasattr(builtins, "MethodView"): + builtins.MethodView = MethodView # type: ignore[attr-defined] + + +@pytest.fixture +def app() -> Flask: + app = Flask(__name__) + app.config["TESTING"] = True + return app + + +def test_console_remote_files_fastopenapi_get_info(app: Flask): + ext_fastopenapi.init_app(app) + + response = httpx.Response( + 200, + request=httpx.Request("HEAD", "http://example.com/file.txt"), + headers={"Content-Type": "text/plain", "Content-Length": "10"}, + ) + + with patch("controllers.console.remote_files.ssrf_proxy.head", return_value=response): + client = app.test_client() + encoded_url = "http%3A%2F%2Fexample.com%2Ffile.txt" + resp = client.get(f"/console/api/remote-files/{encoded_url}") + + assert resp.status_code == 200 + assert resp.get_json() == {"file_type": "text/plain", "file_length": 10} + + +def test_console_remote_files_fastopenapi_upload(app: Flask): + ext_fastopenapi.init_app(app) + + head_response = httpx.Response( + 200, + request=httpx.Request("GET", "http://example.com/file.txt"), + content=b"hello", + ) + file_info = SimpleNamespace( + extension="txt", + size=5, + filename="file.txt", + mimetype="text/plain", + ) + uploaded = SimpleNamespace( + id="file-id", + name="file.txt", + size=5, + extension="txt", + mime_type="text/plain", + created_by="user-id", + created_at=datetime(2024, 1, 1), + ) + + with ( + patch("controllers.console.remote_files.db", new=SimpleNamespace(engine=object())), + patch("controllers.console.remote_files.ssrf_proxy.head", return_value=head_response), + patch("controllers.console.remote_files.helpers.guess_file_info_from_response", return_value=file_info), + patch("controllers.console.remote_files.FileService.is_file_size_within_limit", return_value=True), + patch("controllers.console.remote_files.FileService.__init__", return_value=None), + patch("controllers.console.remote_files.current_account_with_tenant", return_value=(object(), "tenant-id")), + patch("controllers.console.remote_files.FileService.upload_file", return_value=uploaded), + patch("controllers.console.remote_files.file_helpers.get_signed_file_url", return_value="signed-url"), + ): + client = app.test_client() + resp = client.post( + "/console/api/remote-files/upload", + json={"url": "http://example.com/file.txt"}, + ) + + assert resp.status_code == 201 + assert resp.get_json() == { + "id": "file-id", + "name": "file.txt", + "size": 5, + "extension": "txt", + "url": "signed-url", + "mime_type": "text/plain", + "created_by": "user-id", + "created_at": int(uploaded.created_at.timestamp()), + } diff --git a/api/tests/unit_tests/core/model_runtime/__base/test_large_language_model_non_stream_parsing.py b/api/tests/unit_tests/core/model_runtime/__base/test_large_language_model_non_stream_parsing.py index 91352b2a5f..cfdeef6a8d 100644 --- a/api/tests/unit_tests/core/model_runtime/__base/test_large_language_model_non_stream_parsing.py +++ b/api/tests/unit_tests/core/model_runtime/__base/test_large_language_model_non_stream_parsing.py @@ -101,3 +101,26 @@ def test__normalize_non_stream_plugin_result__empty_iterator_defaults(): assert result.message.tool_calls == [] assert result.usage == LLMUsage.empty_usage() assert result.system_fingerprint is None + + +def test__normalize_non_stream_plugin_result__closes_chunk_iterator(): + prompt_messages = [UserPromptMessage(content="hi")] + + chunk = _make_chunk(content="hello", usage=LLMUsage.empty_usage()) + closed: list[bool] = [] + + def _chunk_iter(): + try: + yield chunk + yield _make_chunk(content="ignored", usage=LLMUsage.empty_usage()) + finally: + closed.append(True) + + result = _normalize_non_stream_plugin_result( + model="test-model", + prompt_messages=prompt_messages, + result=_chunk_iter(), + ) + + assert result.message.content == "hello" + assert closed == [True] diff --git a/api/ty.toml b/api/ty.toml index 640ed6cdee..afdd37897e 100644 --- a/api/ty.toml +++ b/api/ty.toml @@ -1,11 +1,6 @@ [src] exclude = [ # deps groups (A1/A2/B/C/D/E) - # A1: foundational runtime typing / provider plumbing - "core/mcp/session", - "core/model_runtime/model_providers", - "core/workflow/nodes/protocols.py", - "libs/gmpy2_pkcs10aep_cipher.py", # A2: workflow engine/nodes "core/workflow", "core/app/workflow", @@ -33,6 +28,3 @@ exclude = [ "tests", ] -[rules] -missing-argument = "ignore" # TODO: restore when **args for constructor is supported properly -possibly-unbound-attribute = "ignore" diff --git a/api/uv.lock b/api/uv.lock index 1d959782da..5fc64fb62e 100644 --- a/api/uv.lock +++ b/api/uv.lock @@ -1486,7 +1486,7 @@ wheels = [ [[package]] name = "dify-api" -version = "1.11.4" +version = "1.12.0" source = { virtual = "." } dependencies = [ { name = "aliyun-log-python-sdk" }, diff --git a/docker/docker-compose-template.yaml b/docker/docker-compose-template.yaml index 1740161b7b..cc4240edcd 100644 --- a/docker/docker-compose-template.yaml +++ b/docker/docker-compose-template.yaml @@ -21,7 +21,7 @@ services: # API service api: - image: langgenius/dify-api:1.11.4 + image: langgenius/dify-api:1.12.0 restart: always environment: # Use the shared environment variables. @@ -63,7 +63,7 @@ services: # worker service # The Celery worker for processing all queues (dataset, workflow, mail, etc.) worker: - image: langgenius/dify-api:1.11.4 + image: langgenius/dify-api:1.12.0 restart: always environment: # Use the shared environment variables. @@ -102,7 +102,7 @@ services: # worker_beat service # Celery beat for scheduling periodic tasks. worker_beat: - image: langgenius/dify-api:1.11.4 + image: langgenius/dify-api:1.12.0 restart: always environment: # Use the shared environment variables. @@ -132,7 +132,7 @@ services: # Frontend web application. web: - image: langgenius/dify-web:1.11.4 + image: langgenius/dify-web:1.12.0 restart: always environment: CONSOLE_API_URL: ${CONSOLE_API_URL:-} @@ -271,7 +271,7 @@ services: # plugin daemon plugin_daemon: - image: langgenius/dify-plugin-daemon:0.5.2-local + image: langgenius/dify-plugin-daemon:0.5.3-local restart: always environment: # Use the shared environment variables. diff --git a/docker/docker-compose.middleware.yaml b/docker/docker-compose.middleware.yaml index 81c34fc6a2..4a739bbbe0 100644 --- a/docker/docker-compose.middleware.yaml +++ b/docker/docker-compose.middleware.yaml @@ -123,7 +123,7 @@ services: # plugin daemon plugin_daemon: - image: langgenius/dify-plugin-daemon:0.5.2-local + image: langgenius/dify-plugin-daemon:0.5.3-local restart: always env_file: - ./middleware.env diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 7f08b39e5c..f0d4fdc292 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -709,7 +709,7 @@ services: # API service api: - image: langgenius/dify-api:1.11.4 + image: langgenius/dify-api:1.12.0 restart: always environment: # Use the shared environment variables. @@ -751,7 +751,7 @@ services: # worker service # The Celery worker for processing all queues (dataset, workflow, mail, etc.) worker: - image: langgenius/dify-api:1.11.4 + image: langgenius/dify-api:1.12.0 restart: always environment: # Use the shared environment variables. @@ -790,7 +790,7 @@ services: # worker_beat service # Celery beat for scheduling periodic tasks. worker_beat: - image: langgenius/dify-api:1.11.4 + image: langgenius/dify-api:1.12.0 restart: always environment: # Use the shared environment variables. @@ -820,7 +820,7 @@ services: # Frontend web application. web: - image: langgenius/dify-web:1.11.4 + image: langgenius/dify-web:1.12.0 restart: always environment: CONSOLE_API_URL: ${CONSOLE_API_URL:-} @@ -959,7 +959,7 @@ services: # plugin daemon plugin_daemon: - image: langgenius/dify-plugin-daemon:0.5.2-local + image: langgenius/dify-plugin-daemon:0.5.3-local restart: always environment: # Use the shared environment variables. diff --git a/web/app/components/explore/sidebar/no-apps/index.tsx b/web/app/components/explore/sidebar/no-apps/index.tsx index 39b425ce35..f2f406008b 100644 --- a/web/app/components/explore/sidebar/no-apps/index.tsx +++ b/web/app/components/explore/sidebar/no-apps/index.tsx @@ -2,6 +2,7 @@ import type { FC } from 'react' import * as React from 'react' import { useTranslation } from 'react-i18next' +import { useDocLink } from '@/context/i18n' import useTheme from '@/hooks/use-theme' import { Theme } from '@/types/app' import { cn } from '@/utils/classnames' @@ -12,12 +13,13 @@ const i18nPrefix = 'sidebar.noApps' const NoApps: FC = () => { const { t } = useTranslation() const { theme } = useTheme() + const docLink = useDocLink() return (
{t(`${i18nPrefix}.title`, { ns: 'explore' })}
{t(`${i18nPrefix}.description`, { ns: 'explore' })}
- {t(`${i18nPrefix}.learnMore`, { ns: 'explore' })} + {t(`${i18nPrefix}.learnMore`, { ns: 'explore' })}
) } diff --git a/web/app/components/explore/try-app/tab.tsx b/web/app/components/explore/try-app/tab.tsx index cbd8e1db85..55d0900fad 100644 --- a/web/app/components/explore/try-app/tab.tsx +++ b/web/app/components/explore/try-app/tab.tsx @@ -2,6 +2,7 @@ import type { FC } from 'react' import * as React from 'react' import { useTranslation } from 'react-i18next' +import { IS_CLOUD_EDITION } from '@/config' import TabHeader from '../../base/tab-header' export enum TypeEnum { @@ -21,10 +22,13 @@ const Tab: FC = ({ disableTry, }) => { const { t } = useTranslation() - const tabs = [ - { id: TypeEnum.TRY, name: t('tryApp.tabHeader.try', { ns: 'explore' }), disabled: disableTry }, - { id: TypeEnum.DETAIL, name: t('tryApp.tabHeader.detail', { ns: 'explore' }) }, - ] + + const tabs = React.useMemo(() => { + return [ + IS_CLOUD_EDITION ? { id: TypeEnum.TRY, name: t('tryApp.tabHeader.try', { ns: 'explore' }), disabled: disableTry } : null, + { id: TypeEnum.DETAIL, name: t('tryApp.tabHeader.detail', { ns: 'explore' }) }, + ].filter(item => item !== null) as { id: TypeEnum, name: string }[] + }, [t, disableTry]) return ( , schemaTypeDefinitions?: Sc const metaData = genNodeMetaData({ sort: 1, type: BlockEnum.TriggerPlugin, - helpLinkUri: 'plugin-trigger', + helpLinkUri: 'trigger/plugin-trigger', isStart: true, }) diff --git a/web/app/components/workflow/nodes/trigger-schedule/default.ts b/web/app/components/workflow/nodes/trigger-schedule/default.ts index 4f166675e7..587a125c2d 100644 --- a/web/app/components/workflow/nodes/trigger-schedule/default.ts +++ b/web/app/components/workflow/nodes/trigger-schedule/default.ts @@ -110,7 +110,7 @@ const validateVisualConfig = (payload: ScheduleTriggerNodeType, t: any): string const metaData = genNodeMetaData({ sort: 2, type: BlockEnum.TriggerSchedule, - helpLinkUri: 'schedule-trigger', + helpLinkUri: 'trigger/schedule-trigger', isStart: true, }) diff --git a/web/app/components/workflow/nodes/trigger-webhook/default.ts b/web/app/components/workflow/nodes/trigger-webhook/default.ts index ec0369d753..66fae30b0d 100644 --- a/web/app/components/workflow/nodes/trigger-webhook/default.ts +++ b/web/app/components/workflow/nodes/trigger-webhook/default.ts @@ -8,7 +8,7 @@ import { createWebhookRawVariable } from './utils/raw-variable' const metaData = genNodeMetaData({ sort: 3, type: BlockEnum.TriggerWebhook, - helpLinkUri: 'webhook-trigger', + helpLinkUri: 'trigger/webhook-trigger', isStart: true, }) diff --git a/web/app/components/workflow/utils/gen-node-meta-data.ts b/web/app/components/workflow/utils/gen-node-meta-data.ts index f45bfcb018..e625e3a8af 100644 --- a/web/app/components/workflow/utils/gen-node-meta-data.ts +++ b/web/app/components/workflow/utils/gen-node-meta-data.ts @@ -1,4 +1,5 @@ import type { BlockEnum } from '@/app/components/workflow/types' +import type { UseDifyNodesPath } from '@/types/doc-paths' import { BlockClassificationEnum } from '@/app/components/workflow/block-selector/types' export type GenNodeMetaDataParams = { @@ -7,7 +8,7 @@ export type GenNodeMetaDataParams = { type: BlockEnum title?: string author?: string - helpLinkUri?: string + helpLinkUri?: UseDifyNodesPath isRequired?: boolean isUndeletable?: boolean isStart?: boolean diff --git a/web/context/i18n.ts b/web/context/i18n.ts index 2766dfe5ea..5f39d1afb3 100644 --- a/web/context/i18n.ts +++ b/web/context/i18n.ts @@ -1,6 +1,7 @@ import type { Locale } from '@/i18n-config/language' import type { DocPathWithoutLang } from '@/types/doc-paths' import { useTranslation } from '#i18n' +import { useCallback } from 'react' import { getDocLanguage, getLanguage, getPricingPageLanguage } from '@/i18n-config/language' import { apiReferencePathTranslations } from '@/types/doc-paths' @@ -27,21 +28,24 @@ export const useDocLink = (baseUrl?: string): ((path?: DocPathWithoutLang, pathM let baseDocUrl = baseUrl || defaultDocBaseUrl baseDocUrl = (baseDocUrl.endsWith('/')) ? baseDocUrl.slice(0, -1) : baseDocUrl const locale = useLocale() - const docLanguage = getDocLanguage(locale) - return (path?: DocPathWithoutLang, pathMap?: DocPathMap): string => { - const pathUrl = path || '' - let targetPath = (pathMap) ? pathMap[locale] || pathUrl : pathUrl - let languagePrefix = `/${docLanguage}` + return useCallback( + (path?: DocPathWithoutLang, pathMap?: DocPathMap): string => { + const docLanguage = getDocLanguage(locale) + const pathUrl = path || '' + let targetPath = (pathMap) ? pathMap[locale] || pathUrl : pathUrl + let languagePrefix = `/${docLanguage}` - // Translate API reference paths for non-English locales - if (targetPath.startsWith('/api-reference/') && docLanguage !== 'en') { - const translatedPath = apiReferencePathTranslations[targetPath]?.[docLanguage as 'zh' | 'ja'] - if (translatedPath) { - targetPath = translatedPath - languagePrefix = '' + // Translate API reference paths for non-English locales + if (targetPath.startsWith('/api-reference/') && docLanguage !== 'en') { + const translatedPath = apiReferencePathTranslations[targetPath]?.[docLanguage as 'zh' | 'ja'] + if (translatedPath) { + targetPath = translatedPath + languagePrefix = '' + } } - } - return `${baseDocUrl}${languagePrefix}${targetPath}` - } + return `${baseDocUrl}${languagePrefix}${targetPath}` + }, + [baseDocUrl, locale], + ) } diff --git a/web/eslint-rules/index.js b/web/eslint-rules/index.js index 1559590328..8eda0caaa6 100644 --- a/web/eslint-rules/index.js +++ b/web/eslint-rules/index.js @@ -3,14 +3,13 @@ import noAsAnyInT from './rules/no-as-any-in-t.js' import noExtraKeys from './rules/no-extra-keys.js' import noLegacyNamespacePrefix from './rules/no-legacy-namespace-prefix.js' import noVersionPrefix from './rules/no-version-prefix.js' -import preferTailwindIcon from './rules/prefer-tailwind-icon.js' import requireNsOption from './rules/require-ns-option.js' import validI18nKeys from './rules/valid-i18n-keys.js' /** @type {import('eslint').ESLint.Plugin} */ const plugin = { meta: { - name: 'dify', + name: 'dify-i18n', version: '1.0.0', }, rules: { @@ -19,7 +18,6 @@ const plugin = { 'no-extra-keys': noExtraKeys, 'no-legacy-namespace-prefix': noLegacyNamespacePrefix, 'no-version-prefix': noVersionPrefix, - 'prefer-tailwind-icon': preferTailwindIcon, 'require-ns-option': requireNsOption, 'valid-i18n-keys': validI18nKeys, }, diff --git a/web/eslint-rules/rules/prefer-tailwind-icon.js b/web/eslint-rules/rules/prefer-tailwind-icon.js deleted file mode 100644 index ed5e111316..0000000000 --- a/web/eslint-rules/rules/prefer-tailwind-icon.js +++ /dev/null @@ -1,384 +0,0 @@ -/** - * Default prop-to-class mappings - * Maps component props to Tailwind class prefixes - */ -const DEFAULT_PROP_MAPPINGS = { - size: 'size', - width: 'w', - height: 'h', -} - -/** - * Convert PascalCase/camelCase to kebab-case - * @param {string} name - * @returns {string} The kebab-case string - */ -function camelToKebab(name) { - return name - .replace(/([a-z])(\d)/g, '$1-$2') - .replace(/(\d)([a-z])/gi, '$1-$2') - .replace(/([a-z])([A-Z])/g, '$1-$2') - .toLowerCase() -} - -/** - * Default icon library configurations - * - * Config options: - * - pattern: string | RegExp - Pattern to match import source - * - prefix: string | ((match: RegExpMatchArray) => string) - Icon class prefix - * - suffix: string | ((match: RegExpMatchArray) => string) - Icon class suffix - * - extractSubPath: boolean - Extract subdirectory path and add to prefix - * - iconFilter: (name: string) => boolean - Filter which imports to process - * - stripPrefix: string - Prefix to remove from icon name before transform - * - stripSuffix: string - Suffix to remove from icon name before transform - */ -const DEFAULT_ICON_CONFIGS = [ - { - // @/app/components/base/icons/src/public/* and vender/* - pattern: /^@\/app\/components\/base\/icons\/src\/(public|vender)/, - prefix: match => `i-custom-${match[1]}-`, - extractSubPath: true, - }, - { - // @remixicon/react - pattern: '@remixicon/react', - prefix: 'i-ri-', - iconFilter: name => name.startsWith('Ri'), - stripPrefix: 'Ri', - }, - { - // @heroicons/react/{size}/{variant} - pattern: /^@heroicons\/react\/(\d+)\/(solid|outline)$/, - prefix: 'i-heroicons-', - suffix: match => `-${match[1]}-${match[2]}`, - iconFilter: name => name.endsWith('Icon'), - stripSuffix: 'Icon', - }, -] - -/** - * Convert pixel value to Tailwind class - * @param {number} pixels - * @param {string} classPrefix - e.g., 'size', 'w', 'h' - * @returns {string} The Tailwind class string - */ -function pixelToClass(pixels, classPrefix) { - if (pixels % 4 === 0) { - const units = pixels / 4 - return `${classPrefix}-${units}` - } - // For non-standard sizes, use Tailwind arbitrary value syntax - return `${classPrefix}-[${pixels}px]` -} - -/** - * Match source against config pattern - * @param {string} source - The import source path - * @param {object} config - The icon config - * @returns {{ matched: boolean, match: RegExpMatchArray | null, basePath: string }} Match result - */ -function matchPattern(source, config) { - const { pattern } = config - if (pattern instanceof RegExp) { - const match = source.match(pattern) - if (match) { - return { matched: true, match, basePath: match[0] } - } - return { matched: false, match: null, basePath: '' } - } - // String pattern: exact match or prefix match - if (source === pattern || source.startsWith(`${pattern}/`)) { - return { matched: true, match: null, basePath: pattern } - } - return { matched: false, match: null, basePath: '' } -} - -/** - * Get icon class from config - * @param {string} iconName - * @param {object} config - * @param {string} source - The import source path - * @param {RegExpMatchArray | null} match - The regex match result - * @returns {string} The full Tailwind icon class string - */ -function getIconClass(iconName, config, source, match) { - // Strip prefix/suffix from icon name if configured - let name = iconName - if (config.stripPrefix && name.startsWith(config.stripPrefix)) { - name = name.slice(config.stripPrefix.length) - } - if (config.stripSuffix && name.endsWith(config.stripSuffix)) { - name = name.slice(0, -config.stripSuffix.length) - } - - // Transform name (use custom or default camelToKebab) - const transformed = config.transformName ? config.transformName(name, source) : camelToKebab(name) - - // Get prefix (can be string or function) - const prefix = typeof config.prefix === 'function' ? config.prefix(match) : config.prefix - - // Get suffix (can be string or function) - const suffix = typeof config.suffix === 'function' ? config.suffix(match) : (config.suffix || '') - - // Extract subdirectory path after the pattern to include in prefix (only if extractSubPath is enabled) - let subPrefix = '' - if (config.extractSubPath) { - const basePath = match ? match[0] : config.pattern - if (source.startsWith(`${basePath}/`)) { - const subPath = source.slice(basePath.length + 1) - if (subPath) { - subPrefix = `${subPath.replace(/\//g, '-')}-` - } - } - } - - return `${prefix}${subPrefix}${transformed}${suffix}` -} - -/** @type {import('eslint').Rule.RuleModule} */ -export default { - meta: { - type: 'suggestion', - docs: { - description: 'Prefer Tailwind CSS icon classes over icon library components', - }, - hasSuggestions: true, - schema: [ - { - type: 'object', - properties: { - libraries: { - type: 'array', - items: { - type: 'object', - properties: { - pattern: { type: 'string' }, - prefix: { type: 'string' }, - suffix: { type: 'string' }, - extractSubPath: { type: 'boolean' }, - }, - required: ['pattern', 'prefix'], - }, - }, - propMappings: { - type: 'object', - additionalProperties: { type: 'string' }, - description: 'Maps component props to Tailwind class prefixes, e.g., { size: "size", width: "w", height: "h" }', - }, - }, - additionalProperties: false, - }, - ], - messages: { - preferTailwindIcon: - 'Prefer using Tailwind CSS icon class "{{iconClass}}" over "{{componentName}}" from "{{source}}"', - preferTailwindIconImport: - 'Icon "{{importedName}}" from "{{source}}" can be replaced with Tailwind CSS class "{{iconClass}}"', - }, - }, - create(context) { - const options = context.options[0] || {} - const iconConfigs = options.libraries || DEFAULT_ICON_CONFIGS - const propMappings = options.propMappings || DEFAULT_PROP_MAPPINGS - - // Track imports: localName -> { node, importedName, config, source, match, used } - const iconImports = new Map() - - return { - ImportDeclaration(node) { - const source = node.source.value - - // Find matching config - let matchedConfig = null - let matchResult = null - for (const config of iconConfigs) { - const result = matchPattern(source, config) - if (result.matched) { - matchedConfig = config - matchResult = result.match - break - } - } - if (!matchedConfig) - return - - // Use default filter if not provided (for user-configured libraries) - const iconFilter = matchedConfig.iconFilter || (() => true) - - for (const specifier of node.specifiers) { - if (specifier.type === 'ImportSpecifier') { - const importedName = specifier.imported.name - const localName = specifier.local.name - - if (iconFilter(importedName)) { - iconImports.set(localName, { - node: specifier, - importedName, - localName, - config: matchedConfig, - source, - match: matchResult, - used: false, - }) - } - } - } - }, - - JSXOpeningElement(node) { - if (node.name.type !== 'JSXIdentifier') - return - - const componentName = node.name.name - const iconInfo = iconImports.get(componentName) - - if (!iconInfo) - return - - iconInfo.used = true - - const iconClass = getIconClass(iconInfo.importedName, iconInfo.config, iconInfo.source, iconInfo.match) - - // Find className attribute - const classNameAttr = node.attributes.find( - attr => attr.type === 'JSXAttribute' && attr.name.name === 'className', - ) - - // Process prop mappings (size, width, height, etc.) - const mappedClasses = [] - const mappedPropNames = Object.keys(propMappings) - - for (const propName of mappedPropNames) { - const attr = node.attributes.find( - a => a.type === 'JSXAttribute' && a.name.name === propName, - ) - - if (attr && attr.value) { - let pixelValue = null - - if (attr.value.type === 'JSXExpressionContainer' - && attr.value.expression.type === 'Literal' - && typeof attr.value.expression.value === 'number') { - pixelValue = attr.value.expression.value - } - else if (attr.value.type === 'Literal' - && typeof attr.value.value === 'number') { - pixelValue = attr.value.value - } - - if (pixelValue !== null) { - mappedClasses.push(pixelToClass(pixelValue, propMappings[propName])) - } - } - } - - // Build new className - const sourceCode = context.sourceCode - let newClassName - const classesToAdd = [iconClass, ...mappedClasses].filter(Boolean).join(' ') - - if (classNameAttr && classNameAttr.value) { - if (classNameAttr.value.type === 'Literal') { - newClassName = `${classesToAdd} ${classNameAttr.value.value}` - } - else if (classNameAttr.value.type === 'JSXExpressionContainer') { - const expression = sourceCode.getText(classNameAttr.value.expression) - newClassName = `\`${classesToAdd} \${${expression}}\`` - } - } - else { - newClassName = classesToAdd - } - - const parent = node.parent - const isSelfClosing = node.selfClosing - const excludedAttrs = ['className', ...mappedPropNames] - - context.report({ - node, - messageId: 'preferTailwindIcon', - data: { - iconClass, - componentName, - source: iconInfo.source, - }, - suggest: [ - { - messageId: 'preferTailwindIcon', - data: { - iconClass, - componentName, - source: iconInfo.source, - }, - fix(fixer) { - const fixes = [] - - const classValue = newClassName.startsWith('`') - ? `{${newClassName}}` - : `"${newClassName}"` - - const otherAttrs = node.attributes - .filter(attr => !(attr.type === 'JSXAttribute' && excludedAttrs.includes(attr.name.name))) - .map(attr => sourceCode.getText(attr)) - .join(' ') - - const attrsStr = otherAttrs - ? `className=${classValue} ${otherAttrs}` - : `className=${classValue}` - - if (isSelfClosing) { - fixes.push(fixer.replaceText(parent, ``)) - } - else { - const closingElement = parent.closingElement - fixes.push(fixer.replaceText(node, ``)) - if (closingElement) { - fixes.push(fixer.replaceText(closingElement, '')) - } - } - - return fixes - }, - }, - ], - }) - }, - - 'Program:exit': function () { - const sourceCode = context.sourceCode - - // Report icons that were imported but not found in JSX - for (const [, iconInfo] of iconImports) { - if (!iconInfo.used) { - // Verify the import is still referenced somewhere in the file (besides the import itself) - try { - const variables = sourceCode.getDeclaredVariables(iconInfo.node) - const variable = variables[0] - // Check if there are any references besides the import declaration - const hasReferences = variable && variable.references.some( - ref => ref.identifier !== iconInfo.node.local, - ) - if (!hasReferences) - continue - } - catch { - continue - } - - const iconClass = getIconClass(iconInfo.importedName, iconInfo.config, iconInfo.source, iconInfo.match) - context.report({ - node: iconInfo.node, - messageId: 'preferTailwindIconImport', - data: { - importedName: iconInfo.importedName, - source: iconInfo.source, - iconClass, - }, - }) - } - } - }, - } - }, -} diff --git a/web/eslint-suppressions.json b/web/eslint-suppressions.json index 0e4f2ca3d2..ea2f7c30d2 100644 --- a/web/eslint-suppressions.json +++ b/web/eslint-suppressions.json @@ -177,6 +177,11 @@ "count": 1 } }, + "app/components/app/annotation/add-annotation-modal/edit-item/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/app/annotation/batch-add-annotation-modal/csv-downloader.spec.tsx": { "ts/no-explicit-any": { "count": 2 @@ -186,6 +191,9 @@ "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 1 }, + "react-refresh/only-export-components": { + "count": 1 + }, "ts/no-explicit-any": { "count": 2 } @@ -193,6 +201,9 @@ "app/components/app/annotation/edit-annotation-modal/edit-item/index.tsx": { "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 1 + }, + "react-refresh/only-export-components": { + "count": 1 } }, "app/components/app/annotation/edit-annotation-modal/index.spec.tsx": { @@ -249,6 +260,11 @@ "count": 3 } }, + "app/components/app/configuration/base/var-highlight/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/app/configuration/config-prompt/advanced-prompt-input.tsx": { "ts/no-explicit-any": { "count": 2 @@ -419,6 +435,11 @@ "count": 6 } }, + "app/components/app/configuration/debug/debug-with-multiple-model/context.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/app/configuration/debug/debug-with-multiple-model/index.spec.tsx": { "ts/no-explicit-any": { "count": 5 @@ -501,6 +522,11 @@ "count": 1 } }, + "app/components/app/create-app-dialog/app-list/sidebar.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/app/create-app-modal/index.spec.tsx": { "ts/no-explicit-any": { "count": 7 @@ -517,6 +543,14 @@ "app/components/app/create-from-dsl-modal/index.tsx": { "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 2 + }, + "react-refresh/only-export-components": { + "count": 1 + } + }, + "app/components/app/log/filter.tsx": { + "react-refresh/only-export-components": { + "count": 1 } }, "app/components/app/log/index.tsx": { @@ -585,6 +619,9 @@ "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 3 }, + "react-refresh/only-export-components": { + "count": 1 + }, "ts/no-explicit-any": { "count": 3 } @@ -594,6 +631,11 @@ "count": 2 } }, + "app/components/app/workflow-log/filter.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/app/workflow-log/list.spec.tsx": { "ts/no-explicit-any": { "count": 1 @@ -645,6 +687,11 @@ "count": 1 } }, + "app/components/base/action-button/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/base/agent-log-modal/detail.tsx": { "ts/no-explicit-any": { "count": 1 @@ -673,6 +720,11 @@ "count": 2 } }, + "app/components/base/amplitude/AmplitudeProvider.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/base/amplitude/utils.ts": { "ts/no-explicit-any": { "count": 2 @@ -721,6 +773,9 @@ "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 1 }, + "react-refresh/only-export-components": { + "count": 1 + }, "react/no-nested-component-definitions": { "count": 1 } @@ -730,11 +785,21 @@ "count": 1 } }, + "app/components/base/button/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/base/button/sync-button.stories.tsx": { "no-console": { "count": 1 } }, + "app/components/base/carousel/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/base/chat/chat-with-history/chat-wrapper.tsx": { "ts/no-explicit-any": { "count": 6 @@ -814,6 +879,11 @@ "count": 1 } }, + "app/components/base/chat/chat/context.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/base/chat/chat/hooks.ts": { "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 2 @@ -917,10 +987,18 @@ } }, "app/components/base/error-boundary/index.tsx": { + "react-refresh/only-export-components": { + "count": 3 + }, "ts/no-explicit-any": { "count": 2 } }, + "app/components/base/features/context.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/base/features/new-feature-panel/annotation-reply/index.tsx": { "ts/no-explicit-any": { "count": 3 @@ -986,6 +1064,11 @@ "count": 3 } }, + "app/components/base/file-uploader/store.tsx": { + "react-refresh/only-export-components": { + "count": 4 + } + }, "app/components/base/file-uploader/utils.spec.ts": { "test/no-identical-title": { "count": 1 @@ -1082,6 +1165,11 @@ "count": 2 } }, + "app/components/base/ga/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/base/icons/utils.ts": { "ts/no-explicit-any": { "count": 3 @@ -1133,6 +1221,16 @@ "count": 1 } }, + "app/components/base/input/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, + "app/components/base/logo/dify-logo.tsx": { + "react-refresh/only-export-components": { + "count": 2 + } + }, "app/components/base/markdown-blocks/audio-block.tsx": { "ts/no-explicit-any": { "count": 5 @@ -1283,6 +1381,11 @@ "count": 1 } }, + "app/components/base/node-status/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/base/notion-connector/index.stories.tsx": { "no-console": { "count": 1 @@ -1314,6 +1417,9 @@ } }, "app/components/base/portal-to-follow-elem/index.tsx": { + "react-refresh/only-export-components": { + "count": 2 + }, "ts/no-explicit-any": { "count": 1 } @@ -1480,6 +1586,16 @@ "count": 1 } }, + "app/components/base/textarea/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, + "app/components/base/toast/index.tsx": { + "react-refresh/only-export-components": { + "count": 2 + } + }, "app/components/base/video-gallery/VideoPlayer.tsx": { "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 1 @@ -1523,6 +1639,16 @@ "count": 2 } }, + "app/components/billing/pricing/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, + "app/components/billing/pricing/plan-switcher/plan-range-switcher.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/billing/pricing/plans/cloud-plan-item/index.spec.tsx": { "test/prefer-hooks-in-order": { "count": 1 @@ -1573,6 +1699,11 @@ "count": 3 } }, + "app/components/datasets/common/image-uploader/store.tsx": { + "react-refresh/only-export-components": { + "count": 4 + } + }, "app/components/datasets/common/image-uploader/utils.ts": { "ts/no-explicit-any": { "count": 2 @@ -1583,6 +1714,16 @@ "count": 1 } }, + "app/components/datasets/common/retrieval-method-info/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, + "app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/datasets/create/file-preview/index.tsx": { "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 1 @@ -1613,6 +1754,11 @@ "count": 3 } }, + "app/components/datasets/create/step-two/preview-item/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/datasets/create/stop-embedding-modal/index.spec.tsx": { "test/prefer-hooks-in-order": { "count": 1 @@ -1670,6 +1816,9 @@ "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 2 }, + "react-refresh/only-export-components": { + "count": 1 + }, "ts/no-explicit-any": { "count": 2 } @@ -1734,6 +1883,11 @@ "count": 2 } }, + "app/components/datasets/documents/create-from-pipeline/data-source/store/provider.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/datasets/documents/create-from-pipeline/data-source/store/slices/online-drive.ts": { "ts/no-explicit-any": { "count": 4 @@ -1779,6 +1933,11 @@ "count": 1 } }, + "app/components/datasets/documents/detail/completed/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/datasets/documents/detail/completed/new-child-segment.tsx": { "ts/no-explicit-any": { "count": 1 @@ -1802,6 +1961,11 @@ "count": 1 } }, + "app/components/datasets/documents/detail/segment-add/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/datasets/documents/detail/settings/pipeline-settings/index.tsx": { "ts/no-explicit-any": { "count": 6 @@ -1942,6 +2106,11 @@ "count": 1 } }, + "app/components/explore/try-app/tab.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/goto-anything/actions/commands/command-bus.ts": { "ts/no-explicit-any": { "count": 2 @@ -1953,6 +2122,9 @@ } }, "app/components/goto-anything/actions/commands/slash.tsx": { + "react-refresh/only-export-components": { + "count": 3 + }, "ts/no-explicit-any": { "count": 1 } @@ -1970,6 +2142,9 @@ "app/components/goto-anything/context.tsx": { "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 4 + }, + "react-refresh/only-export-components": { + "count": 1 } }, "app/components/goto-anything/index.spec.tsx": { @@ -2166,6 +2341,11 @@ "count": 4 } }, + "app/components/plugins/install-plugin/install-bundle/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/plugins/install-plugin/install-bundle/item/github-item.tsx": { "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 1 @@ -2242,6 +2422,11 @@ "count": 2 } }, + "app/components/plugins/plugin-auth/index.tsx": { + "react-refresh/only-export-components": { + "count": 3 + } + }, "app/components/plugins/plugin-auth/plugin-auth-in-agent.tsx": { "ts/no-explicit-any": { "count": 1 @@ -2326,6 +2511,9 @@ } }, "app/components/plugins/plugin-detail-panel/subscription-list/create/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + }, "ts/no-explicit-any": { "count": 1 } @@ -2371,6 +2559,9 @@ } }, "app/components/plugins/plugin-page/context.tsx": { + "react-refresh/only-export-components": { + "count": 2 + }, "ts/no-explicit-any": { "count": 1 } @@ -2725,6 +2916,11 @@ "count": 1 } }, + "app/components/workflow/block-selector/constants.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/workflow/block-selector/featured-tools.tsx": { "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 2 @@ -2746,6 +2942,11 @@ "count": 1 } }, + "app/components/workflow/block-selector/index-bar.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/workflow/block-selector/market-place-plugin/action.tsx": { "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 1 @@ -2784,16 +2985,31 @@ "count": 1 } }, + "app/components/workflow/block-selector/view-type-select.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/workflow/candidate-node-main.tsx": { "ts/no-explicit-any": { "count": 2 } }, + "app/components/workflow/context.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/workflow/custom-group-node/custom-group-node.tsx": { "unused-imports/no-unused-vars": { "count": 1 } }, + "app/components/workflow/datasets-detail-store/provider.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/workflow/header/run-mode.tsx": { "no-console": { "count": 1 @@ -2802,11 +3018,21 @@ "count": 1 } }, + "app/components/workflow/header/test-run-menu.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/workflow/header/view-workflow-history.tsx": { "ts/no-explicit-any": { "count": 1 } }, + "app/components/workflow/hooks-store/provider.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/workflow/hooks/use-checklist.ts": { "ts/no-empty-object-type": { "count": 2 @@ -2871,6 +3097,9 @@ } }, "app/components/workflow/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + }, "ts/no-explicit-any": { "count": 1 } @@ -2917,10 +3146,18 @@ } }, "app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx": { + "react-refresh/only-export-components": { + "count": 1 + }, "ts/no-explicit-any": { "count": 6 } }, + "app/components/workflow/nodes/_base/components/entry-node-container.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/workflow/nodes/_base/components/error-handle/default-value.tsx": { "ts/no-explicit-any": { "count": 1 @@ -2946,6 +3183,16 @@ "count": 1 } }, + "app/components/workflow/nodes/_base/components/layout/index.tsx": { + "react-refresh/only-export-components": { + "count": 7 + } + }, + "app/components/workflow/nodes/_base/components/mcp-tool-availability.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/workflow/nodes/_base/components/memory-config.tsx": { "unicorn/prefer-number-properties": { "count": 1 @@ -3029,6 +3276,9 @@ } }, "app/components/workflow/nodes/_base/components/workflow-panel/tab.tsx": { + "react-refresh/only-export-components": { + "count": 1 + }, "ts/no-explicit-any": { "count": 1 } @@ -3082,6 +3332,9 @@ } }, "app/components/workflow/nodes/agent/panel.tsx": { + "react-refresh/only-export-components": { + "count": 1 + }, "ts/no-explicit-any": { "count": 1 } @@ -3370,6 +3623,11 @@ "count": 2 } }, + "app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/context.tsx": { + "react-refresh/only-export-components": { + "count": 3 + } + }, "app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/auto-width-input.tsx": { "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 1 @@ -3662,6 +3920,11 @@ "count": 1 } }, + "app/components/workflow/note-node/note-editor/toolbar/color-picker.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/workflow/note-node/note-editor/utils.ts": { "regexp/no-useless-quantifier": { "count": 1 @@ -3698,6 +3961,9 @@ } }, "app/components/workflow/panel/chat-variable-panel/components/object-value-item.tsx": { + "react-refresh/only-export-components": { + "count": 1 + }, "ts/no-explicit-any": { "count": 5 }, @@ -3852,6 +4118,16 @@ "count": 4 } }, + "app/components/workflow/skill/editor/skill-editor/plugins/tool-block/tool-block-context.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, + "app/components/workflow/skill/hooks/use-skill-save-manager.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "app/components/workflow/store/workflow/debug/inspect-vars-slice.ts": { "ts/no-explicit-any": { "count": 2 @@ -3959,6 +4235,11 @@ "count": 8 } }, + "app/components/workflow/workflow-history-store.tsx": { + "react-refresh/only-export-components": { + "count": 2 + } + }, "app/components/workflow/workflow-preview/components/nodes/constants.ts": { "ts/no-explicit-any": { "count": 1 @@ -4020,30 +4301,79 @@ } }, "context/app-context.tsx": { + "react-refresh/only-export-components": { + "count": 2 + }, "ts/no-explicit-any": { "count": 1 } }, + "context/datasets-context.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, + "context/event-emitter.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, + "context/external-api-panel-context.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, + "context/external-knowledge-api-context.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, + "context/global-public-context.tsx": { + "react-refresh/only-export-components": { + "count": 4 + } + }, "context/hooks/use-trigger-events-limit-modal.ts": { "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 3 } }, + "context/mitt-context.tsx": { + "react-refresh/only-export-components": { + "count": 3 + } + }, "context/modal-context.test.tsx": { "ts/no-explicit-any": { "count": 3 } }, "context/modal-context.tsx": { + "react-refresh/only-export-components": { + "count": 2 + }, "ts/no-explicit-any": { "count": 5 } }, "context/provider-context.tsx": { + "react-refresh/only-export-components": { + "count": 3 + }, "ts/no-explicit-any": { "count": 1 } }, + "context/web-app-context.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, + "context/workspace-context.tsx": { + "react-refresh/only-export-components": { + "count": 1 + } + }, "hooks/use-async-window-open.spec.ts": { "ts/no-explicit-any": { "count": 6 @@ -4080,6 +4410,9 @@ "hooks/use-pay.tsx": { "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 4 + }, + "react-refresh/only-export-components": { + "count": 3 } }, "i18n-config/README.md": { diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs index 98d1810376..305441c250 100644 --- a/web/eslint.config.mjs +++ b/web/eslint.config.mjs @@ -104,17 +104,8 @@ export default antfu( 'tailwindcss/migration-from-tailwind-2': 'warn', }, }, - // Dify custom rules { - plugins: { - dify, - }, - }, - { - files: ['**/*.tsx'], - rules: { - 'dify/prefer-tailwind-icon': 'warn', - }, + plugins: { dify }, }, { files: ['i18n/**/*.json'], diff --git a/web/package.json b/web/package.json index a545c19a24..c16b40283e 100644 --- a/web/package.json +++ b/web/package.json @@ -1,7 +1,7 @@ { "name": "dify-web", "type": "module", - "version": "1.11.4", + "version": "1.12.0", "private": true, "packageManager": "pnpm@10.28.1+sha512.7d7dbbca9e99447b7c3bf7a73286afaaf6be99251eb9498baefa7d406892f67b879adb3a1d7e687fc4ccc1a388c7175fbaae567a26ab44d1067b54fcb0d6a316", "imports": { @@ -22,6 +22,9 @@ "and_uc >= 15.5", "and_qq >= 14.9" ], + "engines": { + "node": ">=24" + }, "scripts": { "dev": "next dev", "dev:inspect": "next dev --inspect", @@ -166,19 +169,13 @@ "zustand": "5.0.9" }, "devDependencies": { - "@antfu/eslint-config": "7.0.1", + "@antfu/eslint-config": "7.2.0", "@chromatic-com/storybook": "5.0.0", - "@egoist/tailwindcss-icons": "1.9.0", - "@eslint-react/eslint-plugin": "2.7.0", - "@iconify-json/heroicons": "1.2.3", - "@iconify-json/ri": "1.2.7", - "@iconify/tools": "5.0.2", - "@iconify/types": "2.0.0", - "@iconify/utils": "3.1.0", + "@eslint-react/eslint-plugin": "2.8.1", "@mdx-js/loader": "3.1.1", "@mdx-js/react": "3.1.1", "@next/bundle-analyzer": "16.1.5", - "@next/eslint-plugin-next": "16.1.5", + "@next/eslint-plugin-next": "16.1.6", "@next/mdx": "16.1.5", "@rgrove/parse-xml": "4.2.0", "@serwist/turbopack": "9.5.0", @@ -188,7 +185,7 @@ "@storybook/addon-themes": "10.2.0", "@storybook/nextjs-vite": "10.2.0", "@storybook/react": "10.2.0", - "@tanstack/eslint-plugin-query": "5.91.2", + "@tanstack/eslint-plugin-query": "5.91.3", "@tanstack/react-devtools": "0.9.2", "@tanstack/react-form-devtools": "0.2.12", "@tanstack/react-query-devtools": "5.90.2", @@ -196,9 +193,9 @@ "@testing-library/jest-dom": "6.9.1", "@testing-library/react": "16.3.0", "@testing-library/user-event": "14.6.1", - "@tsslint/cli": "3.0.1", - "@tsslint/compat-eslint": "3.0.1", - "@tsslint/config": "3.0.1", + "@tsslint/cli": "3.0.2", + "@tsslint/compat-eslint": "3.0.2", + "@tsslint/config": "3.0.2", "@types/js-cookie": "3.0.6", "@types/js-yaml": "4.0.9", "@types/negotiator": "0.6.4", @@ -212,19 +209,19 @@ "@types/semver": "7.7.1", "@types/sortablejs": "1.15.8", "@types/uuid": "10.0.0", - "@typescript-eslint/parser": "8.53.0", + "@typescript-eslint/parser": "8.54.0", "@typescript/native-preview": "7.0.0-dev.20251209.1", "@vitejs/plugin-react": "5.1.2", "@vitest/coverage-v8": "4.0.17", "autoprefixer": "10.4.21", - "code-inspector-plugin": "1.4.1", + "code-inspector-plugin": "1.3.6", "cross-env": "10.1.0", "esbuild-wasm": "0.27.2", "eslint": "9.39.2", "eslint-plugin-react-hooks": "7.0.1", "eslint-plugin-react-refresh": "0.4.26", - "eslint-plugin-sonarjs": "3.0.5", - "eslint-plugin-storybook": "10.2.0", + "eslint-plugin-sonarjs": "3.0.6", + "eslint-plugin-storybook": "10.2.1", "eslint-plugin-tailwindcss": "3.18.2", "husky": "9.1.7", "jsdom": "27.3.0", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index a40e18f3cf..8dff77ca7b 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -382,32 +382,14 @@ importers: version: 5.0.9(@types/react@19.2.9)(immer@11.1.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)) devDependencies: '@antfu/eslint-config': - specifier: 7.0.1 - version: 7.0.1(@eslint-react/eslint-plugin@2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(@next/eslint-plugin-next@16.1.5)(@vue/compiler-sfc@3.5.25)(eslint-plugin-react-hooks@7.0.1(eslint@9.39.2(jiti@1.21.7)))(eslint-plugin-react-refresh@0.4.26(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)(vitest@4.0.17(@types/node@18.15.0)(happy-dom@20.0.11)(jiti@1.21.7)(jsdom@27.3.0(canvas@3.2.0))(sass@1.93.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + specifier: 7.2.0 + version: 7.2.0(@eslint-react/eslint-plugin@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(@next/eslint-plugin-next@16.1.6)(@vue/compiler-sfc@3.5.25)(eslint-plugin-react-hooks@7.0.1(eslint@9.39.2(jiti@1.21.7)))(eslint-plugin-react-refresh@0.4.26(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)(vitest@4.0.17(@types/node@18.15.0)(happy-dom@20.0.11)(jiti@1.21.7)(jsdom@27.3.0(canvas@3.2.0))(sass@1.93.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) '@chromatic-com/storybook': specifier: 5.0.0 version: 5.0.0(storybook@10.2.0(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) - '@egoist/tailwindcss-icons': - specifier: 1.9.0 - version: 1.9.0(tailwindcss@3.4.18(tsx@4.21.0)(yaml@2.8.2)) '@eslint-react/eslint-plugin': - specifier: 2.7.0 - version: 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@iconify-json/heroicons': - specifier: 1.2.3 - version: 1.2.3 - '@iconify-json/ri': - specifier: 1.2.7 - version: 1.2.7 - '@iconify/tools': - specifier: 5.0.2 - version: 5.0.2 - '@iconify/types': - specifier: 2.0.0 - version: 2.0.0 - '@iconify/utils': - specifier: 3.1.0 - version: 3.1.0 + specifier: 2.8.1 + version: 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) '@mdx-js/loader': specifier: 3.1.1 version: 3.1.1(webpack@5.103.0(esbuild@0.27.2)(uglify-js@3.19.3)) @@ -418,8 +400,8 @@ importers: specifier: 16.1.5 version: 16.1.5 '@next/eslint-plugin-next': - specifier: 16.1.5 - version: 16.1.5 + specifier: 16.1.6 + version: 16.1.6 '@next/mdx': specifier: 16.1.5 version: 16.1.5(@mdx-js/loader@3.1.1(webpack@5.103.0(esbuild@0.27.2)(uglify-js@3.19.3)))(@mdx-js/react@3.1.1(@types/react@19.2.9)(react@19.2.4)) @@ -448,8 +430,8 @@ importers: specifier: 10.2.0 version: 10.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.0(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) '@tanstack/eslint-plugin-query': - specifier: 5.91.2 - version: 5.91.2(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + specifier: 5.91.3 + version: 5.91.3(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) '@tanstack/react-devtools': specifier: 0.9.2 version: 0.9.2(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.10) @@ -472,14 +454,14 @@ importers: specifier: 14.6.1 version: 14.6.1(@testing-library/dom@10.4.1) '@tsslint/cli': - specifier: 3.0.1 - version: 3.0.1(@tsslint/compat-eslint@3.0.1(jiti@1.21.7)(typescript@5.9.3))(typescript@5.9.3) + specifier: 3.0.2 + version: 3.0.2(@tsslint/compat-eslint@3.0.2(jiti@1.21.7)(typescript@5.9.3))(typescript@5.9.3) '@tsslint/compat-eslint': - specifier: 3.0.1 - version: 3.0.1(jiti@1.21.7)(typescript@5.9.3) + specifier: 3.0.2 + version: 3.0.2(jiti@1.21.7)(typescript@5.9.3) '@tsslint/config': - specifier: 3.0.1 - version: 3.0.1(@tsslint/compat-eslint@3.0.1(jiti@1.21.7)(typescript@5.9.3))(typescript@5.9.3) + specifier: 3.0.2 + version: 3.0.2(@tsslint/compat-eslint@3.0.2(jiti@1.21.7)(typescript@5.9.3))(typescript@5.9.3) '@types/js-cookie': specifier: 3.0.6 version: 3.0.6 @@ -520,8 +502,8 @@ importers: specifier: 10.0.0 version: 10.0.0 '@typescript-eslint/parser': - specifier: 8.53.0 - version: 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + specifier: 8.54.0 + version: 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) '@typescript/native-preview': specifier: 7.0.0-dev.20251209.1 version: 7.0.0-dev.20251209.1 @@ -535,8 +517,8 @@ importers: specifier: 10.4.21 version: 10.4.21(postcss@8.5.6) code-inspector-plugin: - specifier: 1.4.1 - version: 1.4.1 + specifier: 1.3.6 + version: 1.3.6 cross-env: specifier: 10.1.0 version: 10.1.0 @@ -553,11 +535,11 @@ importers: specifier: 0.4.26 version: 0.4.26(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-sonarjs: - specifier: 3.0.5 - version: 3.0.5(eslint@9.39.2(jiti@1.21.7)) + specifier: 3.0.6 + version: 3.0.6(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-storybook: - specifier: 10.2.0 - version: 10.2.0(eslint@9.39.2(jiti@1.21.7))(storybook@10.2.0(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + specifier: 10.2.1 + version: 10.2.1(eslint@9.39.2(jiti@1.21.7))(storybook@10.2.0(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) eslint-plugin-tailwindcss: specifier: 3.18.2 version: 3.18.2(tailwindcss@3.4.18(tsx@4.21.0)(yaml@2.8.2)) @@ -705,8 +687,8 @@ packages: '@amplitude/targeting@0.2.0': resolution: {integrity: sha512-/50ywTrC4hfcfJVBbh5DFbqMPPfaIOivZeb5Gb+OGM03QrA+lsUqdvtnKLNuWtceD4H6QQ2KFzPJ5aAJLyzVDA==} - '@antfu/eslint-config@7.0.1': - resolution: {integrity: sha512-QbCDrLPo2Bpn9/W5PnpGvUuD/EIKhiCmLBuIj9ylxeMvl47XSkXy3MZyinqUVsBJzk196B7BcJQByDZRr5TbZQ==} + '@antfu/eslint-config@7.2.0': + resolution: {integrity: sha512-I/GWDvkvUfp45VolhrMpOdkfBC69f6lstJi0BCSooylQZwH4OTJPkbXCkp4lKh9V4BeMrcO3G5iC+YIfY28/aA==} hasBin: true peerDependencies: '@eslint-react/eslint-plugin': ^2.0.1 @@ -763,9 +745,6 @@ packages: '@antfu/install-pkg@1.1.0': resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} - '@antfu/utils@8.1.1': - resolution: {integrity: sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==} - '@asamuzakjp/css-color@4.1.1': resolution: {integrity: sha512-B0Hv6G3gWGMn0xKJ0txEi/jM5iFpT3MfDxmhZFb4W047GvytCf1DHQ1D69W3zHI4yWe2aTZAA0JnbMZ7Xc8DuQ==} @@ -902,23 +881,23 @@ packages: '@clack/prompts@0.8.2': resolution: {integrity: sha512-6b9Ab2UiZwJYA9iMyboYyW9yJvAO9V753ZhS+DHKEjZRKAxPPOb7MXXu84lsPFG+vZt6FRFniZ8rXi+zCIw4yQ==} - '@code-inspector/core@1.4.1': - resolution: {integrity: sha512-k5iLYvrBBPBPODcwuzgEcAZnXU4XTnEO1jOmNQBHCehN6nrMO1m5Efjz35KPkSX+8T4IWvXvLoXR5XPfhDlxug==} + '@code-inspector/core@1.3.6': + resolution: {integrity: sha512-bSxf/PWDPY6rv9EFf0mJvTnLnz3927PPrpX6BmQcRKQab+Ez95yRqrVZY8IcBUpaqA/k3etA5rZ1qkN0V4ERtw==} - '@code-inspector/esbuild@1.4.1': - resolution: {integrity: sha512-0tf73j0wgsu1Rl5CNe5o5L/GB/lGvQQVjuLTbAB/but+Bw//nHRnlrA29lBzNM6cyBDZzwofa71Q+TH8Fu4aZQ==} + '@code-inspector/esbuild@1.3.6': + resolution: {integrity: sha512-s35dseBXI2yqfX6ZK29Ix941jaE/4KPlZZeMk6B5vDahj75FDUfVxQ7ORy4cX2hyz8CmlOycsY/au5mIvFpAFg==} - '@code-inspector/mako@1.4.1': - resolution: {integrity: sha512-inpiJbc8J+qaEYcMgzyAFusuyryZ9i0wUQhLJRbWl1WrUdWTE8xNHDjhPeTVaMav42NTGDnVKJhhKD6tNaxyFA==} + '@code-inspector/mako@1.3.6': + resolution: {integrity: sha512-FJvuTElOi3TUCWTIaYTFYk2iTUD6MlO51SC8SYfwmelhuvnOvTMa2TkylInX16OGb4f7sGNLRj2r+7NNx/gqpw==} - '@code-inspector/turbopack@1.4.1': - resolution: {integrity: sha512-xVefk907E39U/oywR9YiEqJn1VlNBHIcIsYkjNnFp0U3qBb3A40VqivlCqkWaP9xHAwEH8/UT3Sfh3aoUPC9/Q==} + '@code-inspector/turbopack@1.3.6': + resolution: {integrity: sha512-pfXgvZCn4/brpTvqy8E0HTe6V/ksVKEPQo697Nt5k22kBnlEM61UT3rI2Art+fDDEMPQTxVOFpdbwCKSLwMnmQ==} - '@code-inspector/vite@1.4.1': - resolution: {integrity: sha512-ptbGkmtw5mvuFse6Kjmd6bCgm+isHrBq+HumWlAMBH//Qb2frHkEV7kWjO6/AkBXfm/ccNJy+jNwWq0632ChDg==} + '@code-inspector/vite@1.3.6': + resolution: {integrity: sha512-vXYvzGc0S1NR4p3BeD1Xx2170OnyecZD0GtebLlTiHw/cetzlrBHVpbkIwIEzzzpTYYshwwDt8ZbuvdjmqhHgw==} - '@code-inspector/webpack@1.4.1': - resolution: {integrity: sha512-UkqC5MsWRVJT2y10GM7tIZdQmFuGAlArJSfq2hq727eXMDV3otY5d1UCQopYvUIEC90QQNHJDeK4e+UQipF6AQ==} + '@code-inspector/webpack@1.3.6': + resolution: {integrity: sha512-bi/+vsym9d6NXQQ++Phk74VLMiVoGKjgPHr445j/D43URG8AN8yYa+gRDBEDcZx4B128dihrVMxEO8+OgWGjTw==} '@csstools/color-helpers@5.1.0': resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} @@ -952,18 +931,10 @@ packages: resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} engines: {node: '>=18'} - '@cyberalien/svg-utils@1.0.11': - resolution: {integrity: sha512-qEE9mnyI+avfGT3emKuRs3ucYkITeaV0Xi7VlYN41f+uGnZBecQP3jwz/AF437H9J4Q7qPClHKm4NiTYpNE6hA==} - '@discoveryjs/json-ext@0.5.7': resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} engines: {node: '>=10.0.0'} - '@egoist/tailwindcss-icons@1.9.0': - resolution: {integrity: sha512-xWA9cUy6hzlK7Y6TaoRIcwmilSXiTJ8rbXcEdf9uht7yzDgw/yIgF4rThIQMrpD2Y2v4od51+r2y6Z7GStanDQ==} - peerDependencies: - tailwindcss: '*' - '@emnapi/core@1.7.1': resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==} @@ -983,8 +954,8 @@ packages: resolution: {integrity: sha512-rQkU5u8hNAq2NVRzHnIUUvR6arbO0b6AOlvpTNS48CkiKSn/xtNfOzBK23JE4SiW89DgvU7GtxLVgV4Vn2HBAw==} engines: {node: '>=20.11.0'} - '@es-joy/jsdoccomment@0.79.0': - resolution: {integrity: sha512-q/Nc241VsVRC5b1dgbsOI0fnWfrb1S9sdceFewpDHto4+4r2o6SSCpcY+Z+EdLdMPN6Nsj/PjlPcKag6WbU6XQ==} + '@es-joy/jsdoccomment@0.83.0': + resolution: {integrity: sha512-e1MHSEPJ4m35zkBvNT6kcdeH1SvMaJDsPC3Xhfseg3hvF50FUE3f46Yn36jgbrPYYXezlWUQnevv23c+lx2MCA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@es-joy/resolve.exports@1.2.0': @@ -1159,48 +1130,44 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint-community/regexpp@4.12.2': resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint-react/ast@2.7.0': - resolution: {integrity: sha512-GGrvel9+kR++wK7orcS2kS1xtHpY0o0rh6hbHbiGVWsSiZmg0X8jZfK1nSf8a3FLJR2WLtQlUsrrtJ4hObaqeQ==} + '@eslint-react/ast@2.8.1': + resolution: {integrity: sha512-4D442lxeFvvd9PMvBbA621rfz/Ne8Kod8RW0/FLKO0vx+IOxm74pP6be1uU56rqL9TvoIHxjclBjfgXplEF+Yw==} engines: {node: '>=20.19.0'} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@eslint-react/core@2.7.0': - resolution: {integrity: sha512-xeRSnzLI35Msr2lnGjH4vxgOwohODy2FaXRmXUS1IpmMRDp1Ct+7I3SDknfeW/YExjGZXvpxR0uD2P9dSjU6NA==} + '@eslint-react/core@2.8.1': + resolution: {integrity: sha512-zF73p8blyuX+zrfgyTtpKesichYzK+G54TEjFWtzagWIbnqQjtVscebL/eGep72oWzAOd5B04ACBvJ2hW4fp5g==} engines: {node: '>=20.19.0'} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@eslint-react/eff@2.7.0': - resolution: {integrity: sha512-+uUI53LkS6EDU0ysVUeM2SdyZQwt/xEfh4OSJ0JMLT8fJbseZY8c0hyev7X5arifcLs0PVPHwUP1IPcNhSLOFw==} + '@eslint-react/eff@2.8.1': + resolution: {integrity: sha512-ZASOs8oTZJSiu1giue7V87GEKQvlKLfGfLppal6Rl+aKnfIEz+vartmjpH12pkFQZ9ESRyHzYbU533S6pEDoNg==} engines: {node: '>=20.19.0'} - '@eslint-react/eslint-plugin@2.7.0': - resolution: {integrity: sha512-Bog14dOrsG/jBA9B8URZPJMI6dZuEwqHdkPcTuIkJe92EjFj8NwyziNGFXKY3j7o9AU9ILCBbjfC4JFq56lwjQ==} + '@eslint-react/eslint-plugin@2.8.1': + resolution: {integrity: sha512-ob+SSDnTPnA5dhiWWJLfyHRLEzWnjilCsohgo5s9PPKF5b5bjxG+c/rwqhQwT3M9Ey83mGNdkrLzt00SOfr4pw==} engines: {node: '>=20.19.0'} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@eslint-react/shared@2.7.0': - resolution: {integrity: sha512-/lF5uiGYd+XIfO5t2YMC5RdbQ9lxLkxfL4icZgrbiJIPndirAKjFNl1cdXd+C/qqRCYDACrTPqI8HEL1T4N1Iw==} + '@eslint-react/shared@2.8.1': + resolution: {integrity: sha512-NDmJBiMiPDXR6qeZzYOtiILHxWjYwBHxquQ/bMQkWcWK+1qF5LeD8UTRcWtBpZoMPi3sNBWwR3k2Sc5HWZpJ7g==} engines: {node: '>=20.19.0'} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@eslint-react/var@2.7.0': - resolution: {integrity: sha512-EFztHstOAYYCrFFNUOPZ7+J3o/X/zawqPKgLL7b5/271rhL6/DMxUmTcKtJIHO7hCdFPMcGT+vPxe+omq62Ukg==} + '@eslint-react/var@2.8.1': + resolution: {integrity: sha512-iHIdEBz6kgW4dEFdhEjpy9SEQ6+d4RYg+WBzHg5J5ktT2xSQFi77Dq6Wtemik6QvvAPnYLRseQxgW+m+1rQlfA==} engines: {node: '>=20.19.0'} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -1231,6 +1198,10 @@ packages: resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/config-helpers@0.5.1': + resolution: {integrity: sha512-QN8067dXsXAl9HIvqws7STEviheRFojX3zek5OpC84oBxDGqizW9731ByF/ASxqQihbWrVDdZXS+Ihnsckm9dg==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + '@eslint/core@0.14.0': resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1337,21 +1308,9 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@iconify-json/heroicons@1.2.3': - resolution: {integrity: sha512-n+vmCEgTesRsOpp5AB5ILB6srsgsYK+bieoQBNlafvoEhjVXLq8nIGN4B0v/s4DUfa0dOrjwE/cKJgIKdJXOEg==} - - '@iconify-json/ri@1.2.7': - resolution: {integrity: sha512-j/Fkb8GlWY5y/zLj1BGxWRtDzuJFrI7562zLw+iQVEykieBgew43+r8qAvtSajvb75MfUIHjsNOYQPRD8FfLfw==} - - '@iconify/tools@5.0.2': - resolution: {integrity: sha512-esoFiH0LYpiqqVAO+RTenh6qqGKf0V8T0T6IG7dFLCw26cjcYGG34UMHjkbuq+MMl23U39FtkzhWZsCDDtOhew==} - '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} - '@iconify/utils@2.3.0': - resolution: {integrity: sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==} - '@iconify/utils@3.1.0': resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==} @@ -1781,8 +1740,8 @@ packages: '@next/env@16.1.5': resolution: {integrity: sha512-CRSCPJiSZoi4Pn69RYBDI9R7YK2g59vLexPQFXY0eyw+ILevIenCywzg+DqmlBik9zszEnw2HLFOUlLAcJbL7g==} - '@next/eslint-plugin-next@16.1.5': - resolution: {integrity: sha512-gUWcEsOl+1W7XakmouClcJ0TNFCkblvDUho31wulbDY9na0C6mGtBTSXGRU5GXJY65GjGj0zNaCD/GaBp888Mg==} + '@next/eslint-plugin-next@16.1.6': + resolution: {integrity: sha512-/Qq3PTagA6+nYVfryAtQ7/9FEr/6YVyvOtl6rZnGsbReGLf0jZU6gkpr1FuChAQpvV46a78p4cmHOVP8mbfSMQ==} '@next/mdx@16.1.5': resolution: {integrity: sha512-TYzfGfZiXtf6HXZpqJoKq+2DRB1FjY9BR1HWhfl7WoSW/BAEr6X+WmdrdrCtqNpkY8VSoWHVWP0KNbyTqY7ZTA==} @@ -2913,8 +2872,8 @@ packages: peerDependencies: solid-js: 1.9.11 - '@tanstack/eslint-plugin-query@5.91.2': - resolution: {integrity: sha512-UPeWKl/Acu1IuuHJlsN+eITUHqAaa9/04geHHPedY8siVarSaWprY0SVMKrkpKfk5ehRT7+/MZ5QwWuEtkWrFw==} + '@tanstack/eslint-plugin-query@5.91.3': + resolution: {integrity: sha512-5GMGZMYFK9dOvjpdedjJs4hU40EdPuO2AjzObQzP7eOSsikunCfrXaU3oNGXSsvoU9ve1Z1xQZZuDyPi0C1M7Q==} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -3023,18 +2982,18 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' - '@tsslint/cli@3.0.1': - resolution: {integrity: sha512-y5yzMFl6sKQNsomuGInmFzMiKW37xxDcJauHnPqYoCWL8LldNLnaUOBqx0illfNZ0FDAiSuV/oshC/NG8/F2Tw==} + '@tsslint/cli@3.0.2': + resolution: {integrity: sha512-8lyZcDEs86zitz0wZ5QRdswY6xGz8j+WL11baN4rlpwahtPgYatujpYV5gpoKeyMAyerlNTdQh6u2LUJLoLNyQ==} engines: {node: '>=22.6.0'} hasBin: true peerDependencies: typescript: '*' - '@tsslint/compat-eslint@3.0.1': - resolution: {integrity: sha512-cojBaB1C9RxWjDfCvLBhbffshyizb+Cf1Os9NXHuzyQOPvU1IwYPW5Sxo1RU19pCOE9/TvQcuxgnGfwbkk/Dig==} + '@tsslint/compat-eslint@3.0.2': + resolution: {integrity: sha512-2TzSJPybCEfU/kHNi9UybwI//A7Fe14CwqmNuJ4fR4WYGpfIclXqfDJwsn5U1NzrWbHjWzRSntJITQPNw1SCNA==} - '@tsslint/config@3.0.1': - resolution: {integrity: sha512-1S8YYLrZE22xfH3GtDXRO7YzkeQj9+FjoxaWhYQsjWDU82HHeSRWq5d2UzPSN/ac6WFmFq8yApXIGylfvrG6MA==} + '@tsslint/config@3.0.2': + resolution: {integrity: sha512-oHzteAwL6NHVrLzJnrpqMwewEFOydhDH228weO4wkHW8SwvE4oVV5qrKmjwL69ClYt5Le3y2aGDzGou+GuTbKg==} engines: {node: '>=22.6.0'} hasBin: true peerDependencies: @@ -3046,12 +3005,12 @@ packages: tsl: optional: true - '@tsslint/core@3.0.1': - resolution: {integrity: sha512-8FEczJ20hdpmEH5vm272hS3QAycsk5574yZT6VMS8TUK8kNY4qoRKY/gdOY0nYNYWZrRPs+6dr1TmEVPBZjlvw==} + '@tsslint/core@3.0.2': + resolution: {integrity: sha512-Cu50e9vBojEMQjbqMoshkgLSoBj1BKbbmhSvzgbo07TiQ1wrOblZjvhU8ygB1fAIIHgU4laExX3pLU5OOeeR9g==} engines: {node: '>=22.6.0'} - '@tsslint/types@3.0.1': - resolution: {integrity: sha512-JPK/+tSJ2hPTwgN173fkenPEnAI2CD0r0FDJ23PfftTc0NM449ZiAFHvs1KuPUOjAvBFIo5BsLr7Kxc1Ekdgtw==} + '@tsslint/types@3.0.2': + resolution: {integrity: sha512-RbF3TIxu/YQwRpYrH5j2EL3ff4+Lr2SSmwCJmPJfi832F0hpgJj6xB9xKEorrUj0ZaTHE1QOr5SOMe5B6Qv+2Q==} '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} @@ -3285,16 +3244,16 @@ packages: '@types/zen-observable@0.8.3': resolution: {integrity: sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw==} - '@typescript-eslint/eslint-plugin@8.53.0': - resolution: {integrity: sha512-eEXsVvLPu8Z4PkFibtuFJLJOTAV/nPdgtSjkGoPpddpFk3/ym2oy97jynY6ic2m6+nc5M8SE1e9v/mHKsulcJg==} + '@typescript-eslint/eslint-plugin@8.54.0': + resolution: {integrity: sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.53.0 + '@typescript-eslint/parser': ^8.54.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.53.0': - resolution: {integrity: sha512-npiaib8XzbjtzS2N4HlqPvlpxpmZ14FjSJrteZpPxGUaYPlvhzlzUZ4mZyABo0EFrOWnvyd0Xxroq//hKhtAWg==} + '@typescript-eslint/parser@8.54.0': + resolution: {integrity: sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -3306,18 +3265,34 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/project-service@8.54.0': + resolution: {integrity: sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/scope-manager@8.53.0': resolution: {integrity: sha512-kWNj3l01eOGSdVBnfAF2K1BTh06WS0Yet6JUgb9Cmkqaz3Jlu0fdVUjj9UI8gPidBWSMqDIglmEXifSgDT/D0g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.54.0': + resolution: {integrity: sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/tsconfig-utils@8.53.0': resolution: {integrity: sha512-K6Sc0R5GIG6dNoPdOooQ+KtvT5KCKAvTcY8h2rIuul19vxH5OTQk7ArKkd4yTzkw66WnNY0kPPzzcmWA+XRmiA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.53.0': - resolution: {integrity: sha512-BBAUhlx7g4SmcLhn8cnbxoxtmS7hcq39xKCgiutL3oNx1TaIp+cny51s8ewnKMpVUKQUGb41RAUWZ9kxYdovuw==} + '@typescript-eslint/tsconfig-utils@8.54.0': + resolution: {integrity: sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.54.0': + resolution: {integrity: sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -3327,12 +3302,22 @@ packages: resolution: {integrity: sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.54.0': + resolution: {integrity: sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.53.0': resolution: {integrity: sha512-pw0c0Gdo7Z4xOG987u3nJ8akL9093yEEKv8QTJ+Bhkghj1xyj8cgPaavlr9rq8h7+s6plUJ4QJYw2gCZodqmGw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/typescript-estree@8.54.0': + resolution: {integrity: sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/utils@8.53.0': resolution: {integrity: sha512-XDY4mXTez3Z1iRDI5mbRhH4DFSt46oaIFsLg+Zn97+sYrXACziXSQcSelMybnVZ5pa1P6xYkPr5cMJyunM1ZDA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3340,10 +3325,21 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/utils@8.54.0': + resolution: {integrity: sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/visitor-keys@8.53.0': resolution: {integrity: sha512-LZ2NqIHFhvFwxG0qZeLL9DvdNAHPGCY5dIRwBhyYeU+LfLhcStE1ImjsuTG/WaVh3XysGaeLW8Rqq7cGkPCFvw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/visitor-keys@8.54.0': + resolution: {integrity: sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20251209.1': resolution: {integrity: sha512-F1cnYi+ZeinYQnaTQKKIsbuoq8vip5iepBkSZXlB8PjbG62LW1edUdktd/nVEc+Q+SEysSQ3jRdk9eU766s5iw==} cpu: [arm64] @@ -3906,8 +3902,8 @@ packages: react: ^18 || ^19 || ^19.0.0-rc react-dom: ^18 || ^19 || ^19.0.0-rc - code-inspector-plugin@1.4.1: - resolution: {integrity: sha512-DuOEoOWtkz3Mq6JTogJjSfXkVnXuGy6Gjfi+eBYtgRFlZmQ5sw1/LacsPnTK89O4Oz6gZj+zjxpwNfpWg3htpA==} + code-inspector-plugin@1.3.6: + resolution: {integrity: sha512-ddTg8embDqLZxKEdSNOm+/0YnVVgWKr10+Bu2qFqQDObj/3twGh0Z23TIz+5/URxfRhTPbp2sUSpWlw78piJbQ==} collapse-white-space@2.1.0: resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} @@ -3935,10 +3931,6 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - commander@11.1.0: - resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} - engines: {node: '>=16'} - commander@13.1.0: resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} engines: {node: '>=18'} @@ -3962,6 +3954,10 @@ packages: resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} engines: {node: '>= 12.0.0'} + comment-parser@1.4.5: + resolution: {integrity: sha512-aRDkn3uyIlCFfk5NUA+VdwMmMsh8JGhc4hapfV4yxymHGQ3BVskMQfoXGpCo5IoBuQ9tS5iiVKhCpTcB4pW4qw==} + engines: {node: '>= 12.0.0'} + common-tags@1.8.2: resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} engines: {node: '>=4.0.0'} @@ -4006,21 +4002,10 @@ packages: css-mediaquery@0.1.2: resolution: {integrity: sha512-COtn4EROW5dBGlE/4PiKnh6rZpAPxDeFLaEEwt4i10jpDMFt2EhQGS79QmmrO+iKCHv0PU/HrOWEhijFd1x99Q==} - css-select@5.2.2: - resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} - - css-tree@2.2.1: - resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} - css-tree@3.1.0: resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - css-what@6.2.2: - resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} - engines: {node: '>= 6'} - css.escape@1.5.1: resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} @@ -4029,10 +4014,6 @@ packages: engines: {node: '>=4'} hasBin: true - csso@5.0.5: - resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} - cssstyle@5.3.7: resolution: {integrity: sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==} engines: {node: '>=20'} @@ -4292,6 +4273,10 @@ packages: resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} @@ -4308,25 +4293,12 @@ packages: dom-accessibility-api@0.6.3: resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} - dom-serializer@2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - - domelementtype@2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - - domhandler@5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} - dompurify@3.2.7: resolution: {integrity: sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==} dompurify@3.3.0: resolution: {integrity: sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ==} - domutils@3.2.2: - resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} - dotenv@16.6.1: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} @@ -4458,8 +4430,8 @@ packages: peerDependencies: eslint: ^9.5.0 - eslint-flat-config-utils@2.1.4: - resolution: {integrity: sha512-bEnmU5gqzS+4O+id9vrbP43vByjF+8KOs+QuuV4OlqAuXmnRW2zfI/Rza1fQvdihQ5h4DUo0NqFAiViD4mSrzQ==} + eslint-flat-config-utils@3.0.0: + resolution: {integrity: sha512-bzTam/pSnPANR0GUz4g7lo4fyzlQZwuz/h8ytsSS4w59N/JlXH/l7jmyNVBLxPz3B9/9ntz5ZLevGpazyDXJQQ==} eslint-json-compat-utils@0.2.1: resolution: {integrity: sha512-YzEodbDyW8DX8bImKhAcCeu/L31Dd/70Bidx2Qex9OFUtgzXLqtfWL4Hr5fM/aCCB8QUZLuJur0S9k6UfgFkfg==} @@ -4499,8 +4471,8 @@ packages: peerDependencies: eslint: '>=9.0.0' - eslint-plugin-jsdoc@62.0.0: - resolution: {integrity: sha512-sNdIGLAvjFK3pB0SYFW74iXODZ4ifF8Ax13Wgq8jKepKnrCFzGo7+jRZfLf70h81SD7lPYnTE7MR2nhYSvaLTA==} + eslint-plugin-jsdoc@62.5.0: + resolution: {integrity: sha512-D+1haMVDzW/ZMoPwOnsbXCK07rJtsq98Z1v+ApvDKxSzYTTcPgmFc/nyUDCGmxm2cP7g7hszyjYHO7Zodl/43w==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 @@ -4527,20 +4499,20 @@ packages: peerDependencies: eslint: '>=8.45.0' - eslint-plugin-pnpm@1.4.3: - resolution: {integrity: sha512-wdWrkWN5mxRgEADkQvxwv0xA+0++/hYDD5OyXTL6UqPLUPdcCFQJO61NO7IKhEqb3GclWs02OoFs1METN+a3zQ==} + eslint-plugin-pnpm@1.5.0: + resolution: {integrity: sha512-ayMo1GvrQ/sF/bz1aOAiH0jv9eAqU2Z+a1ycoWz/uFFK5NxQDq49BDKQtBumcOUBf2VHyiTW4a8u+6KVqoIWzQ==} peerDependencies: eslint: ^9.0.0 - eslint-plugin-react-dom@2.7.0: - resolution: {integrity: sha512-9dvpfaAG3dC14jkDx5c9yXK9mQkYvxAUphQYfzorCntumQi5iOPsWNhITO+M1P+uIEpoc4HwuWkX42E/395AGQ==} + eslint-plugin-react-dom@2.8.1: + resolution: {integrity: sha512-VAVs3cp/0XTxdjTeLePtZVadj+om+N1VNVy7hyzSPACfh5ncAicC0zOIc5MB15KUWCj8PoG/ZnVny0YqeubgRg==} engines: {node: '>=20.19.0'} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - eslint-plugin-react-hooks-extra@2.7.0: - resolution: {integrity: sha512-pvjuFvUJkmmHLRjWgJcuRKI+UUq8DddyVU5PrMJY2G3LTYewr4kMHRGaFQ6qg+mbVZWovfxy+VjZjJ8PTfJTDg==} + eslint-plugin-react-hooks-extra@2.8.1: + resolution: {integrity: sha512-YeZLGzcib6UxlY7Gf+3zz8Mfl7u+OoVj3MukGaTuU6zkm1XQMI8/k4o16bKHuWtUauhn7Udl1bLAWfLgQM5UFw==} engines: {node: '>=20.19.0'} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -4552,8 +4524,8 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - eslint-plugin-react-naming-convention@2.7.0: - resolution: {integrity: sha512-BENL2tUVW/PSpFjLyfS0WloG5Buh76rvBM1hG/dCEyWDpHA6s4oJpF2Th9J92eKfim48/uprIPkKCB520Ev2nQ==} + eslint-plugin-react-naming-convention@2.8.1: + resolution: {integrity: sha512-fVj+hSzIe2I6HyPTf1nccMBXq72c4jbM3gk0T+szo/wewEF8/LgenjfquJoxHPpheb1fujFgdlo5HBhsilAX7Q==} engines: {node: '>=20.19.0'} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -4564,15 +4536,15 @@ packages: peerDependencies: eslint: '>=8.40' - eslint-plugin-react-web-api@2.7.0: - resolution: {integrity: sha512-vIuYyHbn2H337YZR8tKqUbzSNAiH6+9jk3atQBEgISJT0NTuwd80nhEPm3oPHfbgB3Sc4+rEhchVTnG+4BsFfg==} + eslint-plugin-react-web-api@2.8.1: + resolution: {integrity: sha512-NYsZKW1aJZ2XZuYTPzbwYLShvGcuXKRV/5TW61VO56gik/btil4Snt5UtyxshHbvT/zXx/Z+QsHul51/XM4/Qw==} engines: {node: '>=20.19.0'} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - eslint-plugin-react-x@2.7.0: - resolution: {integrity: sha512-/za228LsbKt1OlZ2XxP3R4xouG0rXeeuLyEnpHfKsAcY0mKPklempmQ5s0E9+SqcpQ/Jd+O4Jg9/30RU+vCqfw==} + eslint-plugin-react-x@2.8.1: + resolution: {integrity: sha512-4IpCMrsb63AVEa9diOApIm+T3wUGIzK+EB5vyYocO31YYPJ16+R7Fh4lV3S3fOuX1+aQ+Ad4SE0cYuZ2pF2Tlg==} engines: {node: '>=20.19.0'} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -4584,16 +4556,16 @@ packages: peerDependencies: eslint: '>=8.44.0' - eslint-plugin-sonarjs@3.0.5: - resolution: {integrity: sha512-dI62Ff3zMezUToi161hs2i1HX1ie8Ia2hO0jtNBfdgRBicAG4ydy2WPt0rMTrAe3ZrlqhpAO3w1jcQEdneYoFA==} + eslint-plugin-sonarjs@3.0.6: + resolution: {integrity: sha512-3mVUqsAUSylGfkJMj2v0aC2Cu/eUunDLm+XMjLf0uLjAZao205NWF3g6EXxcCAFO+rCZiQ6Or1WQkUcU9/sKFQ==} peerDependencies: eslint: ^8.0.0 || ^9.0.0 - eslint-plugin-storybook@10.2.0: - resolution: {integrity: sha512-OtQJ153FOusr8bIMzccjkfMFJEex/3NFx0iXZ+UaeQ0WXearQ+37EGgBay3onkFElyu8AySggq/fdTknPAEvPA==} + eslint-plugin-storybook@10.2.1: + resolution: {integrity: sha512-5+V+dlzTuZfNKUD8hPbLvCVtggcWfI2lDGTpiq0AENrHeAgcztj17wwDva96lbg/sAG20uX71l8HQo3s/GmpHw==} peerDependencies: eslint: '>=8' - storybook: ^10.2.0 + storybook: ^10.2.1 eslint-plugin-tailwindcss@3.18.2: resolution: {integrity: sha512-QbkMLDC/OkkjFQ1iz/5jkMdHfiMu/uwujUHLAJK5iwNHD8RTxVTlsUezE0toTZ6VhybNBsk+gYGPDq2agfeRNA==} @@ -4601,8 +4573,8 @@ packages: peerDependencies: tailwindcss: ^3.4.0 - eslint-plugin-toml@1.0.0: - resolution: {integrity: sha512-ACotflJMZ9CKCZlc0nznBxRNbiOYcBqWmXUSoKsGf6cyDV7EN1kGoD/WKnMo/lEsIF0WnzaYXcOU1HBOoyxRrg==} + eslint-plugin-toml@1.0.3: + resolution: {integrity: sha512-GlCBX+R313RvFY2Tj0ZmvzCEv8FDp1z2itvTFTV4bW/Bkbl3xEp9inWNsRWH3SiDUlxo8Pew31ILEp/3J0WxaA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} peerDependencies: eslint: '>=9.38.0' @@ -4622,8 +4594,8 @@ packages: '@typescript-eslint/eslint-plugin': optional: true - eslint-plugin-vue@10.6.2: - resolution: {integrity: sha512-nA5yUs/B1KmKzvC42fyD0+l9Yd+LtEpVhWRbXuDj0e+ZURcTtyRbMDWUeJmTAh2wC6jC83raS63anNM2YT3NPw==} + eslint-plugin-vue@10.7.0: + resolution: {integrity: sha512-r2XFCK4qlo1sxEoAMIoTTX0PZAdla0JJDt1fmYiworZUX67WeEGqm+JbyAg3M+pGiJ5U6Mp5WQbontXWtIW7TA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@stylistic/eslint-plugin': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 @@ -4636,11 +4608,11 @@ packages: '@typescript-eslint/parser': optional: true - eslint-plugin-yml@1.19.1: - resolution: {integrity: sha512-bYkOxyEiXh9WxUhVYPELdSHxGG5pOjCSeJOVkfdIyj6tuiHDxrES2WAW1dBxn3iaZQey57XflwLtCYRcNPOiOg==} - engines: {node: ^14.17.0 || >=16.0.0} + eslint-plugin-yml@3.0.0: + resolution: {integrity: sha512-kuAW6o3hlFHyF5p7TLon+AtvNWnsvRrb88pqywGMSCEqAP5d1gOMvNGgWLVlKHqmx5RbFhQLcxFDGmS4IU9DwA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0} peerDependencies: - eslint: '>=6.0.0' + eslint: '>=9.38.0' eslint-processor-vue-blocks@2.0.0: resolution: {integrity: sha512-u4W0CJwGoWY3bjXAuFpc/b6eK3NQEI8MoeW7ritKj3G3z/WtHrKjkqf+wk8mPEy5rlMGS+k6AZYOw2XBoN/02Q==} @@ -4696,6 +4668,10 @@ packages: resolution: {integrity: sha512-+gMeWRrIh/NsG+3NaLeWHuyeyk70p2tbvZIWBYcqQ4/7Xvars6GYTZNhF1sIeLcc6Wb11He5ffz3hsHyXFrw5A==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} + espree@11.1.0: + resolution: {integrity: sha512-WFWYhO1fV4iYkqOOvq8FbqIhr2pYfoDY0kCotMkDeNtGpiGGkZ1iov2u8ydjtgM8yF8rzK7oaTbw2NAzbAbehw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4821,9 +4797,6 @@ packages: fflate@0.4.8: resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==} - fflate@0.8.2: - resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} - file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -5345,6 +5318,10 @@ packages: resolution: {integrity: sha512-c7YbokssPOSHmqTbSAmTtnVgAVa/7lumWNYqomgd5KOMyPrRve2anx6lonfOsXEQacqF9FKVUj7bLg4vRSvdYA==} engines: {node: '>=20.0.0'} + jsdoc-type-pratt-parser@7.1.0: + resolution: {integrity: sha512-SX7q7XyCwzM/MEDCYz0l8GgGbJAACGFII9+WfNYr5SLEKukHWRy2Jk3iWRe7P+lpYJNs7oQ+OSei4JtKGUjd7A==} + engines: {node: '>=20.0.0'} + jsdom-testing-mocks@1.16.0: resolution: {integrity: sha512-wLrulXiLpjmcUYOYGEvz4XARkrmdVpyxzdBl9IAMbQ+ib2/UhUTRCn49McdNfXLff2ysGBUms49ZKX0LR1Q0gg==} engines: {node: '>=14'} @@ -5625,9 +5602,6 @@ packages: mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} - mdn-data@2.0.28: - resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} - mdn-data@2.12.2: resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} @@ -5815,10 +5789,6 @@ packages: mlly@1.8.0: resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} - modern-tar@0.7.3: - resolution: {integrity: sha512-4W79zekKGyYU4JXVmB78DOscMFaJth2gGhgfTl2alWE4rNe3nf4N2pqenQ0rEtIewrnD79M687Ouba3YGTLOvg==} - engines: {node: '>=18.0.0'} - module-alias@2.2.3: resolution: {integrity: sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==} @@ -6121,8 +6091,8 @@ packages: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} - pnpm-workspace-yaml@1.4.3: - resolution: {integrity: sha512-Q8B3SWuuISy/Ciag4DFP7MCrJX07wfaekcqD2o/msdIj4x8Ql3bZ/NEKOXV7mTVh7m1YdiFWiMi9xH+0zuEGHw==} + pnpm-workspace-yaml@1.5.0: + resolution: {integrity: sha512-PxdyJuFvq5B0qm3s9PaH/xOtSxrcvpBRr+BblhucpWjs8c79d4b7/cXhyY4AyHOHCnqklCYZTjfl0bT/mFVTRw==} points-on-curve@0.2.0: resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} @@ -6641,10 +6611,6 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - sax@1.4.4: - resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} - engines: {node: '>=11.0.0'} - saxes@6.0.0: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} @@ -6668,11 +6634,6 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} - engines: {node: '>=10'} - hasBin: true - semver@7.7.3: resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} @@ -6918,11 +6879,6 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svgo@4.0.0: - resolution: {integrity: sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==} - engines: {node: '>=16'} - hasBin: true - symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} @@ -7031,8 +6987,8 @@ packages: toggle-selection@1.0.6: resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} - toml-eslint-parser@1.0.2: - resolution: {integrity: sha512-ZI3t5mJiCt+1jQei8iNvKacpoPg9Qc9LumWZBJpWpHKbezA2df0nIXl16HjgwCr44qxpVm7azTYpJ5rylcbsNg==} + toml-eslint-parser@1.0.3: + resolution: {integrity: sha512-A5F0cM6+mDleacLIEUkmfpkBbnHJFV1d2rprHU2MXNk7mlxHq2zGojA+SRvQD1RoMo9gqjZPWEaKG4v1BQ48lw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} totalist@3.0.1: @@ -7559,9 +7515,9 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yaml-eslint-parser@1.3.2: - resolution: {integrity: sha512-odxVsHAkZYYglR30aPYRY4nUGJnoJ2y1ww2HDvZALo0BDETv9kWbi16J52eHs+PWRNmF4ub6nZqfVOeesOvntg==} - engines: {node: ^14.17.0 || >=16.0.0} + yaml-eslint-parser@2.0.0: + resolution: {integrity: sha512-h0uDm97wvT2bokfwwTmY6kJ1hp6YDFL0nRHwNKz8s/VD1FH/vvZjAKoMUE+un0eaYBSG7/c6h+lJTP+31tjgTw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} yaml@2.8.2: resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} @@ -7790,48 +7746,48 @@ snapshots: idb: 8.0.3 tslib: 2.8.1 - '@antfu/eslint-config@7.0.1(@eslint-react/eslint-plugin@2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(@next/eslint-plugin-next@16.1.5)(@vue/compiler-sfc@3.5.25)(eslint-plugin-react-hooks@7.0.1(eslint@9.39.2(jiti@1.21.7)))(eslint-plugin-react-refresh@0.4.26(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)(vitest@4.0.17(@types/node@18.15.0)(happy-dom@20.0.11)(jiti@1.21.7)(jsdom@27.3.0(canvas@3.2.0))(sass@1.93.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@antfu/eslint-config@7.2.0(@eslint-react/eslint-plugin@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(@next/eslint-plugin-next@16.1.6)(@vue/compiler-sfc@3.5.25)(eslint-plugin-react-hooks@7.0.1(eslint@9.39.2(jiti@1.21.7)))(eslint-plugin-react-refresh@0.4.26(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)(vitest@4.0.17(@types/node@18.15.0)(happy-dom@20.0.11)(jiti@1.21.7)(jsdom@27.3.0(canvas@3.2.0))(sass@1.93.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@antfu/install-pkg': 1.1.0 '@clack/prompts': 0.11.0 '@eslint-community/eslint-plugin-eslint-comments': 4.6.0(eslint@9.39.2(jiti@1.21.7)) '@eslint/markdown': 7.5.1 '@stylistic/eslint-plugin': 5.7.0(eslint@9.39.2(jiti@1.21.7)) - '@typescript-eslint/eslint-plugin': 8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) '@vitest/eslint-plugin': 1.6.6(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)(vitest@4.0.17(@types/node@18.15.0)(happy-dom@20.0.11)(jiti@1.21.7)(jsdom@27.3.0(canvas@3.2.0))(sass@1.93.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) ansis: 4.2.0 cac: 6.7.14 eslint: 9.39.2(jiti@1.21.7) eslint-config-flat-gitignore: 2.1.0(eslint@9.39.2(jiti@1.21.7)) - eslint-flat-config-utils: 2.1.4 + eslint-flat-config-utils: 3.0.0 eslint-merge-processors: 2.0.0(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-antfu: 3.1.3(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-command: 3.4.0(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-import-lite: 0.5.0(eslint@9.39.2(jiti@1.21.7)) - eslint-plugin-jsdoc: 62.0.0(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-jsdoc: 62.5.0(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-jsonc: 2.21.0(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-n: 17.23.2(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) eslint-plugin-no-only-tests: 3.3.0 eslint-plugin-perfectionist: 5.3.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - eslint-plugin-pnpm: 1.4.3(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-pnpm: 1.5.0(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-regexp: 2.10.0(eslint@9.39.2(jiti@1.21.7)) - eslint-plugin-toml: 1.0.0(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-toml: 1.0.3(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-unicorn: 62.0.0(eslint@9.39.2(jiti@1.21.7)) - eslint-plugin-unused-imports: 4.3.0(@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7)) - eslint-plugin-vue: 10.6.2(@stylistic/eslint-plugin@5.7.0(eslint@9.39.2(jiti@1.21.7)))(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(vue-eslint-parser@10.2.0(eslint@9.39.2(jiti@1.21.7))) - eslint-plugin-yml: 1.19.1(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-unused-imports: 4.3.0(@typescript-eslint/eslint-plugin@8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-vue: 10.7.0(@stylistic/eslint-plugin@5.7.0(eslint@9.39.2(jiti@1.21.7)))(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(vue-eslint-parser@10.2.0(eslint@9.39.2(jiti@1.21.7))) + eslint-plugin-yml: 3.0.0(eslint@9.39.2(jiti@1.21.7)) eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.25)(eslint@9.39.2(jiti@1.21.7)) globals: 17.0.0 jsonc-eslint-parser: 2.4.2 local-pkg: 1.1.2 parse-gitignore: 2.0.0 - toml-eslint-parser: 1.0.2 + toml-eslint-parser: 1.0.3 vue-eslint-parser: 10.2.0(eslint@9.39.2(jiti@1.21.7)) - yaml-eslint-parser: 1.3.2 + yaml-eslint-parser: 2.0.0 optionalDependencies: - '@eslint-react/eslint-plugin': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@next/eslint-plugin-next': 16.1.5 + '@eslint-react/eslint-plugin': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@next/eslint-plugin-next': 16.1.6 eslint-plugin-react-hooks: 7.0.1(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-react-refresh: 0.4.26(eslint@9.39.2(jiti@1.21.7)) transitivePeerDependencies: @@ -7846,8 +7802,6 @@ snapshots: package-manager-detector: 1.6.0 tinyexec: 1.0.2 - '@antfu/utils@8.1.1': {} - '@asamuzakjp/css-color@4.1.1': dependencies: '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) @@ -8035,7 +7989,7 @@ snapshots: picocolors: 1.1.1 sisteransi: 1.0.5 - '@code-inspector/core@1.4.1': + '@code-inspector/core@1.3.6': dependencies: '@vue/compiler-dom': 3.5.25 chalk: 4.1.2 @@ -8045,35 +7999,35 @@ snapshots: transitivePeerDependencies: - supports-color - '@code-inspector/esbuild@1.4.1': + '@code-inspector/esbuild@1.3.6': dependencies: - '@code-inspector/core': 1.4.1 + '@code-inspector/core': 1.3.6 transitivePeerDependencies: - supports-color - '@code-inspector/mako@1.4.1': + '@code-inspector/mako@1.3.6': dependencies: - '@code-inspector/core': 1.4.1 + '@code-inspector/core': 1.3.6 transitivePeerDependencies: - supports-color - '@code-inspector/turbopack@1.4.1': + '@code-inspector/turbopack@1.3.6': dependencies: - '@code-inspector/core': 1.4.1 - '@code-inspector/webpack': 1.4.1 + '@code-inspector/core': 1.3.6 + '@code-inspector/webpack': 1.3.6 transitivePeerDependencies: - supports-color - '@code-inspector/vite@1.4.1': + '@code-inspector/vite@1.3.6': dependencies: - '@code-inspector/core': 1.4.1 + '@code-inspector/core': 1.3.6 chalk: 4.1.1 transitivePeerDependencies: - supports-color - '@code-inspector/webpack@1.4.1': + '@code-inspector/webpack@1.3.6': dependencies: - '@code-inspector/core': 1.4.1 + '@code-inspector/core': 1.3.6 transitivePeerDependencies: - supports-color @@ -8099,19 +8053,8 @@ snapshots: '@csstools/css-tokenizer@3.0.4': {} - '@cyberalien/svg-utils@1.0.11': - dependencies: - '@iconify/types': 2.0.0 - '@discoveryjs/json-ext@0.5.7': {} - '@egoist/tailwindcss-icons@1.9.0(tailwindcss@3.4.18(tsx@4.21.0)(yaml@2.8.2))': - dependencies: - '@iconify/utils': 2.3.0 - tailwindcss: 3.4.18(tsx@4.21.0)(yaml@2.8.2) - transitivePeerDependencies: - - supports-color - '@emnapi/core@1.7.1': dependencies: '@emnapi/wasi-threads': 1.1.0 @@ -8140,13 +8083,13 @@ snapshots: esquery: 1.7.0 jsdoc-type-pratt-parser: 7.0.0 - '@es-joy/jsdoccomment@0.79.0': + '@es-joy/jsdoccomment@0.83.0': dependencies: '@types/estree': 1.0.8 - '@typescript-eslint/types': 8.53.0 - comment-parser: 1.4.1 + '@typescript-eslint/types': 8.54.0 + comment-parser: 1.4.5 esquery: 1.7.0 - jsdoc-type-pratt-parser: 7.0.0 + jsdoc-type-pratt-parser: 7.1.0 '@es-joy/resolve.exports@1.2.0': {} @@ -8244,63 +8187,60 @@ snapshots: eslint: 9.39.2(jiti@1.21.7) eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.12.1': {} - '@eslint-community/regexpp@4.12.2': {} - '@eslint-react/ast@2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + '@eslint-react/ast@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@eslint-react/eff': 2.7.0 - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/eff': 2.8.1 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) eslint: 9.39.2(jiti@1.21.7) string-ts: 2.3.1 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@eslint-react/core@2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + '@eslint-react/core@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@eslint-react/ast': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/eff': 2.7.0 - '@eslint-react/shared': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/var': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - birecord: 0.1.1 + '@eslint-react/ast': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/eff': 2.8.1 + '@eslint-react/shared': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/var': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) eslint: 9.39.2(jiti@1.21.7) ts-pattern: 5.9.0 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@eslint-react/eff@2.7.0': {} + '@eslint-react/eff@2.8.1': {} - '@eslint-react/eslint-plugin@2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + '@eslint-react/eslint-plugin@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@eslint-react/eff': 2.7.0 - '@eslint-react/shared': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/type-utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/eff': 2.8.1 + '@eslint-react/shared': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/type-utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) eslint: 9.39.2(jiti@1.21.7) - eslint-plugin-react-dom: 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - eslint-plugin-react-hooks-extra: 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - eslint-plugin-react-naming-convention: 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - eslint-plugin-react-web-api: 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - eslint-plugin-react-x: 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + eslint-plugin-react-dom: 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + eslint-plugin-react-hooks-extra: 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + eslint-plugin-react-naming-convention: 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + eslint-plugin-react-web-api: 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + eslint-plugin-react-x: 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@eslint-react/shared@2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + '@eslint-react/shared@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@eslint-react/eff': 2.7.0 - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/eff': 2.8.1 + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) eslint: 9.39.2(jiti@1.21.7) ts-pattern: 5.9.0 typescript: 5.9.3 @@ -8308,13 +8248,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint-react/var@2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + '@eslint-react/var@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@eslint-react/ast': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/eff': 2.7.0 - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/ast': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/eff': 2.8.1 + '@eslint-react/shared': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) eslint: 9.39.2(jiti@1.21.7) ts-pattern: 5.9.0 typescript: 5.9.3 @@ -8349,6 +8290,10 @@ snapshots: dependencies: '@eslint/core': 0.17.0 + '@eslint/config-helpers@0.5.1': + dependencies: + '@eslint/core': 1.0.1 + '@eslint/core@0.14.0': dependencies: '@types/json-schema': 7.0.15 @@ -8475,39 +8420,8 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@iconify-json/heroicons@1.2.3': - dependencies: - '@iconify/types': 2.0.0 - - '@iconify-json/ri@1.2.7': - dependencies: - '@iconify/types': 2.0.0 - - '@iconify/tools@5.0.2': - dependencies: - '@cyberalien/svg-utils': 1.0.11 - '@iconify/types': 2.0.0 - '@iconify/utils': 3.1.0 - fflate: 0.8.2 - modern-tar: 0.7.3 - pathe: 2.0.3 - svgo: 4.0.0 - '@iconify/types@2.0.0': {} - '@iconify/utils@2.3.0': - dependencies: - '@antfu/install-pkg': 1.1.0 - '@antfu/utils': 8.1.1 - '@iconify/types': 2.0.0 - debug: 4.4.3 - globals: 15.15.0 - kolorist: 1.8.0 - local-pkg: 1.1.2 - mlly: 1.8.0 - transitivePeerDependencies: - - supports-color - '@iconify/utils@3.1.0': dependencies: '@antfu/install-pkg': 1.1.0 @@ -9029,7 +8943,7 @@ snapshots: '@next/env@16.1.5': {} - '@next/eslint-plugin-next@16.1.5': + '@next/eslint-plugin-next@16.1.6': dependencies: fast-glob: 3.3.1 @@ -10093,7 +10007,7 @@ snapshots: - csstype - utf-8-validate - '@tanstack/eslint-plugin-query@5.91.2(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + '@tanstack/eslint-plugin-query@5.91.3(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': dependencies: '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) eslint: 9.39.2(jiti@1.21.7) @@ -10233,11 +10147,11 @@ snapshots: dependencies: '@testing-library/dom': 10.4.1 - '@tsslint/cli@3.0.1(@tsslint/compat-eslint@3.0.1(jiti@1.21.7)(typescript@5.9.3))(typescript@5.9.3)': + '@tsslint/cli@3.0.2(@tsslint/compat-eslint@3.0.2(jiti@1.21.7)(typescript@5.9.3))(typescript@5.9.3)': dependencies: '@clack/prompts': 0.8.2 - '@tsslint/config': 3.0.1(@tsslint/compat-eslint@3.0.1(jiti@1.21.7)(typescript@5.9.3))(typescript@5.9.3) - '@tsslint/core': 3.0.1 + '@tsslint/config': 3.0.2(@tsslint/compat-eslint@3.0.2(jiti@1.21.7)(typescript@5.9.3))(typescript@5.9.3) + '@tsslint/core': 3.0.2 '@volar/language-core': 2.4.27 '@volar/language-hub': 0.0.1 '@volar/typescript': 2.4.27 @@ -10247,32 +10161,32 @@ snapshots: - '@tsslint/compat-eslint' - tsl - '@tsslint/compat-eslint@3.0.1(jiti@1.21.7)(typescript@5.9.3)': + '@tsslint/compat-eslint@3.0.2(jiti@1.21.7)(typescript@5.9.3)': dependencies: - '@tsslint/types': 3.0.1 - '@typescript-eslint/parser': 8.53.0(eslint@9.27.0(jiti@1.21.7))(typescript@5.9.3) + '@tsslint/types': 3.0.2 + '@typescript-eslint/parser': 8.54.0(eslint@9.27.0(jiti@1.21.7))(typescript@5.9.3) eslint: 9.27.0(jiti@1.21.7) transitivePeerDependencies: - jiti - supports-color - typescript - '@tsslint/config@3.0.1(@tsslint/compat-eslint@3.0.1(jiti@1.21.7)(typescript@5.9.3))(typescript@5.9.3)': + '@tsslint/config@3.0.2(@tsslint/compat-eslint@3.0.2(jiti@1.21.7)(typescript@5.9.3))(typescript@5.9.3)': dependencies: - '@tsslint/types': 3.0.1 + '@tsslint/types': 3.0.2 minimatch: 10.1.1 ts-api-utils: 2.4.0(typescript@5.9.3) optionalDependencies: - '@tsslint/compat-eslint': 3.0.1(jiti@1.21.7)(typescript@5.9.3) + '@tsslint/compat-eslint': 3.0.2(jiti@1.21.7)(typescript@5.9.3) transitivePeerDependencies: - typescript - '@tsslint/core@3.0.1': + '@tsslint/core@3.0.2': dependencies: - '@tsslint/types': 3.0.1 + '@tsslint/types': 3.0.2 minimatch: 10.1.1 - '@tsslint/types@3.0.1': {} + '@tsslint/types@3.0.2': {} '@tybys/wasm-util@0.10.1': dependencies: @@ -10535,14 +10449,14 @@ snapshots: '@types/zen-observable@0.8.3': {} - '@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/type-utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.53.0 + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/type-utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.54.0 eslint: 9.39.2(jiti@1.21.7) ignore: 7.0.5 natural-compare: 1.4.0 @@ -10551,24 +10465,24 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.53.0(eslint@9.27.0(jiti@1.21.7))(typescript@5.9.3)': + '@typescript-eslint/parser@8.54.0(eslint@9.27.0(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.53.0 + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.54.0 debug: 4.4.3 eslint: 9.27.0(jiti@1.21.7) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + '@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.53.0 + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.54.0 debug: 4.4.3 eslint: 9.39.2(jiti@1.21.7) typescript: 5.9.3 @@ -10584,20 +10498,38 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/project-service@8.54.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.54.0(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/scope-manager@8.53.0': dependencies: '@typescript-eslint/types': 8.53.0 '@typescript-eslint/visitor-keys': 8.53.0 + '@typescript-eslint/scope-manager@8.54.0': + dependencies: + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/visitor-keys': 8.54.0 + '@typescript-eslint/tsconfig-utils@8.53.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.54.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.2(jiti@1.21.7) ts-api-utils: 2.4.0(typescript@5.9.3) @@ -10607,6 +10539,8 @@ snapshots: '@typescript-eslint/types@8.53.0': {} + '@typescript-eslint/types@8.54.0': {} + '@typescript-eslint/typescript-estree@8.53.0(typescript@5.9.3)': dependencies: '@typescript-eslint/project-service': 8.53.0(typescript@5.9.3) @@ -10622,6 +10556,21 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/typescript-estree@8.54.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.54.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.54.0(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/visitor-keys': 8.54.0 + debug: 4.4.3 + minimatch: 9.0.5 + semver: 7.7.3 + tinyglobby: 0.2.15 + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/utils@8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@1.21.7)) @@ -10633,11 +10582,27 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@1.21.7)) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + eslint: 9.39.2(jiti@1.21.7) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/visitor-keys@8.53.0': dependencies: '@typescript-eslint/types': 8.53.0 eslint-visitor-keys: 4.2.1 + '@typescript-eslint/visitor-keys@8.54.0': + dependencies: + '@typescript-eslint/types': 8.54.0 + eslint-visitor-keys: 4.2.1 + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20251209.1': optional: true @@ -11258,14 +11223,14 @@ snapshots: - '@types/react' - '@types/react-dom' - code-inspector-plugin@1.4.1: + code-inspector-plugin@1.3.6: dependencies: - '@code-inspector/core': 1.4.1 - '@code-inspector/esbuild': 1.4.1 - '@code-inspector/mako': 1.4.1 - '@code-inspector/turbopack': 1.4.1 - '@code-inspector/vite': 1.4.1 - '@code-inspector/webpack': 1.4.1 + '@code-inspector/core': 1.3.6 + '@code-inspector/esbuild': 1.3.6 + '@code-inspector/mako': 1.3.6 + '@code-inspector/turbopack': 1.3.6 + '@code-inspector/vite': 1.3.6 + '@code-inspector/webpack': 1.3.6 chalk: 4.1.1 transitivePeerDependencies: - supports-color @@ -11294,8 +11259,6 @@ snapshots: comma-separated-tokens@2.0.3: {} - commander@11.1.0: {} - commander@13.1.0: {} commander@2.20.3: @@ -11309,6 +11272,8 @@ snapshots: comment-parser@1.4.1: {} + comment-parser@1.4.5: {} + common-tags@1.8.2: {} compare-versions@6.1.1: {} @@ -11352,34 +11317,15 @@ snapshots: css-mediaquery@0.1.2: {} - css-select@5.2.2: - dependencies: - boolbase: 1.0.0 - css-what: 6.2.2 - domhandler: 5.0.3 - domutils: 3.2.2 - nth-check: 2.1.1 - - css-tree@2.2.1: - dependencies: - mdn-data: 2.0.28 - source-map-js: 1.2.1 - css-tree@3.1.0: dependencies: mdn-data: 2.12.2 source-map-js: 1.2.1 - css-what@6.2.2: {} - css.escape@1.5.1: {} cssesc@3.0.0: {} - csso@5.0.5: - dependencies: - css-tree: 2.2.1 - cssstyle@5.3.7: dependencies: '@asamuzakjp/css-color': 4.1.1 @@ -11642,6 +11588,8 @@ snapshots: diff-sequences@27.5.1: {} + diff-sequences@29.6.3: {} + dlv@1.1.3: {} dnd-core@14.0.1: @@ -11658,18 +11606,6 @@ snapshots: dom-accessibility-api@0.6.3: {} - dom-serializer@2.0.0: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - entities: 4.5.0 - - domelementtype@2.3.0: {} - - domhandler@5.0.3: - dependencies: - domelementtype: 2.3.0 - dompurify@3.2.7: optionalDependencies: '@types/trusted-types': 2.0.7 @@ -11678,12 +11614,6 @@ snapshots: optionalDependencies: '@types/trusted-types': 2.0.7 - domutils@3.2.2: - dependencies: - dom-serializer: 2.0.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - dotenv@16.6.1: {} duplexer@0.1.2: {} @@ -11828,8 +11758,9 @@ snapshots: '@eslint/compat': 1.4.1(eslint@9.39.2(jiti@1.21.7)) eslint: 9.39.2(jiti@1.21.7) - eslint-flat-config-utils@2.1.4: + eslint-flat-config-utils@3.0.0: dependencies: + '@eslint/config-helpers': 0.5.1 pathe: 2.0.3 eslint-json-compat-utils@0.2.1(eslint@9.39.2(jiti@1.21.7))(jsonc-eslint-parser@2.4.2): @@ -11862,16 +11793,16 @@ snapshots: dependencies: eslint: 9.39.2(jiti@1.21.7) - eslint-plugin-jsdoc@62.0.0(eslint@9.39.2(jiti@1.21.7)): + eslint-plugin-jsdoc@62.5.0(eslint@9.39.2(jiti@1.21.7)): dependencies: - '@es-joy/jsdoccomment': 0.79.0 + '@es-joy/jsdoccomment': 0.83.0 '@es-joy/resolve.exports': 1.2.0 are-docs-informative: 0.0.2 - comment-parser: 1.4.1 + comment-parser: 1.4.5 debug: 4.4.3 escape-string-regexp: 4.0.0 eslint: 9.39.2(jiti@1.21.7) - espree: 11.0.0 + espree: 11.1.0 esquery: 1.7.0 html-entities: 2.6.0 object-deep-merge: 2.0.0 @@ -11923,27 +11854,27 @@ snapshots: - supports-color - typescript - eslint-plugin-pnpm@1.4.3(eslint@9.39.2(jiti@1.21.7)): + eslint-plugin-pnpm@1.5.0(eslint@9.39.2(jiti@1.21.7)): dependencies: empathic: 2.0.0 eslint: 9.39.2(jiti@1.21.7) jsonc-eslint-parser: 2.4.2 pathe: 2.0.3 - pnpm-workspace-yaml: 1.4.3 + pnpm-workspace-yaml: 1.5.0 tinyglobby: 0.2.15 yaml: 2.8.2 - yaml-eslint-parser: 1.3.2 + yaml-eslint-parser: 2.0.0 - eslint-plugin-react-dom@2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): + eslint-plugin-react-dom@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): dependencies: - '@eslint-react/ast': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/core': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/eff': 2.7.0 - '@eslint-react/shared': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/var': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/ast': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/core': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/eff': 2.8.1 + '@eslint-react/shared': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/var': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) compare-versions: 6.1.1 eslint: 9.39.2(jiti@1.21.7) string-ts: 2.3.1 @@ -11952,17 +11883,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-react-hooks-extra@2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): + eslint-plugin-react-hooks-extra@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): dependencies: - '@eslint-react/ast': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/core': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/eff': 2.7.0 - '@eslint-react/shared': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/var': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/type-utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/ast': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/core': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/eff': 2.8.1 + '@eslint-react/shared': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/var': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/type-utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) eslint: 9.39.2(jiti@1.21.7) string-ts: 2.3.1 ts-pattern: 5.9.0 @@ -11981,17 +11912,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-react-naming-convention@2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): + eslint-plugin-react-naming-convention@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): dependencies: - '@eslint-react/ast': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/core': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/eff': 2.7.0 - '@eslint-react/shared': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/var': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/type-utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/ast': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/core': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/eff': 2.8.1 + '@eslint-react/shared': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/var': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/type-utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) compare-versions: 6.1.1 eslint: 9.39.2(jiti@1.21.7) string-ts: 2.3.1 @@ -12004,16 +11935,17 @@ snapshots: dependencies: eslint: 9.39.2(jiti@1.21.7) - eslint-plugin-react-web-api@2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): + eslint-plugin-react-web-api@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): dependencies: - '@eslint-react/ast': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/core': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/eff': 2.7.0 - '@eslint-react/shared': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/var': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/ast': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/core': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/eff': 2.8.1 + '@eslint-react/shared': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/var': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + birecord: 0.1.1 eslint: 9.39.2(jiti@1.21.7) string-ts: 2.3.1 ts-pattern: 5.9.0 @@ -12021,17 +11953,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-react-x@2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): + eslint-plugin-react-x@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): dependencies: - '@eslint-react/ast': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/core': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/eff': 2.7.0 - '@eslint-react/shared': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@eslint-react/var': 2.7.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/type-utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/ast': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/core': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/eff': 2.8.1 + '@eslint-react/shared': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@eslint-react/var': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/type-utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) compare-versions: 6.1.1 eslint: 9.39.2(jiti@1.21.7) is-immutable-type: 5.0.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) @@ -12053,21 +11985,21 @@ snapshots: regexp-ast-analysis: 0.7.1 scslre: 0.3.0 - eslint-plugin-sonarjs@3.0.5(eslint@9.39.2(jiti@1.21.7)): + eslint-plugin-sonarjs@3.0.6(eslint@9.39.2(jiti@1.21.7)): dependencies: - '@eslint-community/regexpp': 4.12.1 + '@eslint-community/regexpp': 4.12.2 builtin-modules: 3.3.0 bytes: 3.1.2 eslint: 9.39.2(jiti@1.21.7) functional-red-black-tree: 1.0.1 jsx-ast-utils-x: 0.1.0 lodash.merge: 4.6.2 - minimatch: 9.0.5 + minimatch: 10.1.1 scslre: 0.3.0 - semver: 7.7.2 + semver: 7.7.3 typescript: 5.9.3 - eslint-plugin-storybook@10.2.0(eslint@9.39.2(jiti@1.21.7))(storybook@10.2.0(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3): + eslint-plugin-storybook@10.2.1(eslint@9.39.2(jiti@1.21.7))(storybook@10.2.0(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3): dependencies: '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) eslint: 9.39.2(jiti@1.21.7) @@ -12082,13 +12014,13 @@ snapshots: postcss: 8.5.6 tailwindcss: 3.4.18(tsx@4.21.0)(yaml@2.8.2) - eslint-plugin-toml@1.0.0(eslint@9.39.2(jiti@1.21.7)): + eslint-plugin-toml@1.0.3(eslint@9.39.2(jiti@1.21.7)): dependencies: '@eslint/core': 1.0.1 '@eslint/plugin-kit': 0.5.1 debug: 4.4.3 eslint: 9.39.2(jiti@1.21.7) - toml-eslint-parser: 1.0.2 + toml-eslint-parser: 1.0.3 transitivePeerDependencies: - supports-color @@ -12114,13 +12046,13 @@ snapshots: semver: 7.7.3 strip-indent: 4.1.1 - eslint-plugin-unused-imports@4.3.0(@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7)): + eslint-plugin-unused-imports@4.3.0(@typescript-eslint/eslint-plugin@8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7)): dependencies: eslint: 9.39.2(jiti@1.21.7) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - eslint-plugin-vue@10.6.2(@stylistic/eslint-plugin@5.7.0(eslint@9.39.2(jiti@1.21.7)))(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(vue-eslint-parser@10.2.0(eslint@9.39.2(jiti@1.21.7))): + eslint-plugin-vue@10.7.0(@stylistic/eslint-plugin@5.7.0(eslint@9.39.2(jiti@1.21.7)))(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(vue-eslint-parser@10.2.0(eslint@9.39.2(jiti@1.21.7))): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@1.21.7)) eslint: 9.39.2(jiti@1.21.7) @@ -12132,17 +12064,18 @@ snapshots: xml-name-validator: 4.0.0 optionalDependencies: '@stylistic/eslint-plugin': 5.7.0(eslint@9.39.2(jiti@1.21.7)) - '@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - eslint-plugin-yml@1.19.1(eslint@9.39.2(jiti@1.21.7)): + eslint-plugin-yml@3.0.0(eslint@9.39.2(jiti@1.21.7)): dependencies: + '@eslint/core': 1.0.1 + '@eslint/plugin-kit': 0.5.1 debug: 4.4.3 - diff-sequences: 27.5.1 - escape-string-regexp: 4.0.0 + diff-sequences: 29.6.3 + escape-string-regexp: 5.0.0 eslint: 9.39.2(jiti@1.21.7) - eslint-compat-utils: 0.6.5(eslint@9.39.2(jiti@1.21.7)) natural-compare: 1.4.0 - yaml-eslint-parser: 1.3.2 + yaml-eslint-parser: 2.0.0 transitivePeerDependencies: - supports-color @@ -12263,6 +12196,12 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 5.0.0 + espree@11.1.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 5.0.0 + espree@9.6.1: dependencies: acorn: 8.15.0 @@ -12396,8 +12335,6 @@ snapshots: fflate@0.4.8: {} - fflate@0.8.2: {} - file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -12828,7 +12765,7 @@ snapshots: is-immutable-type@5.0.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): dependencies: - '@typescript-eslint/type-utils': 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/type-utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) eslint: 9.39.2(jiti@1.21.7) ts-api-utils: 2.4.0(typescript@5.9.3) ts-declaration-location: 1.0.7(typescript@5.9.3) @@ -12919,6 +12856,8 @@ snapshots: jsdoc-type-pratt-parser@7.0.0: {} + jsdoc-type-pratt-parser@7.1.0: {} + jsdom-testing-mocks@1.16.0: dependencies: bezier-easing: 2.1.0 @@ -13354,8 +13293,6 @@ snapshots: dependencies: '@types/mdast': 4.0.4 - mdn-data@2.0.28: {} - mdn-data@2.12.2: {} memoize-one@5.2.1: {} @@ -13720,8 +13657,6 @@ snapshots: pkg-types: 1.3.1 ufo: 1.6.2 - modern-tar@0.7.3: {} - module-alias@2.2.3: {} monaco-editor@0.55.1: @@ -14012,7 +13947,7 @@ snapshots: pluralize@8.0.0: {} - pnpm-workspace-yaml@1.4.3: + pnpm-workspace-yaml@1.5.0: dependencies: yaml: 2.8.2 @@ -14678,8 +14613,6 @@ snapshots: optionalDependencies: '@parcel/watcher': 2.5.1 - sax@1.4.4: {} - saxes@6.0.0: dependencies: xmlchars: 2.2.0 @@ -14704,8 +14637,6 @@ snapshots: semver@6.3.1: {} - semver@7.7.2: {} - semver@7.7.3: {} serialize-javascript@6.0.2: @@ -14999,16 +14930,6 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svgo@4.0.0: - dependencies: - commander: 11.1.0 - css-select: 5.2.2 - css-tree: 3.1.0 - css-what: 6.2.2 - csso: 5.0.5 - picocolors: 1.1.1 - sax: 1.4.4 - symbol-tree@3.2.4: {} synckit@0.11.11: @@ -15133,7 +15054,7 @@ snapshots: toggle-selection@1.0.6: {} - toml-eslint-parser@1.0.2: + toml-eslint-parser@1.0.3: dependencies: eslint-visitor-keys: 5.0.0 @@ -15635,9 +15556,9 @@ snapshots: yallist@3.1.1: {} - yaml-eslint-parser@1.3.2: + yaml-eslint-parser@2.0.0: dependencies: - eslint-visitor-keys: 3.4.3 + eslint-visitor-keys: 5.0.0 yaml: 2.8.2 yaml@2.8.2: {} diff --git a/web/scripts/gen-doc-paths.ts b/web/scripts/gen-doc-paths.ts index f0393937c2..03c3cdaddc 100644 --- a/web/scripts/gen-doc-paths.ts +++ b/web/scripts/gen-doc-paths.ts @@ -282,6 +282,15 @@ function generateTypeDefinitions( } lines.push('') + + // Add UseDifyNodesPath helper type after UseDifyPath + if (section === 'use-dify') { + lines.push('// UseDify node paths (without prefix)') + // eslint-disable-next-line no-template-curly-in-string + lines.push('type ExtractNodesPath = T extends `/use-dify/nodes/${infer Path}` ? Path : never') + lines.push('export type UseDifyNodesPath = ExtractNodesPath') + lines.push('') + } } // Generate API reference type (English paths only) diff --git a/web/tailwind-common-config.ts b/web/tailwind-common-config.ts index 8b5cd2469a..3a4ebf3180 100644 --- a/web/tailwind-common-config.ts +++ b/web/tailwind-common-config.ts @@ -1,14 +1,8 @@ -import path from 'node:path' -import { fileURLToPath } from 'node:url' import tailwindTypography from '@tailwindcss/typography' // @ts-expect-error workaround for turbopack issue import tailwindThemeVarDefine from './themes/tailwind-theme-var-define.ts' import typography from './typography.js' -const _dirname = typeof __dirname !== 'undefined' - ? __dirname - : path.dirname(fileURLToPath(import.meta.url)) - const config = { theme: { typography, @@ -159,21 +153,7 @@ const config = { }, }, }, - plugins: [ - tailwindTypography, - // iconsPlugin({ - // collections: { - // ...getCollectionsFromSubDirs(path.resolve(_dirname, 'app/components/base/icons/assets/public'), 'custom-public'), - // ...getCollectionsFromSubDirs(path.resolve(_dirname, 'app/components/base/icons/assets/vender'), 'custom-vender'), - // ...getIconCollections(['heroicons', 'ri']), - // }, - // extraProperties: { - // width: '1rem', - // height: '1rem', - // display: 'block', - // }, - // }), - ], + plugins: [tailwindTypography], // https://github.com/tailwindlabs/tailwindcss/discussions/5969 corePlugins: { preflight: false, diff --git a/web/types/doc-paths.ts b/web/types/doc-paths.ts index 7a74f0905d..8f95249354 100644 --- a/web/types/doc-paths.ts +++ b/web/types/doc-paths.ts @@ -2,7 +2,7 @@ // DON NOT EDIT IT MANUALLY // // Generated from: https://raw.githubusercontent.com/langgenius/dify-docs/refs/heads/main/docs.json -// Generated at: 2026-01-21T07:24:02.413Z +// Generated at: 2026-01-30T09:14:29.304Z // Language prefixes export type DocLanguage = 'en' | 'zh' | 'ja' @@ -104,6 +104,10 @@ export type UseDifyPath = | '/use-dify/workspace/subscription-management' | '/use-dify/workspace/team-members-management' +// UseDify node paths (without prefix) +type ExtractNodesPath = T extends `/use-dify/nodes/${infer Path}` ? Path : never +export type UseDifyNodesPath = ExtractNodesPath + // SelfHost paths export type SelfHostPath = | '/self-host/advanced-deployments/local-source-code'