mirror of https://github.com/langgenius/dify.git
Merge remote-tracking branch 'myori/main' into feat/collaboration2
This commit is contained in:
commit
bb3d94f1c5
|
|
@ -16,14 +16,14 @@ jobs:
|
|||
|
||||
- name: Check Docker Compose inputs
|
||||
id: docker-compose-changes
|
||||
uses: tj-actions/changed-files@v46
|
||||
uses: tj-actions/changed-files@v47
|
||||
with:
|
||||
files: |
|
||||
docker/generate_docker_compose
|
||||
docker/.env.example
|
||||
docker/docker-compose-template.yaml
|
||||
docker/docker-compose.yaml
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ jobs:
|
|||
context: "web"
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
path: /tmp/digests
|
||||
pattern: digests-${{ matrix.context }}-*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ jobs:
|
|||
github.event.workflow_run.head_branch == 'deploy/agent-dev'
|
||||
steps:
|
||||
- name: Deploy to server
|
||||
uses: appleboy/ssh-action@v0.1.8
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.AGENT_DEV_SSH_HOST }}
|
||||
username: ${{ secrets.SSH_USER }}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ jobs:
|
|||
github.event.workflow_run.head_branch == 'deploy/dev'
|
||||
steps:
|
||||
- name: Deploy to server
|
||||
uses: appleboy/ssh-action@v0.1.8
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.SSH_HOST }}
|
||||
username: ${{ secrets.SSH_USER }}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ jobs:
|
|||
)
|
||||
steps:
|
||||
- name: Deploy to server
|
||||
uses: appleboy/ssh-action@v0.1.8
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HITL_SSH_HOST }}
|
||||
username: ${{ secrets.SSH_USER }}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ jobs:
|
|||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
- uses: actions/stale@v10
|
||||
with:
|
||||
days-before-issue-stale: 15
|
||||
days-before-issue-close: 3
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
|
|
|||
|
|
@ -12,12 +12,8 @@ The codebase is split into:
|
|||
|
||||
## Backend Workflow
|
||||
|
||||
- Read `api/AGENTS.md` for details
|
||||
- Run backend CLI commands through `uv run --project api <command>`.
|
||||
|
||||
- Before submission, all backend modifications must pass local checks: `make lint`, `make type-check`, and `uv run --project api --dev dev/pytest/pytest_unit_tests.sh`.
|
||||
|
||||
- Use Makefile targets for linting and formatting; `make lint` and `make type-check` cover the required checks.
|
||||
|
||||
- Integration tests are CI-only and are not expected to run in the local environment.
|
||||
|
||||
## Frontend Workflow
|
||||
|
|
|
|||
12
Makefile
12
Makefile
|
|
@ -61,7 +61,8 @@ check:
|
|||
|
||||
lint:
|
||||
@echo "🔧 Running ruff format, check with fixes, import linter, and dotenv-linter..."
|
||||
@uv run --project api --dev sh -c 'ruff format ./api && ruff check --fix ./api'
|
||||
@uv run --project api --dev ruff format ./api
|
||||
@uv run --project api --dev ruff check --fix ./api
|
||||
@uv run --directory api --dev lint-imports
|
||||
@uv run --project api --dev dotenv-linter ./api/.env.example ./web/.env.example
|
||||
@echo "✅ Linting complete"
|
||||
|
|
@ -73,7 +74,12 @@ type-check:
|
|||
|
||||
test:
|
||||
@echo "🧪 Running backend unit tests..."
|
||||
@uv run --project api --dev dev/pytest/pytest_unit_tests.sh
|
||||
@if [ -n "$(TARGET_TESTS)" ]; then \
|
||||
echo "Target: $(TARGET_TESTS)"; \
|
||||
uv run --project api --dev pytest $(TARGET_TESTS); \
|
||||
else \
|
||||
uv run --project api --dev dev/pytest/pytest_unit_tests.sh; \
|
||||
fi
|
||||
@echo "✅ Tests complete"
|
||||
|
||||
# Build Docker images
|
||||
|
|
@ -125,7 +131,7 @@ help:
|
|||
@echo " make check - Check code with ruff"
|
||||
@echo " make lint - Format, fix, and lint code (ruff, imports, dotenv)"
|
||||
@echo " make type-check - Run type checking with basedpyright"
|
||||
@echo " make test - Run backend unit tests"
|
||||
@echo " make test - Run backend unit tests (or TARGET_TESTS=./api/tests/<target_tests>)"
|
||||
@echo ""
|
||||
@echo "Docker Build Targets:"
|
||||
@echo " make build-web - Build web Docker image"
|
||||
|
|
|
|||
248
api/AGENTS.md
248
api/AGENTS.md
|
|
@ -1,62 +1,236 @@
|
|||
# Agent Skill Index
|
||||
# API Agent Guide
|
||||
|
||||
## Agent Notes (must-check)
|
||||
|
||||
Before you start work on any backend file under `api/`, you MUST check whether a related note exists under:
|
||||
|
||||
- `agent-notes/<same-relative-path-as-target-file>.md`
|
||||
|
||||
Rules:
|
||||
|
||||
- **Path mapping**: for a target file `<path>/<name>.py`, the note must be `agent-notes/<path>/<name>.py.md` (same folder structure, same filename, plus `.md`).
|
||||
- **Before working**:
|
||||
- If the note exists, read it first and follow any constraints/decisions recorded there.
|
||||
- If the note conflicts with the current code, or references an "origin" file/path that has been deleted, renamed, or migrated, treat the **code as the single source of truth** and update the note to match reality.
|
||||
- If the note does not exist, create it with a short architecture/intent summary and any relevant invariants/edge cases.
|
||||
- **During working**:
|
||||
- Keep the note in sync as you discover constraints, make decisions, or change approach.
|
||||
- If you move/rename a file, migrate its note to the new mapped path (and fix any outdated references inside the note).
|
||||
- Record non-obvious edge cases, trade-offs, and the test/verification plan as you go (not just at the end).
|
||||
- Keep notes **coherent**: integrate new findings into the relevant sections and rewrite for clarity; avoid append-only “recent fix” / changelog-style additions unless the note is explicitly intended to be a changelog.
|
||||
- **When finishing work**:
|
||||
- Update the related note(s) to reflect what changed, why, and any new edge cases/tests.
|
||||
- If a file is deleted, remove or clearly deprecate the corresponding note so it cannot be mistaken as current guidance.
|
||||
- Keep notes concise and accurate; they are meant to prevent repeated rediscovery.
|
||||
|
||||
## Skill Index
|
||||
|
||||
Start with the section that best matches your need. Each entry lists the problems it solves plus key files/concepts so you know what to expect before opening it.
|
||||
|
||||
______________________________________________________________________
|
||||
### Platform Foundations
|
||||
|
||||
## Platform Foundations
|
||||
|
||||
- **[Infrastructure Overview](agent_skills/infra.md)**\
|
||||
When to read this:
|
||||
#### [Infrastructure Overview](agent_skills/infra.md)
|
||||
|
||||
- **When to read this**
|
||||
- You need to understand where a feature belongs in the architecture.
|
||||
- You’re wiring storage, Redis, vector stores, or OTEL.
|
||||
- You’re about to add CLI commands or async jobs.\
|
||||
What it covers: configuration stack (`configs/app_config.py`, remote settings), storage entry points (`extensions/ext_storage.py`, `core/file/file_manager.py`), Redis conventions (`extensions/ext_redis.py`), plugin runtime topology, vector-store factory (`core/rag/datasource/vdb/*`), observability hooks, SSRF proxy usage, and core CLI commands.
|
||||
- You’re about to add CLI commands or async jobs.
|
||||
- **What it covers**
|
||||
- Configuration stack (`configs/app_config.py`, remote settings)
|
||||
- Storage entry points (`extensions/ext_storage.py`, `core/file/file_manager.py`)
|
||||
- Redis conventions (`extensions/ext_redis.py`)
|
||||
- Plugin runtime topology
|
||||
- Vector-store factory (`core/rag/datasource/vdb/*`)
|
||||
- Observability hooks
|
||||
- SSRF proxy usage
|
||||
- Core CLI commands
|
||||
|
||||
- **[Coding Style](agent_skills/coding_style.md)**\
|
||||
When to read this:
|
||||
### Plugin & Extension Development
|
||||
|
||||
- You’re writing or reviewing backend code and need the authoritative checklist.
|
||||
- You’re unsure about Pydantic validators, SQLAlchemy session usage, or logging patterns.
|
||||
- You want the exact lint/type/test commands used in PRs.\
|
||||
Includes: Ruff & BasedPyright commands, no-annotation policy, session examples (`with Session(db.engine, ...)`), `@field_validator` usage, logging expectations, and the rule set for file size, helpers, and package management.
|
||||
|
||||
______________________________________________________________________
|
||||
|
||||
## Plugin & Extension Development
|
||||
|
||||
- **[Plugin Systems](agent_skills/plugin.md)**\
|
||||
When to read this:
|
||||
#### [Plugin Systems](agent_skills/plugin.md)
|
||||
|
||||
- **When to read this**
|
||||
- You’re building or debugging a marketplace plugin.
|
||||
- You need to know how manifests, providers, daemons, and migrations fit together.\
|
||||
What it covers: plugin manifests (`core/plugin/entities/plugin.py`), installation/upgrade flows (`services/plugin/plugin_service.py`, CLI commands), runtime adapters (`core/plugin/impl/*` for tool/model/datasource/trigger/endpoint/agent), daemon coordination (`core/plugin/entities/plugin_daemon.py`), and how provider registries surface capabilities to the rest of the platform.
|
||||
- You need to know how manifests, providers, daemons, and migrations fit together.
|
||||
- **What it covers**
|
||||
- Plugin manifests (`core/plugin/entities/plugin.py`)
|
||||
- Installation/upgrade flows (`services/plugin/plugin_service.py`, CLI commands)
|
||||
- Runtime adapters (`core/plugin/impl/*` for tool/model/datasource/trigger/endpoint/agent)
|
||||
- Daemon coordination (`core/plugin/entities/plugin_daemon.py`)
|
||||
- How provider registries surface capabilities to the rest of the platform
|
||||
|
||||
- **[Plugin OAuth](agent_skills/plugin_oauth.md)**\
|
||||
When to read this:
|
||||
#### [Plugin OAuth](agent_skills/plugin_oauth.md)
|
||||
|
||||
- **When to read this**
|
||||
- You must integrate OAuth for a plugin or datasource.
|
||||
- You’re handling credential encryption or refresh flows.\
|
||||
Topics: credential storage, encryption helpers (`core/helper/provider_encryption.py`), OAuth client bootstrap (`services/plugin/oauth_service.py`, `services/plugin/plugin_parameter_service.py`), and how console/API layers expose the flows.
|
||||
- You’re handling credential encryption or refresh flows.
|
||||
- **Topics**
|
||||
- Credential storage
|
||||
- Encryption helpers (`core/helper/provider_encryption.py`)
|
||||
- OAuth client bootstrap (`services/plugin/oauth_service.py`, `services/plugin/plugin_parameter_service.py`)
|
||||
- How console/API layers expose the flows
|
||||
|
||||
______________________________________________________________________
|
||||
### Workflow Entry & Execution
|
||||
|
||||
## Workflow Entry & Execution
|
||||
#### [Trigger Concepts](agent_skills/trigger.md)
|
||||
|
||||
- **[Trigger Concepts](agent_skills/trigger.md)**\
|
||||
When to read this:
|
||||
- **When to read this**
|
||||
- You’re debugging why a workflow didn’t start.
|
||||
- You’re adding a new trigger type or hook.
|
||||
- You need to trace async execution, draft debugging, or webhook/schedule pipelines.\
|
||||
Details: Start-node taxonomy, webhook & schedule internals (`core/workflow/nodes/trigger_*`, `services/trigger/*`), async orchestration (`services/async_workflow_service.py`, Celery queues), debug event bus, and storage/logging interactions.
|
||||
- You need to trace async execution, draft debugging, or webhook/schedule pipelines.
|
||||
- **Details**
|
||||
- Start-node taxonomy
|
||||
- Webhook & schedule internals (`core/workflow/nodes/trigger_*`, `services/trigger/*`)
|
||||
- Async orchestration (`services/async_workflow_service.py`, Celery queues)
|
||||
- Debug event bus
|
||||
- Storage/logging interactions
|
||||
|
||||
______________________________________________________________________
|
||||
## General Reminders
|
||||
|
||||
## Additional Notes for Agents
|
||||
|
||||
- All skill docs assume you follow the coding style guide—run Ruff/BasedPyright/tests listed there before submitting changes.
|
||||
- All skill docs assume you follow the coding style rules below—run the lint/type/test commands before submitting changes.
|
||||
- When you cannot find an answer in these briefs, search the codebase using the paths referenced (e.g., `core/plugin/impl/tool.py`, `services/dataset_service.py`).
|
||||
- If you run into cross-cutting concerns (tenancy, configuration, storage), check the infrastructure guide first; it links to most supporting modules.
|
||||
- Keep multi-tenancy and configuration central: everything flows through `configs.dify_config` and `tenant_id`.
|
||||
- When touching plugins or triggers, consult both the system overview and the specialised doc to ensure you adjust lifecycle, storage, and observability consistently.
|
||||
|
||||
## Coding Style
|
||||
|
||||
This is the default standard for backend code in this repo. Follow it for new code and use it as the checklist when reviewing changes.
|
||||
|
||||
### Linting & Formatting
|
||||
|
||||
- Use Ruff for formatting and linting (follow `.ruff.toml`).
|
||||
- Keep each line under 120 characters (including spaces).
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
- Use `snake_case` for variables and functions.
|
||||
- Use `PascalCase` for classes.
|
||||
- Use `UPPER_CASE` for constants.
|
||||
|
||||
### Typing & Class Layout
|
||||
|
||||
- Code should usually include type annotations that match the repo’s current Python version (avoid untyped public APIs and “mystery” values).
|
||||
- Prefer modern typing forms (e.g. `list[str]`, `dict[str, int]`) and avoid `Any` unless there’s a strong reason.
|
||||
- For classes, declare member variables at the top of the class body (before `__init__`) so the class shape is obvious at a glance:
|
||||
|
||||
```python
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class Example:
|
||||
user_id: str
|
||||
created_at: datetime
|
||||
|
||||
def __init__(self, user_id: str, created_at: datetime) -> None:
|
||||
self.user_id = user_id
|
||||
self.created_at = created_at
|
||||
```
|
||||
|
||||
### General Rules
|
||||
|
||||
- Use Pydantic v2 conventions.
|
||||
- Use `uv` for Python package management in this repo (usually with `--project api`).
|
||||
- Prefer simple functions over small “utility classes” for lightweight helpers.
|
||||
- Avoid implementing dunder methods unless it’s clearly needed and matches existing patterns.
|
||||
- Never start long-running services as part of agent work (`uv run app.py`, `flask run`, etc.); running tests is allowed.
|
||||
- Keep files below ~800 lines; split when necessary.
|
||||
- Keep code readable and explicit—avoid clever hacks.
|
||||
|
||||
### Architecture & Boundaries
|
||||
|
||||
- Mirror the layered architecture: controller → service → core/domain.
|
||||
- Reuse existing helpers in `core/`, `services/`, and `libs/` before creating new abstractions.
|
||||
- Optimise for observability: deterministic control flow, clear logging, actionable errors.
|
||||
|
||||
### Logging & Errors
|
||||
|
||||
- Never use `print`; use a module-level logger:
|
||||
- `logger = logging.getLogger(__name__)`
|
||||
- Include tenant/app/workflow identifiers in log context when relevant.
|
||||
- Raise domain-specific exceptions (`services/errors`, `core/errors`) and translate them into HTTP responses in controllers.
|
||||
- Log retryable events at `warning`, terminal failures at `error`.
|
||||
|
||||
### SQLAlchemy Patterns
|
||||
|
||||
- Models inherit from `models.base.TypeBase`; do not create ad-hoc metadata or engines.
|
||||
- Open sessions with context managers:
|
||||
|
||||
```python
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
with Session(db.engine, expire_on_commit=False) as session:
|
||||
stmt = select(Workflow).where(
|
||||
Workflow.id == workflow_id,
|
||||
Workflow.tenant_id == tenant_id,
|
||||
)
|
||||
workflow = session.execute(stmt).scalar_one_or_none()
|
||||
```
|
||||
|
||||
- Prefer SQLAlchemy expressions; avoid raw SQL unless necessary.
|
||||
- Always scope queries by `tenant_id` and protect write paths with safeguards (`FOR UPDATE`, row counts, etc.).
|
||||
- Introduce repository abstractions only for very large tables (e.g., workflow executions) or when alternative storage strategies are required.
|
||||
|
||||
### Storage & External I/O
|
||||
|
||||
- Access storage via `extensions.ext_storage.storage`.
|
||||
- Use `core.helper.ssrf_proxy` for outbound HTTP fetches.
|
||||
- Background tasks that touch storage must be idempotent, and should log relevant object identifiers.
|
||||
|
||||
### Pydantic Usage
|
||||
|
||||
- Define DTOs with Pydantic v2 models and forbid extras by default.
|
||||
- Use `@field_validator` / `@model_validator` for domain rules.
|
||||
|
||||
Example:
|
||||
|
||||
```python
|
||||
from pydantic import BaseModel, ConfigDict, HttpUrl, field_validator
|
||||
|
||||
|
||||
class TriggerConfig(BaseModel):
|
||||
endpoint: HttpUrl
|
||||
secret: str
|
||||
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
@field_validator("secret")
|
||||
def ensure_secret_prefix(cls, value: str) -> str:
|
||||
if not value.startswith("dify_"):
|
||||
raise ValueError("secret must start with dify_")
|
||||
return value
|
||||
```
|
||||
|
||||
### Generics & Protocols
|
||||
|
||||
- Use `typing.Protocol` to define behavioural contracts (e.g., cache interfaces).
|
||||
- Apply generics (`TypeVar`, `Generic`) for reusable utilities like caches or providers.
|
||||
- Validate dynamic inputs at runtime when generics cannot enforce safety alone.
|
||||
|
||||
### Tooling & Checks
|
||||
|
||||
Quick checks while iterating:
|
||||
|
||||
- Format: `make format`
|
||||
- Lint (includes auto-fix): `make lint`
|
||||
- Type check: `make type-check`
|
||||
- Targeted tests: `make test TARGET_TESTS=./api/tests/<target_tests>`
|
||||
|
||||
Before opening a PR / submitting:
|
||||
|
||||
- `make lint`
|
||||
- `make type-check`
|
||||
- `make test`
|
||||
|
||||
### Controllers & Services
|
||||
|
||||
- Controllers: parse input via Pydantic, invoke services, return serialised responses; no business logic.
|
||||
- Services: coordinate repositories, providers, background tasks; keep side effects explicit.
|
||||
- Document non-obvious behaviour with concise comments.
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- Use `configs.dify_config` for configuration—never read environment variables directly.
|
||||
- Maintain tenant awareness end-to-end; `tenant_id` must flow through every layer touching shared resources.
|
||||
- Queue async work through `services/async_workflow_service`; implement tasks under `tasks/` with explicit queue selection.
|
||||
- Keep experimental scripts under `dev/`; do not ship them in production builds.
|
||||
|
|
|
|||
|
|
@ -1,115 +0,0 @@
|
|||
## Linter
|
||||
|
||||
- Always follow `.ruff.toml`.
|
||||
- Run `uv run ruff check --fix --unsafe-fixes`.
|
||||
- Keep each line under 100 characters (including spaces).
|
||||
|
||||
## Code Style
|
||||
|
||||
- `snake_case` for variables and functions.
|
||||
- `PascalCase` for classes.
|
||||
- `UPPER_CASE` for constants.
|
||||
|
||||
## Rules
|
||||
|
||||
- Use Pydantic v2 standard.
|
||||
- Use `uv` for package management.
|
||||
- Do not override dunder methods like `__init__`, `__iadd__`, etc.
|
||||
- Never launch services (`uv run app.py`, `flask run`, etc.); running tests under `tests/` is allowed.
|
||||
- Prefer simple functions over classes for lightweight helpers.
|
||||
- Keep files below 800 lines; split when necessary.
|
||||
- Keep code readable—no clever hacks.
|
||||
- Never use `print`; log with `logger = logging.getLogger(__name__)`.
|
||||
|
||||
## Guiding Principles
|
||||
|
||||
- Mirror the project’s layered architecture: controller → service → core/domain.
|
||||
- Reuse existing helpers in `core/`, `services/`, and `libs/` before creating new abstractions.
|
||||
- Optimise for observability: deterministic control flow, clear logging, actionable errors.
|
||||
|
||||
## SQLAlchemy Patterns
|
||||
|
||||
- Models inherit from `models.base.Base`; never create ad-hoc metadata or engines.
|
||||
|
||||
- Open sessions with context managers:
|
||||
|
||||
```python
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
with Session(db.engine, expire_on_commit=False) as session:
|
||||
stmt = select(Workflow).where(
|
||||
Workflow.id == workflow_id,
|
||||
Workflow.tenant_id == tenant_id,
|
||||
)
|
||||
workflow = session.execute(stmt).scalar_one_or_none()
|
||||
```
|
||||
|
||||
- Use SQLAlchemy expressions; avoid raw SQL unless necessary.
|
||||
|
||||
- Introduce repository abstractions only for very large tables (e.g., workflow executions) to support alternative storage strategies.
|
||||
|
||||
- Always scope queries by `tenant_id` and protect write paths with safeguards (`FOR UPDATE`, row counts, etc.).
|
||||
|
||||
## Storage & External IO
|
||||
|
||||
- Access storage via `extensions.ext_storage.storage`.
|
||||
- Use `core.helper.ssrf_proxy` for outbound HTTP fetches.
|
||||
- Background tasks that touch storage must be idempotent and log the relevant object identifiers.
|
||||
|
||||
## Pydantic Usage
|
||||
|
||||
- Define DTOs with Pydantic v2 models and forbid extras by default.
|
||||
|
||||
- Use `@field_validator` / `@model_validator` for domain rules.
|
||||
|
||||
- Example:
|
||||
|
||||
```python
|
||||
from pydantic import BaseModel, ConfigDict, HttpUrl, field_validator
|
||||
|
||||
class TriggerConfig(BaseModel):
|
||||
endpoint: HttpUrl
|
||||
secret: str
|
||||
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
@field_validator("secret")
|
||||
def ensure_secret_prefix(cls, value: str) -> str:
|
||||
if not value.startswith("dify_"):
|
||||
raise ValueError("secret must start with dify_")
|
||||
return value
|
||||
```
|
||||
|
||||
## Generics & Protocols
|
||||
|
||||
- Use `typing.Protocol` to define behavioural contracts (e.g., cache interfaces).
|
||||
- Apply generics (`TypeVar`, `Generic`) for reusable utilities like caches or providers.
|
||||
- Validate dynamic inputs at runtime when generics cannot enforce safety alone.
|
||||
|
||||
## Error Handling & Logging
|
||||
|
||||
- Raise domain-specific exceptions (`services/errors`, `core/errors`) and translate to HTTP responses in controllers.
|
||||
- Declare `logger = logging.getLogger(__name__)` at module top.
|
||||
- Include tenant/app/workflow identifiers in log context.
|
||||
- Log retryable events at `warning`, terminal failures at `error`.
|
||||
|
||||
## Tooling & Checks
|
||||
|
||||
- Format/lint: `uv run --project api --dev ruff format ./api` and `uv run --project api --dev ruff check --fix --unsafe-fixes ./api`.
|
||||
- Type checks: `uv run --directory api --dev basedpyright`.
|
||||
- Tests: `uv run --project api --dev dev/pytest/pytest_unit_tests.sh`.
|
||||
- Run all of the above before submitting your work.
|
||||
|
||||
## Controllers & Services
|
||||
|
||||
- Controllers: parse input via Pydantic, invoke services, return serialised responses; no business logic.
|
||||
- Services: coordinate repositories, providers, background tasks; keep side effects explicit.
|
||||
- Avoid repositories unless necessary; direct SQLAlchemy usage is preferred for typical tables.
|
||||
- Document non-obvious behaviour with concise comments.
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
- Use `configs.dify_config` for configuration—never read environment variables directly.
|
||||
- Maintain tenant awareness end-to-end; `tenant_id` must flow through every layer touching shared resources.
|
||||
- Queue async work through `services/async_workflow_service`; implement tasks under `tasks/` with explicit queue selection.
|
||||
- Keep experimental scripts under `dev/`; do not ship them in production builds.
|
||||
|
|
@ -30,6 +30,11 @@ class TagBindingRemovePayload(BaseModel):
|
|||
type: Literal["knowledge", "app"] | None = Field(default=None, description="Tag type")
|
||||
|
||||
|
||||
class TagListQueryParam(BaseModel):
|
||||
type: Literal["knowledge", "app", ""] = Field("", description="Tag type filter")
|
||||
keyword: str | None = Field(None, description="Search keyword")
|
||||
|
||||
|
||||
register_schema_models(
|
||||
console_ns,
|
||||
TagBasePayload,
|
||||
|
|
@ -43,12 +48,15 @@ class TagListApi(Resource):
|
|||
@setup_required
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
@console_ns.doc(
|
||||
params={"type": 'Tag type filter. Can be "knowledge" or "app".', "keyword": "Search keyword for tag name."}
|
||||
)
|
||||
@marshal_with(dataset_tag_fields)
|
||||
def get(self):
|
||||
_, current_tenant_id = current_account_with_tenant()
|
||||
tag_type = request.args.get("type", type=str, default="")
|
||||
keyword = request.args.get("keyword", default=None, type=str)
|
||||
tags = TagService.get_tags(tag_type, current_tenant_id, keyword)
|
||||
raw_args = request.args.to_dict()
|
||||
param = TagListQueryParam.model_validate(raw_args)
|
||||
tags = TagService.get_tags(param.type, current_tenant_id, param.keyword)
|
||||
|
||||
return tags, 200
|
||||
|
||||
|
|
|
|||
|
|
@ -71,8 +71,8 @@ class LLMGenerator:
|
|||
response: LLMResult = model_instance.invoke_llm(
|
||||
prompt_messages=list(prompts), model_parameters={"max_tokens": 500, "temperature": 1}, stream=False
|
||||
)
|
||||
answer = cast(str, response.message.content)
|
||||
if answer is None:
|
||||
answer = response.message.get_text_content()
|
||||
if answer == "":
|
||||
return ""
|
||||
try:
|
||||
result_dict = json.loads(answer)
|
||||
|
|
@ -184,7 +184,7 @@ class LLMGenerator:
|
|||
prompt_messages=list(prompt_messages), model_parameters=model_parameters, stream=False
|
||||
)
|
||||
|
||||
rule_config["prompt"] = cast(str, response.message.content)
|
||||
rule_config["prompt"] = response.message.get_text_content()
|
||||
|
||||
except InvokeError as e:
|
||||
error = str(e)
|
||||
|
|
@ -237,13 +237,11 @@ class LLMGenerator:
|
|||
|
||||
return rule_config
|
||||
|
||||
rule_config["prompt"] = cast(str, prompt_content.message.content)
|
||||
rule_config["prompt"] = prompt_content.message.get_text_content()
|
||||
|
||||
if not isinstance(prompt_content.message.content, str):
|
||||
raise NotImplementedError("prompt content is not a string")
|
||||
parameter_generate_prompt = parameter_template.format(
|
||||
inputs={
|
||||
"INPUT_TEXT": prompt_content.message.content,
|
||||
"INPUT_TEXT": prompt_content.message.get_text_content(),
|
||||
},
|
||||
remove_template_variables=False,
|
||||
)
|
||||
|
|
@ -253,7 +251,7 @@ class LLMGenerator:
|
|||
statement_generate_prompt = statement_template.format(
|
||||
inputs={
|
||||
"TASK_DESCRIPTION": instruction,
|
||||
"INPUT_TEXT": prompt_content.message.content,
|
||||
"INPUT_TEXT": prompt_content.message.get_text_content(),
|
||||
},
|
||||
remove_template_variables=False,
|
||||
)
|
||||
|
|
@ -263,7 +261,7 @@ class LLMGenerator:
|
|||
parameter_content: LLMResult = model_instance.invoke_llm(
|
||||
prompt_messages=list(parameter_messages), model_parameters=model_parameters, stream=False
|
||||
)
|
||||
rule_config["variables"] = re.findall(r'"\s*([^"]+)\s*"', cast(str, parameter_content.message.content))
|
||||
rule_config["variables"] = re.findall(r'"\s*([^"]+)\s*"', parameter_content.message.get_text_content())
|
||||
except InvokeError as e:
|
||||
error = str(e)
|
||||
error_step = "generate variables"
|
||||
|
|
@ -272,7 +270,7 @@ class LLMGenerator:
|
|||
statement_content: LLMResult = model_instance.invoke_llm(
|
||||
prompt_messages=list(statement_messages), model_parameters=model_parameters, stream=False
|
||||
)
|
||||
rule_config["opening_statement"] = cast(str, statement_content.message.content)
|
||||
rule_config["opening_statement"] = statement_content.message.get_text_content()
|
||||
except InvokeError as e:
|
||||
error = str(e)
|
||||
error_step = "generate conversation opener"
|
||||
|
|
@ -315,7 +313,7 @@ class LLMGenerator:
|
|||
prompt_messages=list(prompt_messages), model_parameters=model_parameters, stream=False
|
||||
)
|
||||
|
||||
generated_code = cast(str, response.message.content)
|
||||
generated_code = response.message.get_text_content()
|
||||
return {"code": generated_code, "language": code_language, "error": ""}
|
||||
|
||||
except InvokeError as e:
|
||||
|
|
@ -351,7 +349,7 @@ class LLMGenerator:
|
|||
raise TypeError("Expected LLMResult when stream=False")
|
||||
response = result
|
||||
|
||||
answer = cast(str, response.message.content)
|
||||
answer = response.message.get_text_content()
|
||||
return answer.strip()
|
||||
|
||||
@classmethod
|
||||
|
|
@ -375,10 +373,7 @@ class LLMGenerator:
|
|||
prompt_messages=list(prompt_messages), model_parameters=model_parameters, stream=False
|
||||
)
|
||||
|
||||
raw_content = response.message.content
|
||||
|
||||
if not isinstance(raw_content, str):
|
||||
raise ValueError(f"LLM response content must be a string, got: {type(raw_content)}")
|
||||
raw_content = response.message.get_text_content()
|
||||
|
||||
try:
|
||||
parsed_content = json.loads(raw_content)
|
||||
|
|
|
|||
|
|
@ -67,15 +67,17 @@ const CardView: FC<ICardViewProps> = ({ appId, isInPanel, className }) => {
|
|||
<div className="text-xs text-text-secondary">
|
||||
{t('overview.disableTooltip.triggerMode', { ns: 'appOverview', feature: featureName })}
|
||||
</div>
|
||||
<div
|
||||
className="cursor-pointer text-xs font-medium text-text-accent hover:underline"
|
||||
<a
|
||||
href={triggerDocUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block cursor-pointer text-xs font-medium text-text-accent hover:underline"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation()
|
||||
window.open(triggerDocUrl, '_blank')
|
||||
}}
|
||||
>
|
||||
{t('overview.appInfo.enableTooltip.learnMore', { ns: 'appOverview' })}
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
), [t, triggerDocUrl])
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ const SearchInput: FC<SearchInputProps> = ({
|
|||
white,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const inputRef = useRef<HTMLInputElement>(null)
|
||||
const [focus, setFocus] = useState<boolean>(false)
|
||||
const isComposing = useRef<boolean>(false)
|
||||
const [compositionValue, setCompositionValue] = useState<string>('')
|
||||
|
|
@ -36,6 +37,7 @@ const SearchInput: FC<SearchInputProps> = ({
|
|||
<RiSearchLine className="h-4 w-4 text-components-input-text-placeholder" aria-hidden="true" />
|
||||
</div>
|
||||
<input
|
||||
ref={inputRef}
|
||||
type="text"
|
||||
name="query"
|
||||
className={cn(
|
||||
|
|
@ -65,14 +67,17 @@ const SearchInput: FC<SearchInputProps> = ({
|
|||
autoComplete="off"
|
||||
/>
|
||||
{value && (
|
||||
<div
|
||||
className="group/clear flex h-4 w-4 shrink-0 cursor-pointer items-center justify-center"
|
||||
<button
|
||||
type="button"
|
||||
aria-label={t('operation.clear', { ns: 'common' })}
|
||||
className="group/clear flex h-4 w-4 shrink-0 cursor-pointer items-center justify-center border-none bg-transparent p-0"
|
||||
onClick={() => {
|
||||
onChange('')
|
||||
inputRef.current?.focus()
|
||||
}}
|
||||
>
|
||||
<RiCloseCircleFill className="h-4 w-4 text-text-quaternary group-hover/clear:text-text-tertiary" />
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -442,6 +442,10 @@ const Completed: FC<ICompletedProps> = ({
|
|||
setFullScreen(!fullScreen)
|
||||
}, [fullScreen])
|
||||
|
||||
const toggleCollapsed = useCallback(() => {
|
||||
setIsCollapsed(prev => !prev)
|
||||
}, [])
|
||||
|
||||
const viewNewlyAddedChunk = useCallback(async () => {
|
||||
const totalPages = segmentListData?.total_pages || 0
|
||||
const total = segmentListData?.total || 0
|
||||
|
|
@ -578,15 +582,16 @@ const Completed: FC<ICompletedProps> = ({
|
|||
return selectedStatus ? 1 : 0
|
||||
}, [selectedStatus])
|
||||
|
||||
const contextValue = useMemo<SegmentListContextValue>(() => ({
|
||||
isCollapsed,
|
||||
fullScreen,
|
||||
toggleFullScreen,
|
||||
currSegment,
|
||||
currChildChunk,
|
||||
}), [isCollapsed, fullScreen, toggleFullScreen, currSegment, currChildChunk])
|
||||
|
||||
return (
|
||||
<SegmentListContext.Provider value={{
|
||||
isCollapsed,
|
||||
fullScreen,
|
||||
toggleFullScreen,
|
||||
currSegment,
|
||||
currChildChunk,
|
||||
}}
|
||||
>
|
||||
<SegmentListContext.Provider value={contextValue}>
|
||||
{/* Menu Bar */}
|
||||
{!isFullDocMode && (
|
||||
<div className={s.docSearchWrapper}>
|
||||
|
|
@ -618,7 +623,7 @@ const Completed: FC<ICompletedProps> = ({
|
|||
onClear={() => handleInputChange('')}
|
||||
/>
|
||||
<Divider type="vertical" className="mx-3 h-3.5" />
|
||||
<DisplayToggle isCollapsed={isCollapsed} toggleCollapsed={() => setIsCollapsed(!isCollapsed)} />
|
||||
<DisplayToggle isCollapsed={isCollapsed} toggleCollapsed={toggleCollapsed} />
|
||||
</div>
|
||||
)}
|
||||
{/* Segment list */}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import type { FC } from 'react'
|
||||
import type { SegmentListContextValue } from '..'
|
||||
import * as React from 'react'
|
||||
import { Markdown } from '@/app/components/base/markdown'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
|
@ -14,13 +15,15 @@ type ChunkContentProps = {
|
|||
className?: string
|
||||
}
|
||||
|
||||
const selectIsCollapsed = (s: SegmentListContextValue) => s.isCollapsed
|
||||
|
||||
const ChunkContent: FC<ChunkContentProps> = ({
|
||||
detail,
|
||||
isFullDocMode,
|
||||
className,
|
||||
}) => {
|
||||
const { answer, content, sign_content } = detail
|
||||
const isCollapsed = useSegmentListContext(s => s.isCollapsed)
|
||||
const isCollapsed = useSegmentListContext(selectIsCollapsed)
|
||||
|
||||
if (answer) {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import type { NodeOutPutVar, Variable } from '@/app/components/workflow/types'
|
|||
import { useBoolean } from 'ahooks'
|
||||
import * as React from 'react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { createPortal } from 'react-dom'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import VarReferenceVars from '@/app/components/workflow/nodes/_base/components/variable/var-reference-vars'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
|
@ -147,7 +148,7 @@ const CodeEditor: FC<Props> = ({
|
|||
onMount={onEditorMounted}
|
||||
placeholder={t('common.jinjaEditorPlaceholder', { ns: 'workflow' })!}
|
||||
/>
|
||||
{isShowVarPicker && (
|
||||
{isShowVarPicker && createPortal(
|
||||
<div
|
||||
ref={popupRef}
|
||||
className="w-[228px] space-y-1 rounded-lg border border-components-panel-border bg-components-panel-bg p-1 shadow-lg"
|
||||
|
|
@ -164,7 +165,8 @@ const CodeEditor: FC<Props> = ({
|
|||
onChange={handleSelectVar}
|
||||
isSupportFileVar={false}
|
||||
/>
|
||||
</div>
|
||||
</div>,
|
||||
document.body,
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@ export default antfu(
|
|||
'react-hooks/preserve-manual-memoization': 'warn',
|
||||
'react-hooks/purity': 'warn',
|
||||
'react-hooks/refs': 'warn',
|
||||
'react-hooks/set-state-in-effect': 'warn',
|
||||
// prefer react-hooks-extra/no-direct-set-state-in-use-effect
|
||||
'react-hooks/set-state-in-effect': 'off',
|
||||
'react-hooks/set-state-in-render': 'warn',
|
||||
'react-hooks/static-components': 'warn',
|
||||
'react-hooks/unsupported-syntax': 'warn',
|
||||
|
|
@ -53,6 +54,14 @@ export default antfu(
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.ts', '**/*.tsx'],
|
||||
settings: {
|
||||
'react-x': {
|
||||
additionalStateHooks: '/^use\\w*State(?:s)?|useAtom$/u',
|
||||
},
|
||||
},
|
||||
},
|
||||
// downgrade some rules from error to warn for gradual adoption
|
||||
// we should fix these in following pull requests
|
||||
{
|
||||
|
|
|
|||
|
|
@ -155,9 +155,9 @@
|
|||
"zustand": "^5.0.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^6.7.3",
|
||||
"@antfu/eslint-config": "^7.0.1",
|
||||
"@chromatic-com/storybook": "^4.1.1",
|
||||
"@eslint-react/eslint-plugin": "^2.3.13",
|
||||
"@eslint-react/eslint-plugin": "^2.7.0",
|
||||
"@mdx-js/loader": "^3.1.1",
|
||||
"@mdx-js/react": "^3.1.1",
|
||||
"@next/bundle-analyzer": "15.5.9",
|
||||
|
|
@ -192,7 +192,7 @@
|
|||
"@types/semver": "^7.7.1",
|
||||
"@types/sortablejs": "^1.15.8",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@typescript-eslint/parser": "^8.50.0",
|
||||
"@typescript-eslint/parser": "^8.53.0",
|
||||
"@typescript/native-preview": "^7.0.0-dev",
|
||||
"@vitejs/plugin-react": "^5.1.2",
|
||||
"@vitest/coverage-v8": "4.0.16",
|
||||
|
|
@ -204,7 +204,7 @@
|
|||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"eslint-plugin-react-refresh": "^0.4.26",
|
||||
"eslint-plugin-sonarjs": "^3.0.5",
|
||||
"eslint-plugin-storybook": "^10.1.10",
|
||||
"eslint-plugin-storybook": "^10.1.11",
|
||||
"eslint-plugin-tailwindcss": "^3.18.2",
|
||||
"husky": "^9.1.7",
|
||||
"jsdom": "^27.3.0",
|
||||
|
|
@ -227,7 +227,6 @@
|
|||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"@eslint/plugin-kit@<0.3.4": "0.3.4",
|
||||
"@monaco-editor/loader": "1.5.0",
|
||||
"@nolyfill/safe-buffer": "npm:safe-buffer@^5.2.1",
|
||||
"array-includes": "npm:@nolyfill/array-includes@^1",
|
||||
|
|
@ -278,7 +277,6 @@
|
|||
]
|
||||
},
|
||||
"resolutions": {
|
||||
"@eslint/plugin-kit": "~0.3",
|
||||
"@types/react": "~19.2.7",
|
||||
"@types/react-dom": "~19.2.3",
|
||||
"brace-expansion": "~2.0",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ settings:
|
|||
excludeLinksFromLockfile: false
|
||||
|
||||
overrides:
|
||||
'@eslint/plugin-kit': ~0.3
|
||||
'@types/react': ~19.2.7
|
||||
'@types/react-dom': ~19.2.3
|
||||
brace-expansion: ~2.0
|
||||
|
|
@ -13,7 +12,6 @@ overrides:
|
|||
pbkdf2: ~3.1.3
|
||||
prismjs: ~1.30
|
||||
string-width: ~4.2.3
|
||||
'@eslint/plugin-kit@<0.3.4': 0.3.4
|
||||
'@monaco-editor/loader': 1.5.0
|
||||
'@nolyfill/safe-buffer': npm:safe-buffer@^5.2.1
|
||||
array-includes: npm:@nolyfill/array-includes@^1
|
||||
|
|
@ -368,13 +366,13 @@ importers:
|
|||
version: 5.0.10(@types/react@19.2.8)(immer@11.1.3)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))
|
||||
devDependencies:
|
||||
'@antfu/eslint-config':
|
||||
specifier: ^6.7.3
|
||||
version: 6.7.3(@eslint-react/eslint-plugin@2.7.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(@next/eslint-plugin-next@15.5.9)(@vue/compiler-sfc@3.5.17)(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.8)(jiti@1.21.7)(jsdom@27.4.0(canvas@3.2.0))(sass@1.93.2)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.2))
|
||||
specifier: ^7.0.1
|
||||
version: 7.0.1(@eslint-react/eslint-plugin@2.7.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(@next/eslint-plugin-next@15.5.9)(@vue/compiler-sfc@3.5.17)(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.8)(jiti@1.21.7)(jsdom@27.4.0(canvas@3.2.0))(sass@1.93.2)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.2))
|
||||
'@chromatic-com/storybook':
|
||||
specifier: ^4.1.1
|
||||
version: 4.1.1(storybook@9.1.17(@testing-library/dom@10.4.1)(vite@7.3.1(@types/node@18.15.0)(jiti@1.21.7)(sass@1.93.2)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.2)))
|
||||
'@eslint-react/eslint-plugin':
|
||||
specifier: ^2.3.13
|
||||
specifier: ^2.7.0
|
||||
version: 2.7.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
|
||||
'@mdx-js/loader':
|
||||
specifier: ^3.1.1
|
||||
|
|
@ -479,7 +477,7 @@ importers:
|
|||
specifier: ^10.0.0
|
||||
version: 10.0.0
|
||||
'@typescript-eslint/parser':
|
||||
specifier: ^8.50.0
|
||||
specifier: ^8.53.0
|
||||
version: 8.53.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
|
||||
'@typescript/native-preview':
|
||||
specifier: ^7.0.0-dev
|
||||
|
|
@ -515,7 +513,7 @@ importers:
|
|||
specifier: ^3.0.5
|
||||
version: 3.0.5(eslint@9.39.2(jiti@1.21.7))
|
||||
eslint-plugin-storybook:
|
||||
specifier: ^10.1.10
|
||||
specifier: ^10.1.11
|
||||
version: 10.1.11(eslint@9.39.2(jiti@1.21.7))(storybook@9.1.17(@testing-library/dom@10.4.1)(vite@7.3.1(@types/node@18.15.0)(jiti@1.21.7)(sass@1.93.2)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3)
|
||||
eslint-plugin-tailwindcss:
|
||||
specifier: ^3.18.2
|
||||
|
|
@ -655,8 +653,8 @@ packages:
|
|||
'@amplitude/targeting@0.2.0':
|
||||
resolution: {integrity: sha512-/50ywTrC4hfcfJVBbh5DFbqMPPfaIOivZeb5Gb+OGM03QrA+lsUqdvtnKLNuWtceD4H6QQ2KFzPJ5aAJLyzVDA==}
|
||||
|
||||
'@antfu/eslint-config@6.7.3':
|
||||
resolution: {integrity: sha512-0tYYzY59uLnxWgbP9xpuxpvodTcWDacj439kTAJZB3sn7O0BnPfVxTnRvleGYaKCEALBZkzdC/wCho9FD7ICLw==}
|
||||
'@antfu/eslint-config@7.0.1':
|
||||
resolution: {integrity: sha512-QbCDrLPo2Bpn9/W5PnpGvUuD/EIKhiCmLBuIj9ylxeMvl47XSkXy3MZyinqUVsBJzk196B7BcJQByDZRr5TbZQ==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@eslint-react/eslint-plugin': ^2.0.1
|
||||
|
|
@ -1482,6 +1480,10 @@ 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==}
|
||||
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
|
||||
|
||||
'@es-joy/resolve.exports@1.2.0':
|
||||
resolution: {integrity: sha512-Q9hjxWI5xBM+qW2enxfe8wDKdFWMfd0Z29k5ZJnuBqD/CasY5Zryj09aCA6owbGATWz+39p5uIdaHXpopOcG8g==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
@ -1642,8 +1644,8 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@eslint-community/eslint-plugin-eslint-comments@4.5.0':
|
||||
resolution: {integrity: sha512-MAhuTKlr4y/CE3WYX26raZjy+I/kS2PLKSzvfmDCGrBLTFHOYwqROZdr4XwPgXwX3K9rjzMr4pSmUWGnzsUyMg==}
|
||||
'@eslint-community/eslint-plugin-eslint-comments@4.6.0':
|
||||
resolution: {integrity: sha512-2EX2bBQq1ez++xz2o9tEeEQkyvfieWgUFMH4rtJJri2q0Azvhja3hZGXsjPXs31R4fQkZDtWzNDDK2zQn5UE5g==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0
|
||||
|
|
@ -1724,10 +1726,6 @@ packages:
|
|||
resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@eslint/core@0.15.2':
|
||||
resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@eslint/core@0.16.0':
|
||||
resolution: {integrity: sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
|
@ -1736,6 +1734,10 @@ packages:
|
|||
resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@eslint/core@1.0.1':
|
||||
resolution: {integrity: sha512-r18fEAj9uCk+VjzGt2thsbOmychS+4kxI14spVNibUO2vqKX7obOG+ymZljAwuPZl+S3clPGwCwTDtrdqTiY6Q==}
|
||||
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
|
||||
|
||||
'@eslint/eslintrc@3.3.1':
|
||||
resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
|
@ -1752,10 +1754,14 @@ packages:
|
|||
resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@eslint/plugin-kit@0.3.5':
|
||||
resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==}
|
||||
'@eslint/plugin-kit@0.4.1':
|
||||
resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@eslint/plugin-kit@0.5.1':
|
||||
resolution: {integrity: sha512-hZ2uC1jbf6JMSsF2ZklhRQqf6GLpYyux6DlzegnW/aFlpu6qJj5GO7ub7WOETCrEl6pl6DAX7RgTgj/fyG+6BQ==}
|
||||
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
|
||||
|
||||
'@exodus/bytes@1.8.0':
|
||||
resolution: {integrity: sha512-8JPn18Bcp8Uo1T82gR8lh2guEOa5KKU/IEKvvdp0sgmi7coPBWf1Doi1EXsGZb2ehc8ym/StJCjffYV+ne7sXQ==}
|
||||
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
|
||||
|
|
@ -5165,8 +5171,8 @@ packages:
|
|||
peerDependencies:
|
||||
eslint: '*'
|
||||
|
||||
eslint-plugin-antfu@3.1.1:
|
||||
resolution: {integrity: sha512-7Q+NhwLfHJFvopI2HBZbSxWXngTwBLKxW1AGXLr2lEGxcEIK/AsDs8pn8fvIizl5aZjBbVbVK5ujmMpBe4Tvdg==}
|
||||
eslint-plugin-antfu@3.1.3:
|
||||
resolution: {integrity: sha512-Az1QuqQJ/c2efWCxVxF249u3D4AcAu1Y3VCGAlJm+x4cgnn1ybUAnCT5DWVcogeaWduQKeVw07YFydVTOF4xDw==}
|
||||
peerDependencies:
|
||||
eslint: '*'
|
||||
|
||||
|
|
@ -5181,19 +5187,15 @@ packages:
|
|||
peerDependencies:
|
||||
eslint: '>=8'
|
||||
|
||||
eslint-plugin-import-lite@0.4.0:
|
||||
resolution: {integrity: sha512-My0ReAg8WbHXYECIHVJkWB8UxrinZn3m72yonOYH6MFj40ZN1vHYQj16iq2Fd8Wrt/vRZJwDX2xm/BzDk1FzTg==}
|
||||
eslint-plugin-import-lite@0.5.0:
|
||||
resolution: {integrity: sha512-7uBvxuQj+VlYmZSYSHcm33QgmZnvMLP2nQiWaLtjhJ5x1zKcskOqjolL+dJC13XY+ktQqBgidAnnQMELfRaXQg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: '>=9.0.0'
|
||||
typescript: '>=4.5'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
eslint-plugin-jsdoc@61.7.1:
|
||||
resolution: {integrity: sha512-36DpldF95MlTX//n3/naULFVt8d1cV4jmSkx7ZKrE9ikkKHAgMLesuWp1SmwpVwAs5ndIM6abKd6PeOYZUgdWg==}
|
||||
engines: {node: '>=20.11.0'}
|
||||
eslint-plugin-jsdoc@62.0.0:
|
||||
resolution: {integrity: sha512-sNdIGLAvjFK3pB0SYFW74iXODZ4ifF8Ax13Wgq8jKepKnrCFzGo7+jRZfLf70h81SD7lPYnTE7MR2nhYSvaLTA==}
|
||||
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
|
||||
peerDependencies:
|
||||
eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
|
||||
|
||||
|
|
@ -5203,8 +5205,8 @@ packages:
|
|||
peerDependencies:
|
||||
eslint: '>=6.0.0'
|
||||
|
||||
eslint-plugin-n@17.23.1:
|
||||
resolution: {integrity: sha512-68PealUpYoHOBh332JLLD9Sj7OQUDkFpmcfqt8R9sySfFSeuGJjMTJQvCRRB96zO3A/PELRLkPrzsHmzEFQQ5A==}
|
||||
eslint-plugin-n@17.23.2:
|
||||
resolution: {integrity: sha512-RhWBeb7YVPmNa2eggvJooiuehdL76/bbfj/OJewyoGT80qn5PXdz8zMOTO6YHOsI7byPt7+Ighh/i/4a5/v7hw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: '>=8.23.0'
|
||||
|
|
@ -5213,9 +5215,9 @@ packages:
|
|||
resolution: {integrity: sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==}
|
||||
engines: {node: '>=5.0.0'}
|
||||
|
||||
eslint-plugin-perfectionist@4.15.1:
|
||||
resolution: {integrity: sha512-MHF0cBoOG0XyBf7G0EAFCuJJu4I18wy0zAoT1OHfx2o6EOx1EFTIzr2HGeuZa1kDcusoX0xJ9V7oZmaeFd773Q==}
|
||||
engines: {node: ^18.0.0 || >=20.0.0}
|
||||
eslint-plugin-perfectionist@5.3.1:
|
||||
resolution: {integrity: sha512-v8kAP8TarQYqDC4kxr343ZNi++/oOlBnmWovsUZpbJ7A/pq1VHGlgsf/fDh4CdEvEstzkrc8NLvoVKtfpsC4oA==}
|
||||
engines: {node: ^20.0.0 || >=22.0.0}
|
||||
peerDependencies:
|
||||
eslint: '>=8.45.0'
|
||||
|
||||
|
|
@ -5293,11 +5295,11 @@ packages:
|
|||
peerDependencies:
|
||||
tailwindcss: ^3.4.0
|
||||
|
||||
eslint-plugin-toml@0.12.0:
|
||||
resolution: {integrity: sha512-+/wVObA9DVhwZB1nG83D2OAQRrcQZXy+drqUnFJKymqnmbnbfg/UPmEMCKrJNcEboUGxUjYrJlgy+/Y930mURQ==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
eslint-plugin-toml@1.0.0:
|
||||
resolution: {integrity: sha512-ACotflJMZ9CKCZlc0nznBxRNbiOYcBqWmXUSoKsGf6cyDV7EN1kGoD/WKnMo/lEsIF0WnzaYXcOU1HBOoyxRrg==}
|
||||
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
|
||||
peerDependencies:
|
||||
eslint: '>=6.0.0'
|
||||
eslint: '>=9.38.0'
|
||||
|
||||
eslint-plugin-unicorn@62.0.0:
|
||||
resolution: {integrity: sha512-HIlIkGLkvf29YEiS/ImuDZQbP12gWyx5i3C6XrRxMvVdqMroCI9qoVYCoIl17ChN+U89pn9sVwLxhIWj5nEc7g==}
|
||||
|
|
@ -5681,6 +5683,10 @@ packages:
|
|||
resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
globals@17.0.0:
|
||||
resolution: {integrity: sha512-gv5BeD2EssA793rlFWVPMMCqefTlpusw6/2TbAVMy0FzcG8wKJn4O+NqJ4+XWmmwrayJgw5TzrmWjFgmz1XPqw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
globrex@0.1.2:
|
||||
resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==}
|
||||
|
||||
|
|
@ -8056,9 +8062,9 @@ packages:
|
|||
toggle-selection@1.0.6:
|
||||
resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==}
|
||||
|
||||
toml-eslint-parser@0.10.1:
|
||||
resolution: {integrity: sha512-9mjy3frhioGIVGcwamlVlUyJ9x+WHw/TXiz9R4YOlmsIuBN43r9Dp8HZ35SF9EKjHrn3BUZj04CF+YqZ2oJ+7w==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
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:
|
||||
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
|
||||
|
|
@ -8898,11 +8904,11 @@ snapshots:
|
|||
idb: 8.0.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@antfu/eslint-config@6.7.3(@eslint-react/eslint-plugin@2.7.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(@next/eslint-plugin-next@15.5.9)(@vue/compiler-sfc@3.5.17)(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.8)(jiti@1.21.7)(jsdom@27.4.0(canvas@3.2.0))(sass@1.93.2)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.2))':
|
||||
'@antfu/eslint-config@7.0.1(@eslint-react/eslint-plugin@2.7.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(@next/eslint-plugin-next@15.5.9)(@vue/compiler-sfc@3.5.17)(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.8)(jiti@1.21.7)(jsdom@27.4.0(canvas@3.2.0))(sass@1.93.2)(terser@5.44.0)(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.5.0(eslint@9.39.2(jiti@1.21.7))
|
||||
'@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)
|
||||
|
|
@ -8914,27 +8920,27 @@ snapshots:
|
|||
eslint-config-flat-gitignore: 2.1.0(eslint@9.39.2(jiti@1.21.7))
|
||||
eslint-flat-config-utils: 2.1.4
|
||||
eslint-merge-processors: 2.0.0(eslint@9.39.2(jiti@1.21.7))
|
||||
eslint-plugin-antfu: 3.1.1(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.4.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
|
||||
eslint-plugin-jsdoc: 61.7.1(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-jsonc: 2.21.0(eslint@9.39.2(jiti@1.21.7))
|
||||
eslint-plugin-n: 17.23.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
|
||||
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: 4.15.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
|
||||
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-regexp: 2.10.0(eslint@9.39.2(jiti@1.21.7))
|
||||
eslint-plugin-toml: 0.12.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-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.7.0(@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-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.17)(eslint@9.39.2(jiti@1.21.7))
|
||||
globals: 16.5.0
|
||||
globals: 17.0.0
|
||||
jsonc-eslint-parser: 2.4.2
|
||||
local-pkg: 1.1.2
|
||||
parse-gitignore: 2.0.0
|
||||
toml-eslint-parser: 0.10.1
|
||||
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
|
||||
optionalDependencies:
|
||||
|
|
@ -9987,7 +9993,15 @@ snapshots:
|
|||
'@types/estree': 1.0.8
|
||||
'@typescript-eslint/types': 8.53.0
|
||||
comment-parser: 1.4.1
|
||||
esquery: 1.6.0
|
||||
esquery: 1.7.0
|
||||
jsdoc-type-pratt-parser: 7.0.0
|
||||
|
||||
'@es-joy/jsdoccomment@0.79.0':
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
'@typescript-eslint/types': 8.53.0
|
||||
comment-parser: 1.4.1
|
||||
esquery: 1.7.0
|
||||
jsdoc-type-pratt-parser: 7.0.0
|
||||
|
||||
'@es-joy/resolve.exports@1.2.0': {}
|
||||
|
|
@ -10070,11 +10084,11 @@ snapshots:
|
|||
'@esbuild/win32-x64@0.27.2':
|
||||
optional: true
|
||||
|
||||
'@eslint-community/eslint-plugin-eslint-comments@4.5.0(eslint@9.39.2(jiti@1.21.7))':
|
||||
'@eslint-community/eslint-plugin-eslint-comments@4.6.0(eslint@9.39.2(jiti@1.21.7))':
|
||||
dependencies:
|
||||
escape-string-regexp: 4.0.0
|
||||
eslint: 9.39.2(jiti@1.21.7)
|
||||
ignore: 5.3.2
|
||||
ignore: 7.0.5
|
||||
|
||||
'@eslint-community/eslint-utils@4.9.0(eslint@9.39.2(jiti@1.21.7))':
|
||||
dependencies:
|
||||
|
|
@ -10181,10 +10195,6 @@ snapshots:
|
|||
dependencies:
|
||||
'@eslint/core': 0.17.0
|
||||
|
||||
'@eslint/core@0.15.2':
|
||||
dependencies:
|
||||
'@types/json-schema': 7.0.15
|
||||
|
||||
'@eslint/core@0.16.0':
|
||||
dependencies:
|
||||
'@types/json-schema': 7.0.15
|
||||
|
|
@ -10193,6 +10203,10 @@ snapshots:
|
|||
dependencies:
|
||||
'@types/json-schema': 7.0.15
|
||||
|
||||
'@eslint/core@1.0.1':
|
||||
dependencies:
|
||||
'@types/json-schema': 7.0.15
|
||||
|
||||
'@eslint/eslintrc@3.3.1':
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
|
|
@ -10212,7 +10226,7 @@ snapshots:
|
|||
'@eslint/markdown@7.5.1':
|
||||
dependencies:
|
||||
'@eslint/core': 0.17.0
|
||||
'@eslint/plugin-kit': 0.3.5
|
||||
'@eslint/plugin-kit': 0.4.1
|
||||
github-slugger: 2.0.0
|
||||
mdast-util-from-markdown: 2.0.2
|
||||
mdast-util-frontmatter: 2.0.1
|
||||
|
|
@ -10225,9 +10239,14 @@ snapshots:
|
|||
|
||||
'@eslint/object-schema@2.1.7': {}
|
||||
|
||||
'@eslint/plugin-kit@0.3.5':
|
||||
'@eslint/plugin-kit@0.4.1':
|
||||
dependencies:
|
||||
'@eslint/core': 0.15.2
|
||||
'@eslint/core': 0.17.0
|
||||
levn: 0.4.1
|
||||
|
||||
'@eslint/plugin-kit@0.5.1':
|
||||
dependencies:
|
||||
'@eslint/core': 1.0.1
|
||||
levn: 0.4.1
|
||||
|
||||
'@exodus/bytes@1.8.0': {}
|
||||
|
|
@ -13896,14 +13915,14 @@ snapshots:
|
|||
eslint-json-compat-utils@0.2.1(eslint@9.39.2(jiti@1.21.7))(jsonc-eslint-parser@2.4.2):
|
||||
dependencies:
|
||||
eslint: 9.39.2(jiti@1.21.7)
|
||||
esquery: 1.6.0
|
||||
esquery: 1.7.0
|
||||
jsonc-eslint-parser: 2.4.2
|
||||
|
||||
eslint-merge-processors@2.0.0(eslint@9.39.2(jiti@1.21.7)):
|
||||
dependencies:
|
||||
eslint: 9.39.2(jiti@1.21.7)
|
||||
|
||||
eslint-plugin-antfu@3.1.1(eslint@9.39.2(jiti@1.21.7)):
|
||||
eslint-plugin-antfu@3.1.3(eslint@9.39.2(jiti@1.21.7)):
|
||||
dependencies:
|
||||
eslint: 9.39.2(jiti@1.21.7)
|
||||
|
||||
|
|
@ -13914,20 +13933,18 @@ snapshots:
|
|||
|
||||
eslint-plugin-es-x@7.8.0(eslint@9.39.2(jiti@1.21.7)):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@1.21.7))
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@1.21.7))
|
||||
'@eslint-community/regexpp': 4.12.2
|
||||
eslint: 9.39.2(jiti@1.21.7)
|
||||
eslint-compat-utils: 0.5.1(eslint@9.39.2(jiti@1.21.7))
|
||||
|
||||
eslint-plugin-import-lite@0.4.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3):
|
||||
eslint-plugin-import-lite@0.5.0(eslint@9.39.2(jiti@1.21.7)):
|
||||
dependencies:
|
||||
eslint: 9.39.2(jiti@1.21.7)
|
||||
optionalDependencies:
|
||||
typescript: 5.9.3
|
||||
|
||||
eslint-plugin-jsdoc@61.7.1(eslint@9.39.2(jiti@1.21.7)):
|
||||
eslint-plugin-jsdoc@62.0.0(eslint@9.39.2(jiti@1.21.7)):
|
||||
dependencies:
|
||||
'@es-joy/jsdoccomment': 0.78.0
|
||||
'@es-joy/jsdoccomment': 0.79.0
|
||||
'@es-joy/resolve.exports': 1.2.0
|
||||
are-docs-informative: 0.0.2
|
||||
comment-parser: 1.4.1
|
||||
|
|
@ -13947,7 +13964,7 @@ snapshots:
|
|||
|
||||
eslint-plugin-jsonc@2.21.0(eslint@9.39.2(jiti@1.21.7)):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@1.21.7))
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@1.21.7))
|
||||
diff-sequences: 27.5.1
|
||||
eslint: 9.39.2(jiti@1.21.7)
|
||||
eslint-compat-utils: 0.6.5(eslint@9.39.2(jiti@1.21.7))
|
||||
|
|
@ -13960,9 +13977,9 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- '@eslint/json'
|
||||
|
||||
eslint-plugin-n@17.23.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3):
|
||||
eslint-plugin-n@17.23.2(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@1.21.7))
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@1.21.7))
|
||||
enhanced-resolve: 5.18.3
|
||||
eslint: 9.39.2(jiti@1.21.7)
|
||||
eslint-plugin-es-x: 7.8.0(eslint@9.39.2(jiti@1.21.7))
|
||||
|
|
@ -13977,10 +13994,9 @@ snapshots:
|
|||
|
||||
eslint-plugin-no-only-tests@3.3.0: {}
|
||||
|
||||
eslint-plugin-perfectionist@4.15.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3):
|
||||
eslint-plugin-perfectionist@5.3.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.46.1
|
||||
'@typescript-eslint/utils': 8.46.1(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)
|
||||
eslint: 9.39.2(jiti@1.21.7)
|
||||
natural-orderby: 5.0.0
|
||||
transitivePeerDependencies:
|
||||
|
|
@ -14108,8 +14124,8 @@ snapshots:
|
|||
|
||||
eslint-plugin-regexp@2.10.0(eslint@9.39.2(jiti@1.21.7)):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@1.21.7))
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@1.21.7))
|
||||
'@eslint-community/regexpp': 4.12.2
|
||||
comment-parser: 1.4.1
|
||||
eslint: 9.39.2(jiti@1.21.7)
|
||||
jsdoc-type-pratt-parser: 4.8.0
|
||||
|
|
@ -14133,7 +14149,7 @@ snapshots:
|
|||
|
||||
eslint-plugin-storybook@10.1.11(eslint@9.39.2(jiti@1.21.7))(storybook@9.1.17(@testing-library/dom@10.4.1)(vite@7.3.1(@types/node@18.15.0)(jiti@1.21.7)(sass@1.93.2)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@typescript-eslint/utils': 8.46.1(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)
|
||||
eslint: 9.39.2(jiti@1.21.7)
|
||||
storybook: 9.1.17(@testing-library/dom@10.4.1)(vite@7.3.1(@types/node@18.15.0)(jiti@1.21.7)(sass@1.93.2)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.2))
|
||||
transitivePeerDependencies:
|
||||
|
|
@ -14146,27 +14162,27 @@ snapshots:
|
|||
postcss: 8.5.6
|
||||
tailwindcss: 3.4.18(tsx@4.21.0)(yaml@2.8.2)
|
||||
|
||||
eslint-plugin-toml@0.12.0(eslint@9.39.2(jiti@1.21.7)):
|
||||
eslint-plugin-toml@1.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
|
||||
eslint: 9.39.2(jiti@1.21.7)
|
||||
eslint-compat-utils: 0.6.5(eslint@9.39.2(jiti@1.21.7))
|
||||
lodash: 4.17.21
|
||||
toml-eslint-parser: 0.10.1
|
||||
toml-eslint-parser: 1.0.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-plugin-unicorn@62.0.0(eslint@9.39.2(jiti@1.21.7)):
|
||||
dependencies:
|
||||
'@babel/helper-validator-identifier': 7.28.5
|
||||
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@1.21.7))
|
||||
'@eslint/plugin-kit': 0.3.5
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@1.21.7))
|
||||
'@eslint/plugin-kit': 0.4.1
|
||||
change-case: 5.4.4
|
||||
ci-info: 4.3.1
|
||||
clean-regexp: 1.0.0
|
||||
core-js-compat: 3.46.0
|
||||
eslint: 9.39.2(jiti@1.21.7)
|
||||
esquery: 1.6.0
|
||||
esquery: 1.7.0
|
||||
find-up-simple: 1.0.1
|
||||
globals: 16.5.0
|
||||
indent-string: 5.0.0
|
||||
|
|
@ -14186,7 +14202,7 @@ snapshots:
|
|||
|
||||
eslint-plugin-vue@10.7.0(@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))):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@1.21.7))
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@1.21.7))
|
||||
eslint: 9.39.2(jiti@1.21.7)
|
||||
natural-compare: 1.4.0
|
||||
nth-check: 2.1.1
|
||||
|
|
@ -14240,7 +14256,7 @@ snapshots:
|
|||
'@eslint/core': 0.17.0
|
||||
'@eslint/eslintrc': 3.3.1
|
||||
'@eslint/js': 9.39.2
|
||||
'@eslint/plugin-kit': 0.3.5
|
||||
'@eslint/plugin-kit': 0.4.1
|
||||
'@humanfs/node': 0.16.7
|
||||
'@humanwhocodes/module-importer': 1.0.1
|
||||
'@humanwhocodes/retry': 0.4.3
|
||||
|
|
@ -14597,6 +14613,8 @@ snapshots:
|
|||
|
||||
globals@16.5.0: {}
|
||||
|
||||
globals@17.0.0: {}
|
||||
|
||||
globrex@0.1.2: {}
|
||||
|
||||
goober@2.1.18(csstype@3.2.3):
|
||||
|
|
@ -17554,9 +17572,9 @@ snapshots:
|
|||
|
||||
toggle-selection@1.0.6: {}
|
||||
|
||||
toml-eslint-parser@0.10.1:
|
||||
toml-eslint-parser@1.0.3:
|
||||
dependencies:
|
||||
eslint-visitor-keys: 3.4.3
|
||||
eslint-visitor-keys: 5.0.0
|
||||
|
||||
totalist@3.0.1: {}
|
||||
|
||||
|
|
@ -17933,7 +17951,7 @@ snapshots:
|
|||
eslint-scope: 8.4.0
|
||||
eslint-visitor-keys: 4.2.1
|
||||
espree: 10.4.0
|
||||
esquery: 1.6.0
|
||||
esquery: 1.7.0
|
||||
semver: 7.7.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
|
@ -18096,7 +18114,7 @@ snapshots:
|
|||
yaml-eslint-parser@1.3.2:
|
||||
dependencies:
|
||||
eslint-visitor-keys: 3.4.3
|
||||
yaml: 2.8.1
|
||||
yaml: 2.8.2
|
||||
|
||||
yaml@1.10.2: {}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,12 @@ export type FetchOptionType = Omit<RequestInit, 'body'> & {
|
|||
}
|
||||
|
||||
const afterResponse204: AfterResponseHook = async (_request, _options, response) => {
|
||||
if (response.status === 204)
|
||||
return Response.json({ result: 'success' })
|
||||
if (response.status === 204) {
|
||||
return new Response(JSON.stringify({ result: 'success' }), {
|
||||
status: 200,
|
||||
headers: { 'Content-Type': ContentType.json },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export type ResponseError = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue