Compare commits

...

4 Commits

Author SHA1 Message Date
Stephen Zhou
015849f2b3 tweaks 2026-04-02 10:17:54 +08:00
Stephen Zhou
3c33301a08 tweaks 2026-04-02 09:23:40 +08:00
Stephen Zhou
eae0718c19 refactor: move to unocss 2026-04-02 09:07:24 +08:00
Renzo
4e1d060439 refactor: select in message_service and ops_service (#34414)
Some checks failed
autofix.ci / autofix (push) Has been cancelled
Build and Push API & Web / build (api, {{defaultContext}}:api, Dockerfile, DIFY_API_IMAGE_NAME, linux/amd64, ubuntu-latest, build-api-amd64) (push) Has been cancelled
Build and Push API & Web / build (api, {{defaultContext}}:api, Dockerfile, DIFY_API_IMAGE_NAME, linux/arm64, ubuntu-24.04-arm, build-api-arm64) (push) Has been cancelled
Build and Push API & Web / build (web, {{defaultContext}}, web/Dockerfile, DIFY_WEB_IMAGE_NAME, linux/amd64, ubuntu-latest, build-web-amd64) (push) Has been cancelled
Build and Push API & Web / build (web, {{defaultContext}}, web/Dockerfile, DIFY_WEB_IMAGE_NAME, linux/arm64, ubuntu-24.04-arm, build-web-arm64) (push) Has been cancelled
Build and Push API & Web / create-manifest (api, DIFY_API_IMAGE_NAME, merge-api-images) (push) Has been cancelled
Build and Push API & Web / create-manifest (web, DIFY_WEB_IMAGE_NAME, merge-web-images) (push) Has been cancelled
Main CI Pipeline / Skip Duplicate Checks (push) Has been cancelled
Main CI Pipeline / Check Changed Files (push) Has been cancelled
Main CI Pipeline / Run API Tests (push) Has been cancelled
Main CI Pipeline / Skip API Tests (push) Has been cancelled
Main CI Pipeline / API Tests (push) Has been cancelled
Main CI Pipeline / Run Web Tests (push) Has been cancelled
Main CI Pipeline / Skip Web Tests (push) Has been cancelled
Main CI Pipeline / Web Tests (push) Has been cancelled
Main CI Pipeline / Run Web Full-Stack E2E (push) Has been cancelled
Main CI Pipeline / Skip Web Full-Stack E2E (push) Has been cancelled
Main CI Pipeline / Web Full-Stack E2E (push) Has been cancelled
Main CI Pipeline / Style Check (push) Has been cancelled
Main CI Pipeline / Run VDB Tests (push) Has been cancelled
Main CI Pipeline / Skip VDB Tests (push) Has been cancelled
Main CI Pipeline / VDB Tests (push) Has been cancelled
Main CI Pipeline / Run DB Migration Test (push) Has been cancelled
Main CI Pipeline / Skip DB Migration Test (push) Has been cancelled
Main CI Pipeline / DB Migration Test (push) Has been cancelled
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-04-01 16:37:27 +00:00
22 changed files with 987 additions and 226 deletions

View File

@@ -3,6 +3,7 @@ from typing import Union
from graphon.model_runtime.entities.model_entities import ModelType
from pydantic import TypeAdapter
from sqlalchemy import select
from sqlalchemy.orm import sessionmaker
from core.app.apps.advanced_chat.app_config_manager import AdvancedChatAppConfigManager
@@ -75,17 +76,15 @@ class MessageService:
fetch_limit = limit + 1
if first_id:
first_message = (
db.session.query(Message)
.where(Message.conversation_id == conversation.id, Message.id == first_id)
.first()
first_message = db.session.scalar(
select(Message).where(Message.conversation_id == conversation.id, Message.id == first_id).limit(1)
)
if not first_message:
raise FirstMessageNotExistsError()
history_messages = (
db.session.query(Message)
history_messages = db.session.scalars(
select(Message)
.where(
Message.conversation_id == conversation.id,
Message.created_at < first_message.created_at,
@@ -93,16 +92,14 @@ class MessageService:
)
.order_by(Message.created_at.desc())
.limit(fetch_limit)
.all()
)
).all()
else:
history_messages = (
db.session.query(Message)
history_messages = db.session.scalars(
select(Message)
.where(Message.conversation_id == conversation.id)
.order_by(Message.created_at.desc())
.limit(fetch_limit)
.all()
)
).all()
has_more = False
if len(history_messages) > limit:
@@ -129,7 +126,7 @@ class MessageService:
if not user:
return InfiniteScrollPagination(data=[], limit=limit, has_more=False)
base_query = db.session.query(Message)
stmt = select(Message)
fetch_limit = limit + 1
@@ -138,28 +135,27 @@ class MessageService:
app_model=app_model, user=user, conversation_id=conversation_id
)
base_query = base_query.where(Message.conversation_id == conversation.id)
stmt = stmt.where(Message.conversation_id == conversation.id)
# Check if include_ids is not None and not empty to avoid WHERE false condition
if include_ids is not None:
if len(include_ids) == 0:
return InfiniteScrollPagination(data=[], limit=limit, has_more=False)
base_query = base_query.where(Message.id.in_(include_ids))
stmt = stmt.where(Message.id.in_(include_ids))
if last_id:
last_message = base_query.where(Message.id == last_id).first()
last_message = db.session.scalar(stmt.where(Message.id == last_id).limit(1))
if not last_message:
raise LastMessageNotExistsError()
history_messages = (
base_query.where(Message.created_at < last_message.created_at, Message.id != last_message.id)
history_messages = db.session.scalars(
stmt.where(Message.created_at < last_message.created_at, Message.id != last_message.id)
.order_by(Message.created_at.desc())
.limit(fetch_limit)
.all()
)
).all()
else:
history_messages = base_query.order_by(Message.created_at.desc()).limit(fetch_limit).all()
history_messages = db.session.scalars(stmt.order_by(Message.created_at.desc()).limit(fetch_limit)).all()
has_more = False
if len(history_messages) > limit:
@@ -214,21 +210,20 @@ class MessageService:
def get_all_messages_feedbacks(cls, app_model: App, page: int, limit: int):
"""Get all feedbacks of an app"""
offset = (page - 1) * limit
feedbacks = (
db.session.query(MessageFeedback)
feedbacks = db.session.scalars(
select(MessageFeedback)
.where(MessageFeedback.app_id == app_model.id)
.order_by(MessageFeedback.created_at.desc(), MessageFeedback.id.desc())
.limit(limit)
.offset(offset)
.all()
)
).all()
return [record.to_dict() for record in feedbacks]
@classmethod
def get_message(cls, app_model: App, user: Union[Account, EndUser] | None, message_id: str):
message = (
db.session.query(Message)
message = db.session.scalar(
select(Message)
.where(
Message.id == message_id,
Message.app_id == app_model.id,
@@ -236,7 +231,7 @@ class MessageService:
Message.from_end_user_id == (user.id if isinstance(user, EndUser) else None),
Message.from_account_id == (user.id if isinstance(user, Account) else None),
)
.first()
.limit(1)
)
if not message:
@@ -282,10 +277,10 @@ class MessageService:
)
else:
if not conversation.override_model_configs:
app_model_config = (
db.session.query(AppModelConfig)
app_model_config = db.session.scalar(
select(AppModelConfig)
.where(AppModelConfig.id == conversation.app_model_config_id, AppModelConfig.app_id == app_model.id)
.first()
.limit(1)
)
else:
conversation_override_model_configs = _app_model_config_adapter.validate_json(

View File

@@ -1,5 +1,7 @@
from typing import Any
from sqlalchemy import select
from core.ops.entities.config_entity import BaseTracingConfig
from core.ops.ops_trace_manager import OpsTraceManager, provider_config_map
from extensions.ext_database import db
@@ -15,17 +17,17 @@ class OpsService:
:param tracing_provider: tracing provider
:return:
"""
trace_config_data: TraceAppConfig | None = (
db.session.query(TraceAppConfig)
trace_config_data: TraceAppConfig | None = db.session.scalar(
select(TraceAppConfig)
.where(TraceAppConfig.app_id == app_id, TraceAppConfig.tracing_provider == tracing_provider)
.first()
.limit(1)
)
if not trace_config_data:
return None
# decrypt_token and obfuscated_token
app = db.session.query(App).where(App.id == app_id).first()
app = db.session.get(App, app_id)
if not app:
return None
tenant_id = app.tenant_id
@@ -182,17 +184,17 @@ class OpsService:
project_url = None
# check if trace config already exists
trace_config_data: TraceAppConfig | None = (
db.session.query(TraceAppConfig)
trace_config_data: TraceAppConfig | None = db.session.scalar(
select(TraceAppConfig)
.where(TraceAppConfig.app_id == app_id, TraceAppConfig.tracing_provider == tracing_provider)
.first()
.limit(1)
)
if trace_config_data:
return None
# get tenant id
app = db.session.query(App).where(App.id == app_id).first()
app = db.session.get(App, app_id)
if not app:
return None
tenant_id = app.tenant_id
@@ -224,17 +226,17 @@ class OpsService:
raise ValueError(f"Invalid tracing provider: {tracing_provider}")
# check if trace config already exists
current_trace_config = (
db.session.query(TraceAppConfig)
current_trace_config = db.session.scalar(
select(TraceAppConfig)
.where(TraceAppConfig.app_id == app_id, TraceAppConfig.tracing_provider == tracing_provider)
.first()
.limit(1)
)
if not current_trace_config:
return None
# get tenant id
app = db.session.query(App).where(App.id == app_id).first()
app = db.session.get(App, app_id)
if not app:
return None
tenant_id = app.tenant_id
@@ -261,10 +263,10 @@ class OpsService:
:param tracing_provider: tracing provider
:return:
"""
trace_config = (
db.session.query(TraceAppConfig)
trace_config = db.session.scalar(
select(TraceAppConfig)
.where(TraceAppConfig.app_id == app_id, TraceAppConfig.tracing_provider == tracing_provider)
.first()
.limit(1)
)
if not trace_config:

View File

@@ -151,12 +151,7 @@ class TestMessageServicePaginationByFirstId:
for i in range(5)
]
mock_query = MagicMock()
mock_db.session.query.return_value = mock_query
mock_query.where.return_value = mock_query
mock_query.order_by.return_value = mock_query
mock_query.limit.return_value = mock_query
mock_query.all.return_value = messages
mock_db.session.scalars.return_value.all.return_value = messages
# Act
result = MessageService.pagination_by_first_id(
@@ -196,12 +191,7 @@ class TestMessageServicePaginationByFirstId:
for i in range(5)
]
mock_query = MagicMock()
mock_db.session.query.return_value = mock_query
mock_query.where.return_value = mock_query
mock_query.order_by.return_value = mock_query
mock_query.limit.return_value = mock_query
mock_query.all.return_value = messages
mock_db.session.scalars.return_value.all.return_value = messages
# Act
result = MessageService.pagination_by_first_id(
@@ -246,31 +236,8 @@ class TestMessageServicePaginationByFirstId:
for i in range(5)
]
# Setup query mocks
mock_query_first = MagicMock()
mock_query_history = MagicMock()
query_calls = []
def query_side_effect(*args):
if args[0] == Message:
query_calls.append(args)
if len(query_calls) == 1:
return mock_query_first
else:
return mock_query_history
mock_db.session.query.side_effect = [mock_query_first, mock_query_history]
# Setup first message query
mock_query_first.where.return_value = mock_query_first
mock_query_first.first.return_value = first_message
# Setup history messages query
mock_query_history.where.return_value = mock_query_history
mock_query_history.order_by.return_value = mock_query_history
mock_query_history.limit.return_value = mock_query_history
mock_query_history.all.return_value = history_messages
mock_db.session.scalar.return_value = first_message
mock_db.session.scalars.return_value.all.return_value = history_messages
# Act
result = MessageService.pagination_by_first_id(
@@ -285,8 +252,6 @@ class TestMessageServicePaginationByFirstId:
# Assert
assert len(result.data) == 5
assert result.has_more is False
mock_query_first.where.assert_called_once()
mock_query_history.where.assert_called_once()
# Test 06: First message not found
@patch("services.message_service.db")
@@ -300,10 +265,7 @@ class TestMessageServicePaginationByFirstId:
mock_conversation_service.get_conversation.return_value = conversation
mock_query = MagicMock()
mock_db.session.query.return_value = mock_query
mock_query.where.return_value = mock_query
mock_query.first.return_value = None # Message not found
mock_db.session.scalar.return_value = None # Message not found
# Act & Assert
with pytest.raises(FirstMessageNotExistsError):
@@ -336,12 +298,7 @@ class TestMessageServicePaginationByFirstId:
for i in range(11)
]
mock_query = MagicMock()
mock_db.session.query.return_value = mock_query
mock_query.where.return_value = mock_query
mock_query.order_by.return_value = mock_query
mock_query.limit.return_value = mock_query
mock_query.all.return_value = messages
mock_db.session.scalars.return_value.all.return_value = messages
# Act
result = MessageService.pagination_by_first_id(
@@ -369,12 +326,7 @@ class TestMessageServicePaginationByFirstId:
mock_conversation_service.get_conversation.return_value = conversation
mock_query = MagicMock()
mock_db.session.query.return_value = mock_query
mock_query.where.return_value = mock_query
mock_query.order_by.return_value = mock_query
mock_query.limit.return_value = mock_query
mock_query.all.return_value = []
mock_db.session.scalars.return_value.all.return_value = []
# Act
result = MessageService.pagination_by_first_id(
@@ -443,12 +395,7 @@ class TestMessageServicePaginationByLastId:
for i in range(5)
]
mock_query = MagicMock()
mock_db.session.query.return_value = mock_query
mock_query.where.return_value = mock_query
mock_query.order_by.return_value = mock_query
mock_query.limit.return_value = mock_query
mock_query.all.return_value = messages
mock_db.session.scalars.return_value.all.return_value = messages
# Act
result = MessageService.pagination_by_last_id(
@@ -485,22 +432,8 @@ class TestMessageServicePaginationByLastId:
for i in range(6, 10)
]
# Setup base query mock that returns itself for chaining
mock_base_query = MagicMock()
mock_db.session.query.return_value = mock_base_query
# First where() call for last_id lookup
mock_query_last = MagicMock()
mock_query_last.first.return_value = last_message
# Second where() call for history messages
mock_query_history = MagicMock()
mock_query_history.order_by.return_value = mock_query_history
mock_query_history.limit.return_value = mock_query_history
mock_query_history.all.return_value = new_messages
# Setup where() to return different mocks on consecutive calls
mock_base_query.where.side_effect = [mock_query_last, mock_query_history]
mock_db.session.scalar.return_value = last_message
mock_db.session.scalars.return_value.all.return_value = new_messages
# Act
result = MessageService.pagination_by_last_id(
@@ -522,10 +455,7 @@ class TestMessageServicePaginationByLastId:
app = factory.create_app_mock()
user = factory.create_end_user_mock()
mock_query = MagicMock()
mock_db.session.query.return_value = mock_query
mock_query.where.return_value = mock_query
mock_query.first.return_value = None # Message not found
mock_db.session.scalar.return_value = None # Message not found
# Act & Assert
with pytest.raises(LastMessageNotExistsError):
@@ -557,12 +487,7 @@ class TestMessageServicePaginationByLastId:
for i in range(5)
]
mock_query = MagicMock()
mock_db.session.query.return_value = mock_query
mock_query.where.return_value = mock_query
mock_query.order_by.return_value = mock_query
mock_query.limit.return_value = mock_query
mock_query.all.return_value = messages
mock_db.session.scalars.return_value.all.return_value = messages
# Act
result = MessageService.pagination_by_last_id(
@@ -576,8 +501,6 @@ class TestMessageServicePaginationByLastId:
# Assert
assert len(result.data) == 5
assert result.has_more is False
# Verify conversation_id was used in query
mock_query.where.assert_called()
mock_conversation_service.get_conversation.assert_called_once()
# Test 14: Pagination with include_ids filter
@@ -594,12 +517,7 @@ class TestMessageServicePaginationByLastId:
factory.create_message_mock(message_id="msg-003"),
]
mock_query = MagicMock()
mock_db.session.query.return_value = mock_query
mock_query.where.return_value = mock_query
mock_query.order_by.return_value = mock_query
mock_query.limit.return_value = mock_query
mock_query.all.return_value = messages
mock_db.session.scalars.return_value.all.return_value = messages
# Act
result = MessageService.pagination_by_last_id(
@@ -632,12 +550,7 @@ class TestMessageServicePaginationByLastId:
for i in range(11)
]
mock_query = MagicMock()
mock_db.session.query.return_value = mock_query
mock_query.where.return_value = mock_query
mock_query.order_by.return_value = mock_query
mock_query.limit.return_value = mock_query
mock_query.all.return_value = messages
mock_db.session.scalars.return_value.all.return_value = messages
# Act
result = MessageService.pagination_by_last_id(
@@ -743,17 +656,13 @@ class TestMessageServiceGetMessage:
user = factory.create_end_user_mock(user_id="end-user-123")
message = factory.create_message_mock()
mock_query = MagicMock()
mock_db.session.query.return_value = mock_query
mock_query.where.return_value = mock_query
mock_query.first.return_value = message
mock_db.session.scalar.return_value = message
# Act
result = MessageService.get_message(app_model=app, user=user, message_id="msg-123")
# Assert
assert result == message
mock_query.where.assert_called_once()
# Test 21: get_message success for Account (Admin)
@patch("services.message_service.db")
@@ -767,10 +676,7 @@ class TestMessageServiceGetMessage:
user.id = "account-123"
message = factory.create_message_mock()
mock_query = MagicMock()
mock_db.session.query.return_value = mock_query
mock_query.where.return_value = mock_query
mock_query.first.return_value = message
mock_db.session.scalar.return_value = message
# Act
result = MessageService.get_message(app_model=app, user=user, message_id="msg-123")
@@ -786,10 +692,7 @@ class TestMessageServiceGetMessage:
app = factory.create_app_mock()
user = factory.create_end_user_mock()
mock_query = MagicMock()
mock_db.session.query.return_value = mock_query
mock_query.where.return_value = mock_query
mock_query.first.return_value = None
mock_db.session.scalar.return_value = None
# Act & Assert
with pytest.raises(MessageNotExistsError):
@@ -899,21 +802,13 @@ class TestMessageServiceFeedback:
feedback = MagicMock()
feedback.to_dict.return_value = {"id": "fb-1"}
mock_query = MagicMock()
mock_db.session.query.return_value = mock_query
mock_query.where.return_value = mock_query
mock_query.order_by.return_value = mock_query
mock_query.limit.return_value = mock_query
mock_query.offset.return_value = mock_query
mock_query.all.return_value = [feedback]
mock_db.session.scalars.return_value.all.return_value = [feedback]
# Act
result = MessageService.get_all_messages_feedbacks(app_model=app, page=1, limit=10)
# Assert
assert result == [{"id": "fb-1"}]
mock_query.limit.assert_called_with(10)
mock_query.offset.assert_called_with(0)
class TestMessageServiceSuggestedQuestions:
@@ -1015,10 +910,7 @@ class TestMessageServiceSuggestedQuestions:
app_model_config.suggested_questions_after_answer_dict = {"enabled": True}
app_model_config.model_dict = {"provider": "openai", "name": "gpt-4"}
mock_query = MagicMock()
mock_db.session.query.return_value = mock_query
mock_query.where.return_value = mock_query
mock_query.first.return_value = app_model_config
mock_db.session.scalar.return_value = app_model_config
mock_llm_gen.generate_suggested_questions_after_answer.return_value = ["Q1?"]
@@ -1029,7 +921,6 @@ class TestMessageServiceSuggestedQuestions:
# Assert
assert result == ["Q1?"]
mock_query.first.assert_called_once()
mock_llm_gen.generate_suggested_questions_after_answer.assert_called_once()
# Test 30: get_suggested_questions_after_answer - Disabled Error

View File

@@ -12,28 +12,27 @@ class TestOpsService:
@patch("services.ops_service.OpsTraceManager")
def test_get_tracing_app_config_no_config(self, mock_ops_trace_manager, mock_db):
# Arrange
mock_db.session.query.return_value.where.return_value.first.return_value = None
mock_db.session.scalar.return_value = None
# Act
result = OpsService.get_tracing_app_config("app_id", "arize")
# Assert
assert result is None
mock_db.session.query.assert_called_with(TraceAppConfig)
@patch("services.ops_service.db")
@patch("services.ops_service.OpsTraceManager")
def test_get_tracing_app_config_no_app(self, mock_ops_trace_manager, mock_db):
# Arrange
trace_config = MagicMock(spec=TraceAppConfig)
mock_db.session.query.return_value.where.return_value.first.side_effect = [trace_config, None]
mock_db.session.scalar.return_value = trace_config
mock_db.session.get.return_value = None
# Act
result = OpsService.get_tracing_app_config("app_id", "arize")
# Assert
assert result is None
assert mock_db.session.query.call_count == 2
@patch("services.ops_service.db")
@patch("services.ops_service.OpsTraceManager")
@@ -43,7 +42,8 @@ class TestOpsService:
trace_config.tracing_config = None
app = MagicMock(spec=App)
app.tenant_id = "tenant_id"
mock_db.session.query.return_value.where.return_value.first.side_effect = [trace_config, app]
mock_db.session.scalar.return_value = trace_config
mock_db.session.get.return_value = app
# Act & Assert
with pytest.raises(ValueError, match="Tracing config cannot be None."):
@@ -72,7 +72,8 @@ class TestOpsService:
trace_config.to_dict.return_value = {"tracing_config": {"project_url": default_url}}
app = MagicMock(spec=App)
app.tenant_id = "tenant_id"
mock_db.session.query.return_value.where.return_value.first.side_effect = [trace_config, app]
mock_db.session.scalar.return_value = trace_config
mock_db.session.get.return_value = app
mock_ops_trace_manager.decrypt_tracing_config.return_value = {}
mock_ops_trace_manager.obfuscated_decrypt_token.return_value = {}
@@ -97,7 +98,8 @@ class TestOpsService:
trace_config.to_dict.return_value = {"tracing_config": {"project_url": "success_url"}}
app = MagicMock(spec=App)
app.tenant_id = "tenant_id"
mock_db.session.query.return_value.where.return_value.first.side_effect = [trace_config, app]
mock_db.session.scalar.return_value = trace_config
mock_db.session.get.return_value = app
mock_ops_trace_manager.decrypt_tracing_config.return_value = {}
mock_ops_trace_manager.obfuscated_decrypt_token.return_value = {}
@@ -118,7 +120,8 @@ class TestOpsService:
trace_config.to_dict.return_value = {"tracing_config": {"project_url": "https://api.langfuse.com/project/key"}}
app = MagicMock(spec=App)
app.tenant_id = "tenant_id"
mock_db.session.query.return_value.where.return_value.first.side_effect = [trace_config, app]
mock_db.session.scalar.return_value = trace_config
mock_db.session.get.return_value = app
mock_ops_trace_manager.decrypt_tracing_config.return_value = {"host": "https://api.langfuse.com"}
mock_ops_trace_manager.obfuscated_decrypt_token.return_value = {"host": "https://api.langfuse.com"}
@@ -139,7 +142,8 @@ class TestOpsService:
trace_config.to_dict.return_value = {"tracing_config": {"project_url": "https://api.langfuse.com/"}}
app = MagicMock(spec=App)
app.tenant_id = "tenant_id"
mock_db.session.query.return_value.where.return_value.first.side_effect = [trace_config, app]
mock_db.session.scalar.return_value = trace_config
mock_db.session.get.return_value = app
mock_ops_trace_manager.decrypt_tracing_config.return_value = {"host": "https://api.langfuse.com"}
mock_ops_trace_manager.obfuscated_decrypt_token.return_value = {"host": "https://api.langfuse.com"}
@@ -189,7 +193,7 @@ class TestOpsService:
mock_ops_trace_manager.check_trace_config_is_effective.return_value = True
mock_ops_trace_manager.get_trace_config_project_url.side_effect = Exception("error")
mock_ops_trace_manager.get_trace_config_project_key.side_effect = Exception("error")
mock_db.session.query.return_value.where.return_value.first.return_value = MagicMock(spec=TraceAppConfig)
mock_db.session.scalar.return_value = MagicMock(spec=TraceAppConfig)
# Act
result = OpsService.create_tracing_app_config("app_id", provider, config)
@@ -206,7 +210,8 @@ class TestOpsService:
mock_ops_trace_manager.get_trace_config_project_key.return_value = "key"
app = MagicMock(spec=App)
app.tenant_id = "tenant_id"
mock_db.session.query.return_value.where.return_value.first.side_effect = [None, app]
mock_db.session.scalar.return_value = None
mock_db.session.get.return_value = app
mock_ops_trace_manager.encrypt_tracing_config.return_value = {}
# Act
@@ -223,7 +228,7 @@ class TestOpsService:
# Arrange
provider = TracingProviderEnum.ARIZE
mock_ops_trace_manager.check_trace_config_is_effective.return_value = True
mock_db.session.query.return_value.where.return_value.first.return_value = MagicMock(spec=TraceAppConfig)
mock_db.session.scalar.return_value = MagicMock(spec=TraceAppConfig)
# Act
result = OpsService.create_tracing_app_config("app_id", provider, {})
@@ -237,7 +242,8 @@ class TestOpsService:
# Arrange
provider = TracingProviderEnum.ARIZE
mock_ops_trace_manager.check_trace_config_is_effective.return_value = True
mock_db.session.query.return_value.where.return_value.first.side_effect = [None, None]
mock_db.session.scalar.return_value = None
mock_db.session.get.return_value = None
# Act
result = OpsService.create_tracing_app_config("app_id", provider, {})
@@ -253,7 +259,8 @@ class TestOpsService:
mock_ops_trace_manager.check_trace_config_is_effective.return_value = True
app = MagicMock(spec=App)
app.tenant_id = "tenant_id"
mock_db.session.query.return_value.where.return_value.first.side_effect = [None, app]
mock_db.session.scalar.return_value = None
mock_db.session.get.return_value = app
mock_ops_trace_manager.encrypt_tracing_config.return_value = {}
# Act
@@ -274,7 +281,8 @@ class TestOpsService:
mock_ops_trace_manager.get_trace_config_project_url.return_value = "http://project_url"
app = MagicMock(spec=App)
app.tenant_id = "tenant_id"
mock_db.session.query.return_value.where.return_value.first.side_effect = [None, app]
mock_db.session.scalar.return_value = None
mock_db.session.get.return_value = app
mock_ops_trace_manager.encrypt_tracing_config.return_value = {"encrypted": "config"}
# Act
@@ -297,7 +305,7 @@ class TestOpsService:
def test_update_tracing_app_config_no_config(self, mock_ops_trace_manager, mock_db):
# Arrange
provider = TracingProviderEnum.ARIZE
mock_db.session.query.return_value.where.return_value.first.return_value = None
mock_db.session.scalar.return_value = None
# Act
result = OpsService.update_tracing_app_config("app_id", provider, {})
@@ -311,7 +319,8 @@ class TestOpsService:
# Arrange
provider = TracingProviderEnum.ARIZE
current_config = MagicMock(spec=TraceAppConfig)
mock_db.session.query.return_value.where.return_value.first.side_effect = [current_config, None]
mock_db.session.scalar.return_value = current_config
mock_db.session.get.return_value = None
# Act
result = OpsService.update_tracing_app_config("app_id", provider, {})
@@ -327,7 +336,8 @@ class TestOpsService:
current_config = MagicMock(spec=TraceAppConfig)
app = MagicMock(spec=App)
app.tenant_id = "tenant_id"
mock_db.session.query.return_value.where.return_value.first.side_effect = [current_config, app]
mock_db.session.scalar.return_value = current_config
mock_db.session.get.return_value = app
mock_ops_trace_manager.decrypt_tracing_config.return_value = {}
mock_ops_trace_manager.check_trace_config_is_effective.return_value = False
@@ -344,7 +354,8 @@ class TestOpsService:
current_config.to_dict.return_value = {"some": "data"}
app = MagicMock(spec=App)
app.tenant_id = "tenant_id"
mock_db.session.query.return_value.where.return_value.first.side_effect = [current_config, app]
mock_db.session.scalar.return_value = current_config
mock_db.session.get.return_value = app
mock_ops_trace_manager.decrypt_tracing_config.return_value = {}
mock_ops_trace_manager.check_trace_config_is_effective.return_value = True
@@ -358,7 +369,7 @@ class TestOpsService:
@patch("services.ops_service.db")
def test_delete_tracing_app_config_no_config(self, mock_db):
# Arrange
mock_db.session.query.return_value.where.return_value.first.return_value = None
mock_db.session.scalar.return_value = None
# Act
result = OpsService.delete_tracing_app_config("app_id", "arize")
@@ -370,7 +381,7 @@ class TestOpsService:
def test_delete_tracing_app_config_success(self, mock_db):
# Arrange
trace_config = MagicMock(spec=TraceAppConfig)
mock_db.session.query.return_value.where.return_value.first.return_value = trace_config
mock_db.session.scalar.return_value = trace_config
# Act
result = OpsService.delete_tracing_app_config("app_id", "arize")

584
pnpm-lock.yaml generated
View File

@@ -57,6 +57,12 @@ catalogs:
'@iconify-json/ri':
specifier: 1.2.10
version: 1.2.10
'@iconify/tools':
specifier: 4.2.0
version: 4.2.0
'@iconify/utils':
specifier: 3.1.0
version: 3.1.0
'@lexical/link':
specifier: 0.42.0
version: 0.42.0
@@ -228,6 +234,9 @@ catalogs:
'@typescript/native-preview':
specifier: 7.0.0-dev.20260329.1
version: 7.0.0-dev.20260329.1
'@unocss/postcss':
specifier: 66.6.7
version: 66.6.7
'@vitejs/plugin-react':
specifier: 6.0.1
version: 6.0.1
@@ -525,6 +534,9 @@ catalogs:
unist-util-visit:
specifier: 5.1.0
version: 5.1.0
unocss:
specifier: 66.6.7
version: 66.6.7
use-context-selector:
specifier: 2.0.0
version: 2.0.0
@@ -1000,6 +1012,12 @@ importers:
'@iconify-json/ri':
specifier: 'catalog:'
version: 1.2.10
'@iconify/tools':
specifier: 'catalog:'
version: 4.2.0
'@iconify/utils':
specifier: 'catalog:'
version: 3.1.0
'@mdx-js/loader':
specifier: 'catalog:'
version: 3.1.1(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3))
@@ -1108,6 +1126,9 @@ importers:
'@typescript/native-preview':
specifier: 'catalog:'
version: 7.0.0-dev.20260329.1
'@unocss/postcss':
specifier: 'catalog:'
version: 66.6.7(postcss@8.5.8)
'@vitejs/plugin-react':
specifier: 'catalog:'
version: 6.0.1(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))
@@ -1195,6 +1216,9 @@ importers:
uglify-js:
specifier: 'catalog:'
version: 3.19.3
unocss:
specifier: 'catalog:'
version: 66.6.7(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@unocss/postcss@66.6.7(postcss@8.5.8))(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))
vinext:
specifier: 'catalog:'
version: 0.0.38(f5786d681f520e26604259e094ebaa46)
@@ -2439,48 +2463,97 @@ packages:
resolution: {integrity: sha512-XRO0zi2NIUKq2lUk3T1ecFSld1fMWRKE6naRFGkgkdeosx7IslyUKNv5Dcb5PJTja9tHJoFu0v/7yEpAkrkrTg==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
'@oxc-parser/binding-android-arm-eabi@0.115.0':
resolution: {integrity: sha512-VoB2rhgoqgYf64d6Qs5emONQW8ASiTc0xp+aUE4JUhxjX+0pE3gblTYDO0upcN5vt9UlBNmUhAwfSifkfre7nw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [android]
'@oxc-parser/binding-android-arm-eabi@0.121.0':
resolution: {integrity: sha512-n07FQcySwOlzap424/PLMtOkbS7xOu8nsJduKL8P3COGHKgKoDYXwoAHCbChfgFpHnviehrLWIPX0lKGtbEk/A==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [android]
'@oxc-parser/binding-android-arm64@0.115.0':
resolution: {integrity: sha512-lWRX75u+gqfB4TF3pWCHuvhaeneAmRl2b2qNBcl4S6yJ0HtnT4VXOMEZrq747i4Zby1ZTxj6mtOe678Bg8gRLw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
'@oxc-parser/binding-android-arm64@0.121.0':
resolution: {integrity: sha512-/Dd1xIXboYAicw+twT2utxPD7bL8qh7d3ej0qvaYIMj3/EgIrGR+tSnjCUkiCT6g6uTC0neSS4JY8LxhdSU/sA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
'@oxc-parser/binding-darwin-arm64@0.115.0':
resolution: {integrity: sha512-ii/oOZjfGY1aszXTy29Z5DRyCEnBOrAXDVCvfdfXFQsOZlbbOa7NMHD7D+06YFe5qdxfmbWAYv4yn6QJi/0d2g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
'@oxc-parser/binding-darwin-arm64@0.121.0':
resolution: {integrity: sha512-A0jNEvv7QMtCO1yk205t3DWU9sWUjQ2KNF0hSVO5W9R9r/R1BIvzG01UQAfmtC0dQm7sCrs5puixurKSfr2bRQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
'@oxc-parser/binding-darwin-x64@0.115.0':
resolution: {integrity: sha512-R/sW/p8l77wglbjpMcF+h/3rWbp9zk1mRP3U14mxTYIC2k3m+aLBpXXgk2zksqf9qKk5mcc4GIYsuCn9l8TgDg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
'@oxc-parser/binding-darwin-x64@0.121.0':
resolution: {integrity: sha512-SsHzipdxTKUs3I9EOAPmnIimEeJOemqRlRDOp9LIj+96wtxZejF51gNibmoGq8KoqbT1ssAI5po/E3J+vEtXGA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
'@oxc-parser/binding-freebsd-x64@0.115.0':
resolution: {integrity: sha512-CSJ5ldNm9wIGGkhaIJeGmxRMZbgxThRN+X1ufYQQUNi5jZDV/U3C2QDMywpP93fczNBj961hXtcUPO/oVGq4Pw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
'@oxc-parser/binding-freebsd-x64@0.121.0':
resolution: {integrity: sha512-v1APOTkCp+RWOIDAHRoaeW/UoaHF15a60E8eUL6kUQXh+i4K7PBwq2Wi7jm8p0ymID5/m/oC1w3W31Z/+r7HQw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
'@oxc-parser/binding-linux-arm-gnueabihf@0.115.0':
resolution: {integrity: sha512-uWFwssE5dHfQ8lH+ktrsD9JA49+Qa0gtxZHUs62z1e91NgGz6O7jefHGI6aygNyKNS45pnnBSDSP/zV977MsOQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxc-parser/binding-linux-arm-gnueabihf@0.121.0':
resolution: {integrity: sha512-PmqPQuqHZyFVWA4ycr0eu4VnTMmq9laOHZd+8R359w6kzuNZPvmmunmNJ8ybkm769A0nCoVp3TJ6dUz7B3FYIQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxc-parser/binding-linux-arm-musleabihf@0.115.0':
resolution: {integrity: sha512-fZbqt8y/sKQ+v6bBCuv/mYYFoC0+fZI3mGDDEemmDOhT78+aUs2+4ZMdbd2btlXmnLaScl37r8IRbhnok5Ka9w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxc-parser/binding-linux-arm-musleabihf@0.121.0':
resolution: {integrity: sha512-vF24htj+MOH+Q7y9A8NuC6pUZu8t/C2Fr/kDOi2OcNf28oogr2xadBPXAbml802E8wRAVfbta6YLDQTearz+jw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxc-parser/binding-linux-arm64-gnu@0.115.0':
resolution: {integrity: sha512-1ej/MjuTY9tJEunU/hUPIFmgH5PqgMQoRjNOvOkibtJ3Zqlw/+Lc+HGHDNET8sjbgIkWzdhX+p4J96A5CPdbag==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-arm64-gnu@0.121.0':
resolution: {integrity: sha512-wjH8cIG2Lu/3d64iZpbYr73hREMgKAfu7fqpXjgM2S16y2zhTfDIp8EQjxO8vlDtKP5Rc7waZW72lh8nZtWrpA==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -2488,6 +2561,13 @@ packages:
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-arm64-musl@0.115.0':
resolution: {integrity: sha512-HjsZbJPH9mMd4swJRywVMsDZsJX0hyKb1iNHo5ijRl5yhtbO3lj7ImSrrL1oZ1VEg0te4iKmDGGz/6YPLd1G8w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@oxc-parser/binding-linux-arm64-musl@0.121.0':
resolution: {integrity: sha512-qT663J/W8yQFw3dtscbEi9LKJevr20V7uWs2MPGTnvNZ3rm8anhhE16gXGpxDOHeg9raySaSHKhd4IGa3YZvuw==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -2495,6 +2575,13 @@ packages:
os: [linux]
libc: [musl]
'@oxc-parser/binding-linux-ppc64-gnu@0.115.0':
resolution: {integrity: sha512-zhhePoBrd7kQx3oClX/W6NldsuCbuMqaN9rRsY+6/WoorAb4j490PG/FjqgAXscWp2uSW2WV9L+ksn0wHrvsrg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-ppc64-gnu@0.121.0':
resolution: {integrity: sha512-mYNe4NhVvDBbPkAP8JaVS8lC1dsoJZWH5WCjpw5E+sjhk1R08wt3NnXYUzum7tIiWPfgQxbCMcoxgeemFASbRw==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -2502,6 +2589,13 @@ packages:
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-riscv64-gnu@0.115.0':
resolution: {integrity: sha512-t/IRojvUE9XrKu+/H1b8YINug+7Q6FLls5rsm2lxB5mnS8GN/eYAYrPgHkcg9/1SueRDSzGpDYu3lGWTObk1zw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-riscv64-gnu@0.121.0':
resolution: {integrity: sha512-+QiFoGxhAbaI/amqX567784cDyyuZIpinBrJNxUzb+/L2aBRX67mN6Jv40pqduHf15yYByI+K5gUEygCuv0z9w==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -2509,6 +2603,13 @@ packages:
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-riscv64-musl@0.115.0':
resolution: {integrity: sha512-79jBHSSh/YpQRAmvYoaCfpyToRbJ/HBrdB7hxK2ku2JMehjopTVo+xMJss/RV7/ZYqeezgjvKDQzapJbgcjVZA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@oxc-parser/binding-linux-riscv64-musl@0.121.0':
resolution: {integrity: sha512-9ykEgyTa5JD/Uhv2sttbKnCfl2PieUfOjyxJC/oDL2UO0qtXOtjPLl7H8Kaj5G7p3hIvFgu3YWvAxvE0sqY+hQ==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -2516,6 +2617,13 @@ packages:
os: [linux]
libc: [musl]
'@oxc-parser/binding-linux-s390x-gnu@0.115.0':
resolution: {integrity: sha512-nA1TpxkhNTIOMMyiSSsa7XIVJVoOU/SsVrHIz3gHvWweB5PHCQfO7w+Lb2EP0lBWokv7HtA/KbF7aLDoXzmuMw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-s390x-gnu@0.121.0':
resolution: {integrity: sha512-DB1EW5VHZdc1lIRjOI3bW/wV6R6y0xlfvdVrqj6kKi7Ayu2U3UqUBdq9KviVkcUGd5Oq+dROqvUEEFRXGAM7EQ==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -2523,6 +2631,13 @@ packages:
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-x64-gnu@0.115.0':
resolution: {integrity: sha512-9iVX789DoC3SaOOG+X6NcF/tVChgLp2vcHffzOC2/Z1JTPlz6bMG2ogvcW6/9s0BG2qvhNQImd+gbWYeQbOwVw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-x64-gnu@0.121.0':
resolution: {integrity: sha512-s4lfobX9p4kPTclvMiH3gcQUd88VlnkMTF6n2MTMDAyX5FPNRhhRSFZK05Ykhf8Zy5NibV4PbGR6DnK7FGNN6A==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -2530,6 +2645,13 @@ packages:
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-x64-musl@0.115.0':
resolution: {integrity: sha512-RmQmk+mjCB0nMNfEYhaCxwofLo1Z95ebHw1AGvRiWGCd4zhCNOyskgCbMogIcQzSB3SuEKWgkssyaiQYVAA4hQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@oxc-parser/binding-linux-x64-musl@0.121.0':
resolution: {integrity: sha512-P9KlyTpuBuMi3NRGpJO8MicuGZfOoqZVRP1WjOecwx8yk4L/+mrCRNc5egSi0byhuReblBF2oVoDSMgV9Bj4Hw==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -2537,29 +2659,58 @@ packages:
os: [linux]
libc: [musl]
'@oxc-parser/binding-openharmony-arm64@0.115.0':
resolution: {integrity: sha512-viigraWWQhhDvX5aGq+wrQq58k00Xq3MHz/0R4AFMxGlZ8ogNonpEfNc73Q5Ly87Z6sU9BvxEdG0dnYTfVnmew==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
'@oxc-parser/binding-openharmony-arm64@0.121.0':
resolution: {integrity: sha512-R+4jrWOfF2OAPPhj3Eb3U5CaKNAH9/btMveMULIrcNW/hjfysFQlF8wE0GaVBr81dWz8JLgQlsxwctoL78JwXw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
'@oxc-parser/binding-wasm32-wasi@0.115.0':
resolution: {integrity: sha512-IzGCrMwXhpb4kTXy/8lnqqqwjI7eOvy+r9AhVw+hsr8t1ecBBEHprcNy0aKatFHN6hsX7UMHHQmBAQjVvL/p1A==}
engines: {node: '>=14.0.0'}
cpu: [wasm32]
'@oxc-parser/binding-wasm32-wasi@0.121.0':
resolution: {integrity: sha512-5TFISkPTymKvsmIlKasPVTPuWxzCcrT8pM+p77+mtQbIZDd1UC8zww4CJcRI46kolmgrEX6QpKO8AvWMVZ+ifw==}
engines: {node: '>=14.0.0'}
cpu: [wasm32]
'@oxc-parser/binding-win32-arm64-msvc@0.115.0':
resolution: {integrity: sha512-/ym+Absk/TLFvbhh3se9XYuI1D7BrUVHw4RaG/2dmWKgBenrZHaJsgnRb7NJtaOyjEOLIPtULx1wDdVL0SX2eg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
'@oxc-parser/binding-win32-arm64-msvc@0.121.0':
resolution: {integrity: sha512-V0pxh4mql4XTt3aiEtRNUeBAUFOw5jzZNxPABLaOKAWrVzSr9+XUaB095lY7jqMf5t8vkfh8NManGB28zanYKw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
'@oxc-parser/binding-win32-ia32-msvc@0.115.0':
resolution: {integrity: sha512-AQSZjIR+b+Te7uaO/hGTMjT8/oxlYrvKrOTi4KTHF/O6osjHEatUQ3y6ZW2+8+lJxy20zIcGz6iQFmFq/qDKkg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ia32]
os: [win32]
'@oxc-parser/binding-win32-ia32-msvc@0.121.0':
resolution: {integrity: sha512-4Ob1qvYMPnlF2N9rdmKdkQFdrq16QVcQwBsO8yiPZXof0fHKFF+LmQV501XFbi7lHyrKm8rlJRfQ/M8bZZPVLw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ia32]
os: [win32]
'@oxc-parser/binding-win32-x64-msvc@0.115.0':
resolution: {integrity: sha512-oxUl82N+fIO9jIaXPph8SPPHQXrA08BHokBBJW8ct9F/x6o6bZE6eUAhUtWajbtvFhL8UYcCWRMba+kww6MBlA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
'@oxc-parser/binding-win32-x64-msvc@0.121.0':
resolution: {integrity: sha512-BOp1KCzdboB1tPqoCPXgntgFs0jjeSyOXHzgxVFR7B/qfr3F8r4YDacHkTOUNXtDgM8YwKnkf3rE5gwALYX7NA==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -2570,6 +2721,9 @@ packages:
resolution: {integrity: sha512-p0bQukD8OEHxzY4T9OlANBbEFGnOnjo1CYi50HES7OD36UO2yPh6T+uOJKLtlg06eclxroipRCpQGMpeH8EJ/g==}
engines: {node: ^20.19.0 || >=22.12.0}
'@oxc-project/types@0.115.0':
resolution: {integrity: sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw==}
'@oxc-project/types@0.121.0':
resolution: {integrity: sha512-CGtOARQb9tyv7ECgdAlFxi0Fv7lmzvmlm2rpD/RdijOO9rfk/JvB1CjT8EnoD+tjna/IYgKKw3IV7objRb+aYw==}
@@ -4360,6 +4514,81 @@ packages:
'@ungap/structured-clone@1.3.0':
resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
'@unocss/cli@66.6.7':
resolution: {integrity: sha512-m/yW5HMVyxfAOeyO4OyA4JB9dY+/gTsk25ucI8xVCFVDEENPEGr+vEqTDOA+vfe6pdURtyDYS7OrhikIRU1WNA==}
engines: {node: '>=14'}
hasBin: true
'@unocss/config@66.6.7':
resolution: {integrity: sha512-1uleyRLyJc6PNNc2L3hEaKL89zXwvQAtP36oFySgL47RAxZHPZ4vfqFpbwR0eEN4iSqTS24ZFr7CTRWCaEGjzQ==}
engines: {node: '>=14'}
'@unocss/core@66.6.7':
resolution: {integrity: sha512-Q8456iWFtdwrUNYKVOQY8ygRggjZOVtLc6Jc8KIkxig7OiNlUWOgXJTfCh4I8g6jBYzC5eHaHFDLgJOmOrxBsg==}
'@unocss/extractor-arbitrary-variants@66.6.7':
resolution: {integrity: sha512-PQiBHK0yUJ0BR+3GYnTPU6va6HVSRPV+O+s1zZmt23TWbyIeucoKCNR47TDtv+Z1xuksY8krIjtDYtufdrVWKw==}
'@unocss/inspector@66.6.7':
resolution: {integrity: sha512-4lA70A/wy9dfSDm7rJ5Uq5fKz+/Szm2rUcHjdbLCVNEc6vv2YXeI7aFvP5qDjTp4ClBSF2AMPnF1mtoMQOfDvA==}
'@unocss/postcss@66.6.7':
resolution: {integrity: sha512-ArXEkhP2czxkeKQKI7RqmZiw3n8Kj6AR+WIssta/KgLRefEbYHJht3a2qgP739a1uSDYnvn19SN40+i7TCpKrg==}
engines: {node: '>=14'}
peerDependencies:
postcss: ^8.4.21
'@unocss/preset-attributify@66.6.7':
resolution: {integrity: sha512-thtoLQb53+Acy2QJYT6n+YhgNJ5ilhS8k9bqi+UzflbsuK4TJqOuQQjC9fRkULP5QjtNxgqN3d5Up7ms8tBPDA==}
'@unocss/preset-icons@66.6.7':
resolution: {integrity: sha512-mGAOyI/qz1pZUV1BcOtWAMm5czdFCjhFCYcDk0KY+Jw37pKRVSQRFeh4gpHuYKmehGv36caLyVrWXpTAwRBdFQ==}
'@unocss/preset-mini@66.6.7':
resolution: {integrity: sha512-tf0mqiSEhPQ49WZOqjNhxlbZbNakiBLzCoxfLSzqfIGglOPYShP8mxsdp9Jv0n+Ntn0rHcBiX5KTLfax1/Bd9g==}
'@unocss/preset-tagify@66.6.7':
resolution: {integrity: sha512-0WeQf+Dx9Ztv3aewkBKEnAfOauSjvWBlfkpsgLpXcCkyGMnCqq87UrAq3+b76TDJvQc8i2ADlvVGK7V1z0JZQg==}
'@unocss/preset-typography@66.6.7':
resolution: {integrity: sha512-RA7MwPDD5N9xGrbWnguVm5tP+F4/n/9X1rJsq2nBjvvK2dbtIRJZjRFM1vBDsR0GIhtvbHMoTchZaSZed5I+Hw==}
'@unocss/preset-uno@66.6.7':
resolution: {integrity: sha512-imGCe6Yv2XgrJxP77gV8WZCz0xL99MsGov5rYn64lh2/tcsHF2rUIhTj/Urgxt0kwk8rLFtGbR1JuwPMNL5EDw==}
'@unocss/preset-web-fonts@66.6.7':
resolution: {integrity: sha512-GLjUoSL/kYt1Yw2zpzixKnxvpHgLHAg0JXiPglct4PZ9YmUzCPbvJ/vVn+0AnB8Fxr29Z8NAFSNoX625ZaRonQ==}
'@unocss/preset-wind3@66.6.7':
resolution: {integrity: sha512-PKyqeRzlIMd3Irdt6fCKMm73zgwweiXESk5edUK8dVWndvPIcZCOqrEq7yg6Pr/Q8tHdq26viYSkVY3a3t8RSg==}
'@unocss/preset-wind4@66.6.7':
resolution: {integrity: sha512-9grhWeBsFzpv8iER9AFATRaxLyXMCwGQ5HzeI4XZh2ZZ9O6vC7nYfGhns4/I+F/RpFglzU1bjqMWRS/DS8OpGQ==}
'@unocss/preset-wind@66.6.7':
resolution: {integrity: sha512-jxtAN96jljd+KglbhPv6Y/ujceI5rVdrLQimj4KUTPoYBPEiWadzsGKN3o8Q07hlPRg+hBlO0r4tGSUWl+/EZQ==}
'@unocss/rule-utils@66.6.7':
resolution: {integrity: sha512-4PT/s8yKIShSqP9XPSw4EjbZopcu3wlIB9i3kbGbzQwF91H+0Yy10guK3kHDGtkmWVN6Np6VvaGIj2UcbmaivA==}
engines: {node: '>=14'}
'@unocss/transformer-attributify-jsx@66.6.7':
resolution: {integrity: sha512-r5bsnaPVe4iySLK5G5rA/QPSKmpPjYT9lixEv+KElvZcqZ+cPpkGoo+E+rnTcapu9KDMOVJItH/4Zy9m4AQ1ZQ==}
'@unocss/transformer-compile-class@66.6.7':
resolution: {integrity: sha512-4uz4jCyq8VUaSPveXhelUWUNaTnetPFvEmXzmbYJ5BygAlUlipNynffUlUusDQmBBRrfZhJNB5J1Zif2Q6oUiA==}
'@unocss/transformer-directives@66.6.7':
resolution: {integrity: sha512-z3gi8/cD2P0I+c6jOPZUtsPXknHwVNlMIitSh7LhyM6W3EqbqvDcYH2gFeGhdhoYcN2r5OpTBujq34iz4IdUxA==}
'@unocss/transformer-variant-group@66.6.7':
resolution: {integrity: sha512-XouJuQCjYJpvR3sY4QDXnGXxtyJ4qgWFG+S9bAB01TTslhQLvNPE9o2+4gZlltnJLqxiPQWuLeJA1KdPD6ciww==}
'@unocss/vite@66.6.7':
resolution: {integrity: sha512-8AHrVzAecnQaPLJv3/mpyFt5j2iL3gEwkZcZ8HzjH5ttK2XON1YE9vgujN5NS/yvZwlJxCMNPxn0S410/Ek61A==}
peerDependencies:
vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0-0
'@unpic/core@1.0.3':
resolution: {integrity: sha512-aum9YNVUGso7MjGLD0Rp/08kywCGLqZ03/q6VQBFFakDBOXWEc8D4kPGcZ8v5wEnGRex3lE+++bOuucBp3KJ/w==}
@@ -5006,6 +5235,10 @@ packages:
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
engines: {node: '>= 14.16.0'}
chokidar@5.0.0:
resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
engines: {node: '>= 20.19.0'}
chownr@1.1.4:
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
@@ -5079,6 +5312,9 @@ packages:
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
colorette@2.0.20:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
comma-separated-tokens@1.0.8:
resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==}
@@ -5184,6 +5420,10 @@ packages:
resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
css-tree@3.2.1:
resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==}
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'}
@@ -5478,6 +5718,9 @@ packages:
resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==}
engines: {node: '>=12'}
duplexer@0.1.2:
resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
echarts-for-react@3.0.6:
resolution: {integrity: sha512-4zqLgTGWS3JvkQDXjzkR1k1CHRdpd6by0988TWMJgnvDytegWLbeP/VNZmMa+0VJx2eD7Y632bi2JquXDgiGJg==}
peerDependencies:
@@ -6146,6 +6389,10 @@ packages:
graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
gzip-size@6.0.0:
resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==}
engines: {node: '>=10'}
hachure-fill@0.5.2:
resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==}
@@ -6748,6 +6995,9 @@ packages:
resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
hasBin: true
magic-regexp@0.10.0:
resolution: {integrity: sha512-Uly1Bu4lO1hwHUW0CQeSWuRtzCMNO00CmXtS8N6fyvB3B979GOEEeAkiTUDsmbYLAbvpUS/Kt5c4ibosAzVyVg==}
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
@@ -6849,6 +7099,9 @@ packages:
mdn-data@2.23.0:
resolution: {integrity: sha512-786vq1+4079JSeu2XdcDjrhi/Ry7BWtjDl9WtGPWLiIHb2T66GvIVflZTBoSNZ5JqTtJGYEVMuFA/lbQlMOyDQ==}
mdn-data@2.27.1:
resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==}
memoize-one@5.2.1:
resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==}
@@ -7206,6 +7459,10 @@ packages:
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
engines: {node: '>= 0.8.0'}
oxc-parser@0.115.0:
resolution: {integrity: sha512-2w7Xn3CbS/zwzSY82S5WLemrRu3CT57uF7Lx8llrE/2bul6iMTcJE4Rbls7GDNbLn3ttATI68PfOz2Pt3KZ2cQ==}
engines: {node: ^20.19.0 || >=22.12.0}
oxc-parser@0.121.0:
resolution: {integrity: sha512-ek9o58+SCv6AV7nchiAcUJy1DNE2CC5WRdBcO0mF+W4oRjNQfPO7b3pLjTHSFECpHkKGOZSQxx3hk8viIL5YCg==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -7213,6 +7470,11 @@ packages:
oxc-resolver@11.19.1:
resolution: {integrity: sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg==}
oxc-walker@0.7.0:
resolution: {integrity: sha512-54B4KUhrzbzc4sKvKwVYm7E2PgeROpGba0/2nlNZMqfDyca+yOor5IMb4WLGBatGDT0nkzYdYuzylg7n3YfB7A==}
peerDependencies:
oxc-parser: '>=0.98.0'
oxfmt@0.42.0:
resolution: {integrity: sha512-QhejGErLSMReNuZ6vxgFHDyGoPbjTRNi6uGHjy0cvIjOQFqD6xmr/T+3L41ixR3NIgzcNiJ6ylQKpvShTgDfqg==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -7732,6 +7994,10 @@ packages:
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
engines: {node: '>= 14.18.0'}
readdirp@5.0.0:
resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==}
engines: {node: '>= 20.19.0'}
recast@0.23.11:
resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==}
engines: {node: '>= 4'}
@@ -8416,6 +8682,9 @@ packages:
resolution: {integrity: sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==}
engines: {node: '>=20'}
type-level-regexp@0.1.17:
resolution: {integrity: sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg==}
typescript@5.9.3:
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
engines: {node: '>=14.17'}
@@ -8484,6 +8753,21 @@ packages:
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
engines: {node: '>= 10.0.0'}
unocss@66.6.7:
resolution: {integrity: sha512-TdZ/JnKhrqkknrMvLl0KOwrGzFThEspFIyYiylFYJki2JkMN/5EJIr+vIZEGRX69hFTjTLi6utIpbipueqzNbw==}
engines: {node: '>=14'}
peerDependencies:
'@unocss/astro': 66.6.7
'@unocss/postcss': 66.6.7
'@unocss/webpack': 66.6.7
peerDependenciesMeta:
'@unocss/astro':
optional: true
'@unocss/postcss':
optional: true
'@unocss/webpack':
optional: true
unpic@4.2.2:
resolution: {integrity: sha512-z6T2ScMgRV2y2H8MwwhY5xHZWXhUx/YxtOCGJwfURSl7ypVy4HpLIMWoIZKnnxQa/RKzM0kg8hUh0paIrpLfvw==}
@@ -10398,54 +10682,110 @@ snapshots:
'@ota-meshi/ast-token-store@0.3.0': {}
'@oxc-parser/binding-android-arm-eabi@0.115.0':
optional: true
'@oxc-parser/binding-android-arm-eabi@0.121.0':
optional: true
'@oxc-parser/binding-android-arm64@0.115.0':
optional: true
'@oxc-parser/binding-android-arm64@0.121.0':
optional: true
'@oxc-parser/binding-darwin-arm64@0.115.0':
optional: true
'@oxc-parser/binding-darwin-arm64@0.121.0':
optional: true
'@oxc-parser/binding-darwin-x64@0.115.0':
optional: true
'@oxc-parser/binding-darwin-x64@0.121.0':
optional: true
'@oxc-parser/binding-freebsd-x64@0.115.0':
optional: true
'@oxc-parser/binding-freebsd-x64@0.121.0':
optional: true
'@oxc-parser/binding-linux-arm-gnueabihf@0.115.0':
optional: true
'@oxc-parser/binding-linux-arm-gnueabihf@0.121.0':
optional: true
'@oxc-parser/binding-linux-arm-musleabihf@0.115.0':
optional: true
'@oxc-parser/binding-linux-arm-musleabihf@0.121.0':
optional: true
'@oxc-parser/binding-linux-arm64-gnu@0.115.0':
optional: true
'@oxc-parser/binding-linux-arm64-gnu@0.121.0':
optional: true
'@oxc-parser/binding-linux-arm64-musl@0.115.0':
optional: true
'@oxc-parser/binding-linux-arm64-musl@0.121.0':
optional: true
'@oxc-parser/binding-linux-ppc64-gnu@0.115.0':
optional: true
'@oxc-parser/binding-linux-ppc64-gnu@0.121.0':
optional: true
'@oxc-parser/binding-linux-riscv64-gnu@0.115.0':
optional: true
'@oxc-parser/binding-linux-riscv64-gnu@0.121.0':
optional: true
'@oxc-parser/binding-linux-riscv64-musl@0.115.0':
optional: true
'@oxc-parser/binding-linux-riscv64-musl@0.121.0':
optional: true
'@oxc-parser/binding-linux-s390x-gnu@0.115.0':
optional: true
'@oxc-parser/binding-linux-s390x-gnu@0.121.0':
optional: true
'@oxc-parser/binding-linux-x64-gnu@0.115.0':
optional: true
'@oxc-parser/binding-linux-x64-gnu@0.121.0':
optional: true
'@oxc-parser/binding-linux-x64-musl@0.115.0':
optional: true
'@oxc-parser/binding-linux-x64-musl@0.121.0':
optional: true
'@oxc-parser/binding-openharmony-arm64@0.115.0':
optional: true
'@oxc-parser/binding-openharmony-arm64@0.121.0':
optional: true
'@oxc-parser/binding-wasm32-wasi@0.115.0(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)':
dependencies:
'@napi-rs/wasm-runtime': 1.1.2(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)
transitivePeerDependencies:
- '@emnapi/core'
- '@emnapi/runtime'
optional: true
'@oxc-parser/binding-wasm32-wasi@0.121.0(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)':
dependencies:
'@napi-rs/wasm-runtime': 1.1.2(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)
@@ -10454,17 +10794,28 @@ snapshots:
- '@emnapi/runtime'
optional: true
'@oxc-parser/binding-win32-arm64-msvc@0.115.0':
optional: true
'@oxc-parser/binding-win32-arm64-msvc@0.121.0':
optional: true
'@oxc-parser/binding-win32-ia32-msvc@0.115.0':
optional: true
'@oxc-parser/binding-win32-ia32-msvc@0.121.0':
optional: true
'@oxc-parser/binding-win32-x64-msvc@0.115.0':
optional: true
'@oxc-parser/binding-win32-x64-msvc@0.121.0':
optional: true
'@oxc-project/runtime@0.121.0': {}
'@oxc-project/types@0.115.0': {}
'@oxc-project/types@0.121.0': {}
'@oxc-project/types@0.122.0': {}
@@ -12115,6 +12466,147 @@ snapshots:
'@ungap/structured-clone@1.3.0': {}
'@unocss/cli@66.6.7':
dependencies:
'@jridgewell/remapping': 2.3.5
'@unocss/config': 66.6.7
'@unocss/core': 66.6.7
'@unocss/preset-wind3': 66.6.7
'@unocss/preset-wind4': 66.6.7
'@unocss/transformer-directives': 66.6.7
cac: 6.7.14
chokidar: 5.0.0
colorette: 2.0.20
consola: 3.4.2
magic-string: 0.30.21
pathe: 2.0.3
perfect-debounce: 2.1.0
tinyglobby: 0.2.15
unplugin-utils: 0.3.1
'@unocss/config@66.6.7':
dependencies:
'@unocss/core': 66.6.7
colorette: 2.0.20
consola: 3.4.2
unconfig: 7.5.0
'@unocss/core@66.6.7': {}
'@unocss/extractor-arbitrary-variants@66.6.7':
dependencies:
'@unocss/core': 66.6.7
'@unocss/inspector@66.6.7':
dependencies:
'@unocss/core': 66.6.7
'@unocss/rule-utils': 66.6.7
colorette: 2.0.20
gzip-size: 6.0.0
sirv: 3.0.2
'@unocss/postcss@66.6.7(postcss@8.5.8)':
dependencies:
'@unocss/config': 66.6.7
'@unocss/core': 66.6.7
'@unocss/rule-utils': 66.6.7
css-tree: 3.2.1
postcss: 8.5.8
tinyglobby: 0.2.15
'@unocss/preset-attributify@66.6.7':
dependencies:
'@unocss/core': 66.6.7
'@unocss/preset-icons@66.6.7':
dependencies:
'@iconify/utils': 3.1.0
'@unocss/core': 66.6.7
ofetch: 1.5.1
'@unocss/preset-mini@66.6.7':
dependencies:
'@unocss/core': 66.6.7
'@unocss/extractor-arbitrary-variants': 66.6.7
'@unocss/rule-utils': 66.6.7
'@unocss/preset-tagify@66.6.7':
dependencies:
'@unocss/core': 66.6.7
'@unocss/preset-typography@66.6.7':
dependencies:
'@unocss/core': 66.6.7
'@unocss/rule-utils': 66.6.7
'@unocss/preset-uno@66.6.7':
dependencies:
'@unocss/core': 66.6.7
'@unocss/preset-wind3': 66.6.7
'@unocss/preset-web-fonts@66.6.7':
dependencies:
'@unocss/core': 66.6.7
ofetch: 1.5.1
'@unocss/preset-wind3@66.6.7':
dependencies:
'@unocss/core': 66.6.7
'@unocss/preset-mini': 66.6.7
'@unocss/rule-utils': 66.6.7
'@unocss/preset-wind4@66.6.7':
dependencies:
'@unocss/core': 66.6.7
'@unocss/extractor-arbitrary-variants': 66.6.7
'@unocss/rule-utils': 66.6.7
'@unocss/preset-wind@66.6.7':
dependencies:
'@unocss/core': 66.6.7
'@unocss/preset-wind3': 66.6.7
'@unocss/rule-utils@66.6.7':
dependencies:
'@unocss/core': 66.6.7
magic-string: 0.30.21
'@unocss/transformer-attributify-jsx@66.6.7(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)':
dependencies:
'@unocss/core': 66.6.7
oxc-parser: 0.115.0(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)
oxc-walker: 0.7.0(oxc-parser@0.115.0(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1))
transitivePeerDependencies:
- '@emnapi/core'
- '@emnapi/runtime'
'@unocss/transformer-compile-class@66.6.7':
dependencies:
'@unocss/core': 66.6.7
'@unocss/transformer-directives@66.6.7':
dependencies:
'@unocss/core': 66.6.7
'@unocss/rule-utils': 66.6.7
css-tree: 3.2.1
'@unocss/transformer-variant-group@66.6.7':
dependencies:
'@unocss/core': 66.6.7
'@unocss/vite@66.6.7(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))':
dependencies:
'@jridgewell/remapping': 2.3.5
'@unocss/config': 66.6.7
'@unocss/core': 66.6.7
'@unocss/inspector': 66.6.7
chokidar: 5.0.0
magic-string: 0.30.21
pathe: 2.0.3
tinyglobby: 0.2.15
unplugin-utils: 0.3.1
vite: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)'
'@unpic/core@1.0.3':
dependencies:
unpic: 4.2.2
@@ -12840,6 +13332,10 @@ snapshots:
dependencies:
readdirp: 4.1.2
chokidar@5.0.0:
dependencies:
readdirp: 5.0.0
chownr@1.1.4:
optional: true
@@ -12907,6 +13403,8 @@ snapshots:
color-name@1.1.4: {}
colorette@2.0.20: {}
comma-separated-tokens@1.0.8: {}
comma-separated-tokens@2.0.3: {}
@@ -12997,6 +13495,11 @@ snapshots:
mdn-data: 2.0.30
source-map-js: 1.2.1
css-tree@3.2.1:
dependencies:
mdn-data: 2.27.1
source-map-js: 1.2.1
css-what@6.2.2: {}
css.escape@1.5.1: {}
@@ -13292,6 +13795,8 @@ snapshots:
dotenv@16.6.1: {}
duplexer@0.1.2: {}
echarts-for-react@3.0.6(echarts@6.0.0)(react@19.2.4):
dependencies:
echarts: 6.0.0
@@ -14197,6 +14702,10 @@ snapshots:
graceful-fs@4.2.11: {}
gzip-size@6.0.0:
dependencies:
duplexer: 0.1.2
hachure-fill@0.5.2: {}
happy-dom@20.8.9:
@@ -14801,6 +15310,16 @@ snapshots:
lz-string@1.5.0: {}
magic-regexp@0.10.0:
dependencies:
estree-walker: 3.0.3
magic-string: 0.30.21
mlly: 1.8.2
regexp-tree: 0.1.27
type-level-regexp: 0.1.17
ufo: 1.6.3
unplugin: 2.3.11
magic-string@0.30.21:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
@@ -15036,6 +15555,8 @@ snapshots:
mdn-data@2.23.0: {}
mdn-data@2.27.1: {}
memoize-one@5.2.1: {}
merge-stream@2.0.0: {}
@@ -15565,6 +16086,34 @@ snapshots:
type-check: 0.4.0
word-wrap: 1.2.5
oxc-parser@0.115.0(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1):
dependencies:
'@oxc-project/types': 0.115.0
optionalDependencies:
'@oxc-parser/binding-android-arm-eabi': 0.115.0
'@oxc-parser/binding-android-arm64': 0.115.0
'@oxc-parser/binding-darwin-arm64': 0.115.0
'@oxc-parser/binding-darwin-x64': 0.115.0
'@oxc-parser/binding-freebsd-x64': 0.115.0
'@oxc-parser/binding-linux-arm-gnueabihf': 0.115.0
'@oxc-parser/binding-linux-arm-musleabihf': 0.115.0
'@oxc-parser/binding-linux-arm64-gnu': 0.115.0
'@oxc-parser/binding-linux-arm64-musl': 0.115.0
'@oxc-parser/binding-linux-ppc64-gnu': 0.115.0
'@oxc-parser/binding-linux-riscv64-gnu': 0.115.0
'@oxc-parser/binding-linux-riscv64-musl': 0.115.0
'@oxc-parser/binding-linux-s390x-gnu': 0.115.0
'@oxc-parser/binding-linux-x64-gnu': 0.115.0
'@oxc-parser/binding-linux-x64-musl': 0.115.0
'@oxc-parser/binding-openharmony-arm64': 0.115.0
'@oxc-parser/binding-wasm32-wasi': 0.115.0(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)
'@oxc-parser/binding-win32-arm64-msvc': 0.115.0
'@oxc-parser/binding-win32-ia32-msvc': 0.115.0
'@oxc-parser/binding-win32-x64-msvc': 0.115.0
transitivePeerDependencies:
- '@emnapi/core'
- '@emnapi/runtime'
oxc-parser@0.121.0(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1):
dependencies:
'@oxc-project/types': 0.121.0
@@ -15619,6 +16168,11 @@ snapshots:
- '@emnapi/core'
- '@emnapi/runtime'
oxc-walker@0.7.0(oxc-parser@0.115.0(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)):
dependencies:
magic-regexp: 0.10.0
oxc-parser: 0.115.0(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)
oxfmt@0.42.0:
dependencies:
tinypool: 2.1.0
@@ -16212,6 +16766,8 @@ snapshots:
readdirp@4.1.2: {}
readdirp@5.0.0: {}
recast@0.23.11:
dependencies:
ast-types: 0.16.1
@@ -17057,6 +17613,8 @@ snapshots:
dependencies:
tagged-tag: 1.0.0
type-level-regexp@0.1.17: {}
typescript@5.9.3: {}
ufo@1.6.3: {}
@@ -17138,6 +17696,32 @@ snapshots:
universalify@2.0.1: {}
unocss@66.6.7(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@unocss/postcss@66.6.7(postcss@8.5.8))(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)):
dependencies:
'@unocss/cli': 66.6.7
'@unocss/core': 66.6.7
'@unocss/preset-attributify': 66.6.7
'@unocss/preset-icons': 66.6.7
'@unocss/preset-mini': 66.6.7
'@unocss/preset-tagify': 66.6.7
'@unocss/preset-typography': 66.6.7
'@unocss/preset-uno': 66.6.7
'@unocss/preset-web-fonts': 66.6.7
'@unocss/preset-wind': 66.6.7
'@unocss/preset-wind3': 66.6.7
'@unocss/preset-wind4': 66.6.7
'@unocss/transformer-attributify-jsx': 66.6.7(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)
'@unocss/transformer-compile-class': 66.6.7
'@unocss/transformer-directives': 66.6.7
'@unocss/transformer-variant-group': 66.6.7
'@unocss/vite': 66.6.7(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))
optionalDependencies:
'@unocss/postcss': 66.6.7(postcss@8.5.8)
transitivePeerDependencies:
- '@emnapi/core'
- '@emnapi/runtime'
- vite
unpic@4.2.2: {}
unplugin-utils@0.3.1:

View File

@@ -86,6 +86,8 @@ catalog:
"@hono/node-server": 1.19.11
"@iconify-json/heroicons": 1.2.3
"@iconify-json/ri": 1.2.10
"@iconify/tools": 4.2.0
"@iconify/utils": 3.1.0
"@lexical/code": 0.42.0
"@lexical/link": 0.42.0
"@lexical/list": 0.42.0
@@ -116,6 +118,7 @@ catalog:
"@streamdown/math": 1.0.2
"@svgdotjs/svg.js": 3.2.5
"@t3-oss/env-nextjs": 0.13.11
"@unocss/postcss": 66.6.7
"@tailwindcss/typography": 0.5.19
"@tanstack/eslint-plugin-query": 5.95.2
"@tanstack/react-devtools": 0.10.0
@@ -242,6 +245,7 @@ catalog:
tsx: 4.21.0
typescript: 5.9.3
uglify-js: 3.19.3
unocss: 66.6.7
unist-util-visit: 5.1.0
use-context-selector: 2.0.0
uuid: 13.0.0

View File

@@ -1,5 +1,3 @@
@tailwind components;
@layer components {
.action-btn {
@apply inline-flex justify-center items-center cursor-pointer text-text-tertiary hover:text-text-secondary hover:bg-state-base-hover

View File

@@ -1,5 +1,3 @@
@tailwind components;
@layer components {
.badge {
@apply inline-flex justify-center items-center text-text-tertiary border border-divider-deep

View File

@@ -1,5 +1,3 @@
@tailwind components;
@layer components {
.btn {
@apply inline-flex justify-center items-center cursor-pointer whitespace-nowrap

View File

@@ -1,5 +1,3 @@
@tailwind components;
@layer components {
.premium-badge {
@apply shrink-0 relative inline-flex justify-center items-center rounded-md box-border border border-transparent text-white shadow-xs hover:shadow-lg bg-origin-border overflow-hidden transition-all duration-100 ease-out;

View File

@@ -1,5 +1,3 @@
@tailwind components;
@layer components {
.segmented-control {
@apply flex items-center bg-components-segmented-control-bg-normal gap-x-px
@@ -78,4 +76,4 @@
.item-text-large {
@apply px-0.5
}
}
}

View File

@@ -96,7 +96,7 @@
@apply w-3 h-3 bg-gray-500 hover:bg-none mr-1 !important;
}
.textArea {
@apply placeholder:text-gray-400 bg-gray-50 px-2 py-1 caret-primary-600 rounded-md hover:bg-gray-100 focus-visible:outline-none focus-visible:bg-white focus-visible:border focus-visible:border-gray-300 hover:shadow-[0_1px_2px_rgba(16,24,40,0.05);];
@apply placeholder:text-gray-400 bg-gray-50 px-2 py-1 caret-primary-600 rounded-md hover:bg-gray-100 focus-visible:outline-none focus-visible:bg-white focus-visible:border focus-visible:border-gray-300 hover:shadow-[0_1px_2px_rgba(16,24,40,0.05)];
}
.input {
@apply bg-gray-50 hover:bg-gray-100 focus-visible:bg-white !important

View File

@@ -150,7 +150,7 @@ function CodeGroupHeader({ title, tabTitles, selectedIndex }: CodeGroupHeaderPro
const hasTabs = (tabTitles?.length ?? 0) > 1
return (
<div className="flex min-h-[calc(theme(spacing.12)+1px)] flex-wrap items-start gap-x-4 border-b border-zinc-700 bg-zinc-800 px-4 dark:border-zinc-800 dark:bg-transparent">
<div className="flex min-h-[calc(3rem+1px)] flex-wrap items-start gap-x-4 border-b border-zinc-700 bg-zinc-800 px-4 dark:border-zinc-800 dark:bg-transparent">
{title && (
<h3 className="mr-auto pt-3 text-xs font-semibold text-white">
{title}

View File

@@ -83,7 +83,7 @@ export function Properties({ children }: IChildrenProps) {
<div className="my-6">
<ul
role="list"
className="m-0 max-w-[calc(theme(maxWidth.lg)-theme(spacing.8))] list-none divide-y divide-zinc-900/5 p-0 dark:divide-white/5"
className="m-0 max-w-[30rem] list-none divide-y divide-zinc-900/5 p-0 dark:divide-white/5"
>
{children}
</ul>

View File

@@ -19,7 +19,6 @@ import {
import { ErrorHandleTypeEnum } from '@/app/components/workflow/nodes/_base/components/error-handle/types'
import { cn } from '@/utils/classnames'
import BlockSelector from './block-selector'
import { ITERATION_CHILDREN_Z_INDEX, LOOP_CHILDREN_Z_INDEX } from './constants'
import CustomEdgeLinearGradientRender from './custom-edge-linear-gradient-render'
import {
useAvailableBlocks,
@@ -145,8 +144,8 @@ const CustomEdge = ({
'nopan nodrag hover:scale-125',
data?._hovering ? 'block' : 'hidden',
open && '!block',
data.isInIteration && `z-[${ITERATION_CHILDREN_Z_INDEX}]`,
data.isInLoop && `z-[${LOOP_CHILDREN_Z_INDEX}]`,
data.isInIteration && 'z-[1002]',
data.isInLoop && 'z-[1002]',
)}
style={{
position: 'absolute',

View File

@@ -13,9 +13,6 @@
@import "../components/base/premium-badge/index.css";
@import "../components/base/segmented-control/index.css";
@tailwind base;
@tailwind components;
html {
color-scheme: light;
}
@@ -691,7 +688,7 @@ a {
display: none;
}
@tailwind utilities;
@unocss !preflights;
@layer utilities {

View File

@@ -9,7 +9,7 @@
box-sizing: border-box; /* 1 */
border-width: 0; /* 2 */
border-style: solid; /* 2 */
border-color: theme('borderColor.DEFAULT', currentColor); /* 2 */
border-color: currentColor; /* 2 */
}
::before,
@@ -33,7 +33,7 @@ html,
-webkit-text-size-adjust: 100%; /* 2 */
-moz-tab-size: 4; /* 3 */
tab-size: 4; /* 3 */
font-family: theme('fontFamily.sans', ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"); /* 4 */
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */
-webkit-tap-highlight-color: transparent; /* 7 */
}
@@ -110,7 +110,7 @@ code,
kbd,
samp,
pre {
font-family: theme('fontFamily.mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace); /* 1 */
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */
font-size: 1em; /* 4 */
}
@@ -326,7 +326,7 @@ textarea {
input::placeholder,
textarea::placeholder {
opacity: 1; /* 1 */
color: theme('colors.gray.400', #9ca3af); /* 2 */
color: #98a2b3; /* 2 */
}
/*

View File

@@ -1,5 +1,6 @@
import { IS_DEV } from '@/config'
import { env } from '@/env'
import 'uno.css'
async function main() {
// Polyfill for Array.prototype.toSpliced (ES2023, Chrome 110+)

View File

@@ -163,6 +163,8 @@
"@hono/node-server": "catalog:",
"@iconify-json/heroicons": "catalog:",
"@iconify-json/ri": "catalog:",
"@iconify/tools": "catalog:",
"@iconify/utils": "catalog:",
"@mdx-js/loader": "catalog:",
"@mdx-js/react": "catalog:",
"@mdx-js/rollup": "catalog:",
@@ -199,6 +201,7 @@
"@types/sortablejs": "catalog:",
"@typescript-eslint/parser": "catalog:",
"@typescript/native-preview": "catalog:",
"@unocss/postcss": "catalog:",
"@vitejs/plugin-react": "catalog:",
"@vitejs/plugin-rsc": "catalog:",
"@vitest/coverage-v8": "catalog:",
@@ -228,6 +231,7 @@
"tsx": "catalog:",
"typescript": "catalog:",
"uglify-js": "catalog:",
"unocss": "catalog:",
"vinext": "catalog:",
"vite": "catalog:",
"vite-plugin-inspect": "catalog:",

View File

@@ -1,6 +0,0 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

286
web/uno.config.ts Normal file
View File

@@ -0,0 +1,286 @@
/* eslint-disable ts/ban-ts-comment */
// @ts-nocheck
import { readdirSync } from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { cleanupSVG, deOptimisePaths, isEmptyColor, parseColors, runSVGO, SVG } from '@iconify/tools'
import { compareColors, stringToColor } from '@iconify/utils/lib/colors'
import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders'
import { defineConfig, presetIcons, presetTypography, presetWind3, transformerDirectives } from 'unocss'
import tailwindThemeVarDefine from './themes/tailwind-theme-var-define.ts'
const dirname = typeof __dirname !== 'undefined'
? __dirname
: path.dirname(fileURLToPath(import.meta.url))
const blackColor = stringToColor('black')
const whiteColor = stringToColor('white')
const transformSvgToCurrentColor = (source: string) => {
const svg = new SVG(source)
cleanupSVG(svg)
parseColors(svg, {
defaultColor: 'currentColor',
callback: (attr, colorString, color) => {
if (!color)
throw new Error(`Invalid color: "${colorString}" in attribute ${attr}`)
if (isEmptyColor(color))
return color
if (compareColors(color, blackColor))
return 'currentColor'
if (compareColors(color, whiteColor))
return 'remove'
return 'currentColor'
},
})
runSVGO(svg)
deOptimisePaths(svg)
return svg.toString()
}
const findSvgDirectories = (rootDir: string) => {
const result: string[] = []
const walk = (dir: string) => {
const entries = readdirSync(dir, { withFileTypes: true })
const subdirs: string[] = []
let hasSvgFiles = false
for (const entry of entries) {
if (entry.isFile() && entry.name.endsWith('.svg'))
hasSvgFiles = true
else if (entry.isDirectory())
subdirs.push(path.join(dir, entry.name))
}
if (hasSvgFiles)
result.push(dir)
for (const subdir of subdirs)
walk(subdir)
}
walk(rootDir)
return result
}
const createCollectionLoaders = (source: string, prefix: string) => {
const directories = findSvgDirectories(source)
return Object.fromEntries(
directories.map((dir) => {
const pathPrefix = path.relative(source, dir).split(path.sep).join('-')
return [
`${prefix}-${pathPrefix}`,
FileSystemIconLoader(dir, transformSvgToCurrentColor),
]
}),
)
}
const publicCollections = createCollectionLoaders(
path.resolve(dirname, 'app/components/base/icons/assets/public'),
'custom-public',
)
const venderCollections = createCollectionLoaders(
path.resolve(dirname, 'app/components/base/icons/assets/vender'),
'custom-vender',
)
export default defineConfig({
blocklist: [
/\$\{/,
/^(?:Array|array)\[/,
/^[A-Z][A-Z0-9_[\].-]*$/,
/bg-\[var\(--sdm-bg,inherit\]/,
/bg-\[var\(--shiki-dark-bg,var\(--sdm-bg,inherit\)\]/,
],
rules: [
['bg-[var(--sdm-bg,inherit]', { 'background-color': 'var(--sdm-bg,inherit)' }],
['bg-[var(--shiki-dark-bg,var(--sdm-bg,inherit)]', { 'background-color': 'var(--shiki-dark-bg,var(--sdm-bg,inherit))' }],
],
content: {
pipeline: {
include: [
/\.(vue|svelte|[jt]sx|vine.ts|mdx?|astro|elm|php|phtml|marko|html)($|\?)/,
/\/app\/.*\.[jt]s($|\?)/,
/\/context\/.*\.[jt]s($|\?)/,
/\/node_modules\/streamdown\/dist\/.*\.js($|\?)/,
/\/node_modules\/@streamdown\/math\/dist\/.*\.js($|\?)/,
],
exclude: [
/\/__tests__\//,
/\.(spec|test)\.[jt]sx?($|\?)/,
],
},
},
presets: [
presetWind3(),
presetTypography(),
presetIcons({
collections: {
...publicCollections,
...venderCollections,
},
extraProperties: {
width: '1rem',
height: '1rem',
display: 'block',
},
}),
],
transformers: [
transformerDirectives(),
],
extendTheme: (theme) => {
theme.breakpoints = {
...theme.breakpoints,
'mobile': '100px',
'tablet': '640px',
'pc': '769px',
'2k': '2560px',
}
theme.colors = {
...theme.colors,
'gray': {
...theme.colors?.gray,
25: '#fcfcfd',
50: '#f9fafb',
100: '#f2f4f7',
200: '#eaecf0',
300: '#d0d5dd',
400: '#98a2b3',
500: '#667085',
600: '#344054',
700: '#475467',
800: '#1d2939',
900: '#101828',
},
'primary': {
25: '#f5f8ff',
50: '#eff4ff',
100: '#d1e0ff',
200: '#b2ccff',
300: '#84adff',
400: '#528bff',
500: '#2970ff',
600: '#155eef',
700: '#004eeb',
800: '#0040c1',
900: '#00359e',
},
'blue': {
...theme.colors?.blue,
500: '#E1EFFE',
},
'green': {
...theme.colors?.green,
50: '#F3FAF7',
100: '#DEF7EC',
800: '#03543F',
},
'yellow': {
...theme.colors?.yellow,
100: '#FDF6B2',
800: '#723B13',
},
'purple': {
...theme.colors?.purple,
50: '#F6F5FF',
200: '#DCD7FE',
},
'indigo': {
...theme.colors?.indigo,
25: '#F5F8FF',
50: '#EEF4FF',
100: '#E0EAFF',
300: '#A4BCFD',
400: '#8098F9',
600: '#444CE7',
800: '#2D31A6',
},
'background-gradient-bg-fill-chat-bubble-bg-3': 'var(--color-background-gradient-bg-fill-chat-bubble-bg-3)',
...tailwindThemeVarDefine,
}
theme.boxShadow = {
...theme.boxShadow,
'xs': '0px 1px 2px 0px rgba(16, 24, 40, 0.05)',
'sm': '0px 1px 2px 0px rgba(16, 24, 40, 0.06), 0px 1px 3px 0px rgba(16, 24, 40, 0.10)',
'sm-no-bottom': '0px -1px 2px 0px rgba(16, 24, 40, 0.06), 0px -1px 3px 0px rgba(16, 24, 40, 0.10)',
'md': '0px 2px 4px -2px rgba(16, 24, 40, 0.06), 0px 4px 8px -2px rgba(16, 24, 40, 0.10)',
'lg': '0px 4px 6px -2px rgba(16, 24, 40, 0.03), 0px 12px 16px -4px rgba(16, 24, 40, 0.08)',
'xl': '0px 8px 8px -4px rgba(16, 24, 40, 0.03), 0px 20px 24px -4px rgba(16, 24, 40, 0.08)',
'2xl': '0px 24px 48px -12px rgba(16, 24, 40, 0.18)',
'3xl': '0px 32px 64px -12px rgba(16, 24, 40, 0.14)',
'status-indicator-green-shadow': '0px 2px 6px 0px var(--color-components-badge-status-light-success-halo), 0px 0px 0px 1px var(--color-components-badge-status-light-border-outer)',
'status-indicator-warning-shadow': '0px 2px 6px 0px var(--color-components-badge-status-light-warning-halo), 0px 0px 0px 1px var(--color-components-badge-status-light-border-outer)',
'status-indicator-red-shadow': '0px 2px 6px 0px var(--color-components-badge-status-light-error-halo), 0px 0px 0px 1px var(--color-components-badge-status-light-border-outer)',
'status-indicator-blue-shadow': '0px 2px 6px 0px var(--color-components-badge-status-light-normal-halo), 0px 0px 0px 1px var(--color-components-badge-status-light-border-outer)',
'status-indicator-gray-shadow': '0px 1px 2px 0px var(--color-components-badge-status-light-disabled-halo), 0px 0px 0px 1px var(--color-components-badge-status-light-border-outer)',
}
theme.opacity = {
...theme.opacity,
2: '0.02',
8: '0.08',
}
theme.fontSize = {
...theme.fontSize,
'2xs': '0.625rem',
}
theme.backgroundImage = {
...theme.backgroundImage,
'chatbot-bg': 'var(--color-chatbot-bg)',
'chat-bubble-bg': 'var(--color-chat-bubble-bg)',
'chat-input-mask': 'var(--color-chat-input-mask)',
'workflow-process-bg': 'var(--color-workflow-process-bg)',
'workflow-process-paused-bg': 'var(--color-workflow-process-paused-bg)',
'workflow-run-failed-bg': 'var(--color-workflow-run-failed-bg)',
'workflow-batch-failed-bg': 'var(--color-workflow-batch-failed-bg)',
'mask-top2bottom-gray-50-to-transparent': 'var(--mask-top2bottom-gray-50-to-transparent)',
'marketplace-divider-bg': 'var(--color-marketplace-divider-bg)',
'marketplace-plugin-empty': 'var(--color-marketplace-plugin-empty)',
'toast-success-bg': 'var(--color-toast-success-bg)',
'toast-warning-bg': 'var(--color-toast-warning-bg)',
'toast-error-bg': 'var(--color-toast-error-bg)',
'toast-info-bg': 'var(--color-toast-info-bg)',
'app-detail-bg': 'var(--color-app-detail-bg)',
'app-detail-overlay-bg': 'var(--color-app-detail-overlay-bg)',
'dataset-chunk-process-success-bg': 'var(--color-dataset-chunk-process-success-bg)',
'dataset-chunk-process-error-bg': 'var(--color-dataset-chunk-process-error-bg)',
'dataset-chunk-detail-card-hover-bg': 'var(--color-dataset-chunk-detail-card-hover-bg)',
'dataset-child-chunk-expand-btn-bg': 'var(--color-dataset-child-chunk-expand-btn-bg)',
'dataset-option-card-blue-gradient': 'var(--color-dataset-option-card-blue-gradient)',
'dataset-option-card-purple-gradient': 'var(--color-dataset-option-card-purple-gradient)',
'dataset-option-card-orange-gradient': 'var(--color-dataset-option-card-orange-gradient)',
'dataset-chunk-list-mask-bg': 'var(--color-dataset-chunk-list-mask-bg)',
'line-divider-bg': 'var(--color-line-divider-bg)',
'dataset-warning-message-bg': 'var(--color-dataset-warning-message-bg)',
'price-premium-badge-background': 'var(--color-premium-badge-background)',
'premium-yearly-tip-text-background': 'var(--color-premium-yearly-tip-text-background)',
'price-premium-text-background': 'var(--color-premium-text-background)',
'price-enterprise-background': 'var(--color-price-enterprise-background)',
'grid-mask-background': 'var(--color-grid-mask-background)',
'node-data-source-bg': 'var(--color-node-data-source-bg)',
'tag-selector-mask-bg': 'var(--color-tag-selector-mask-bg)',
'tag-selector-mask-hover-bg': 'var(--color-tag-selector-mask-hover-bg)',
'pipeline-template-card-hover-bg': 'var(--color-pipeline-template-card-hover-bg)',
'pipeline-add-documents-title-bg': 'var(--color-pipeline-add-documents-title-bg)',
'billing-plan-title-bg': 'var(--color-billing-plan-title-bg)',
'billing-plan-card-premium-bg': 'var(--color-billing-plan-card-premium-bg)',
'billing-plan-card-enterprise-bg': 'var(--color-billing-plan-card-enterprise-bg)',
'knowledge-pipeline-creation-footer-bg': 'var(--color-knowledge-pipeline-creation-footer-bg)',
'progress-bar-indeterminate-stripe': 'var(--color-progress-bar-indeterminate-stripe)',
'chat-answer-human-input-form-divider-bg': 'var(--color-chat-answer-human-input-form-divider-bg)',
}
theme.animation = {
...theme.animation,
'spin-slow': 'spin 2s linear infinite',
}
return theme
},
})

View File

@@ -1,5 +1,6 @@
import { fileURLToPath } from 'node:url'
import react from '@vitejs/plugin-react'
import UnoCSS from 'unocss/vite'
import vinext from 'vinext'
import Inspect from 'vite-plugin-inspect'
import { defineConfig } from 'vite-plus'
@@ -37,6 +38,7 @@ export default defineConfig(({ mode }) => {
]
: isStorybook
? [
UnoCSS(),
react(),
]
: [
@@ -48,6 +50,7 @@ export default defineConfig(({ mode }) => {
injectTarget: rootClientInjectTarget,
projectRoot,
}),
UnoCSS(),
react(),
vinext({ react: false }),
customI18nHmrPlugin({ injectTarget: rootClientInjectTarget }),