docs(web): update dev guide (#33815)

This commit is contained in:
Stephen Zhou
2026-03-20 17:23:17 +08:00
committed by GitHub
parent b0566b4193
commit ec8ff89dc1
10 changed files with 206 additions and 81 deletions

View File

@ -94,11 +94,6 @@ jobs:
find . -name "*.py" -type f -exec sed -i.bak -E 's/"([^"]+)" \| None/Optional["\1"]/g; s/'"'"'([^'"'"']+)'"'"' \| None/Optional['"'"'\1'"'"']/g' {} \;
find . -name "*.py.bak" -type f -delete
# mdformat breaks YAML front matter in markdown files. Add --exclude for directories containing YAML front matter.
- name: mdformat
run: |
uvx --python 3.13 mdformat . --exclude ".agents/skills/**"
- name: Setup web environment
if: steps.web-changes.outputs.any_changed == 'true'
uses: ./.github/actions/setup-web

View File

@ -6,19 +6,23 @@ NEXT_PUBLIC_EDITION=SELF_HOSTED
NEXT_PUBLIC_BASE_PATH=
# The base URL of console application, refers to the Console base URL of WEB service if console domain is
# different from api or web app domain.
# example: http://cloud.dify.ai/console/api
# example: https://cloud.dify.ai/console/api
NEXT_PUBLIC_API_PREFIX=http://localhost:5001/console/api
# The URL for Web APP, refers to the Web App base URL of WEB service if web app domain is different from
# console or api domain.
# example: http://udify.app/api
# example: https://udify.app/api
NEXT_PUBLIC_PUBLIC_API_PREFIX=http://localhost:5001/api
# Dev-only Hono proxy targets. The frontend keeps requesting http://localhost:5001 directly.
# When the frontend and backend run on different subdomains, set NEXT_PUBLIC_COOKIE_DOMAIN=1.
NEXT_PUBLIC_COOKIE_DOMAIN=
# Dev-only Hono proxy targets.
# The frontend keeps requesting http://localhost:5001 directly,
# the proxy server will forward the request to the target server,
# so that you don't need to run a separate backend server and use online API in development.
HONO_PROXY_HOST=127.0.0.1
HONO_PROXY_PORT=5001
HONO_CONSOLE_API_PROXY_TARGET=
HONO_PUBLIC_API_PROXY_TARGET=
# When the frontend and backend run on different subdomains, set NEXT_PUBLIC_COOKIE_DOMAIN=1.
NEXT_PUBLIC_COOKIE_DOMAIN=
# The API PREFIX for MARKETPLACE
NEXT_PUBLIC_MARKETPLACE_API_PREFIX=https://marketplace.dify.ai/api/v1

View File

@ -1,6 +1,6 @@
# Dify Frontend
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
This is a [Next.js] project, but you can dev with [vinext].
## Getting Started
@ -8,8 +8,11 @@ This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next
Before starting the web frontend service, please make sure the following environment is ready.
- [Node.js](https://nodejs.org)
- [pnpm](https://pnpm.io)
- [Node.js]
- [pnpm]
You can also use [Vite+] with the corresponding `vp` commands.
For example, use `vp install` instead of `pnpm install` and `vp test` instead of `pnpm run test`.
> [!TIP]
> It is recommended to install and enable Corepack to manage package manager versions automatically:
@ -19,7 +22,7 @@ Before starting the web frontend service, please make sure the following environ
> corepack enable
> ```
>
> Learn more: [Corepack](https://github.com/nodejs/corepack#readme)
> Learn more: [Corepack]
First, install the dependencies:
@ -27,31 +30,14 @@ First, install the dependencies:
pnpm install
```
Then, configure the environment variables. Create a file named `.env.local` in the current directory and copy the contents from `.env.example`. Modify the values of these environment variables according to your requirements:
Then, configure the environment variables.
Create a file named `.env.local` in the current directory and copy the contents from `.env.example`.
Modify the values of these environment variables according to your requirements:
```bash
cp .env.example .env.local
```
```txt
# For production release, change this to PRODUCTION
NEXT_PUBLIC_DEPLOY_ENV=DEVELOPMENT
# The deployment edition, SELF_HOSTED
NEXT_PUBLIC_EDITION=SELF_HOSTED
# The base URL of console application, refers to the Console base URL of WEB service if console domain is
# different from api or web app domain.
# example: http://cloud.dify.ai/console/api
NEXT_PUBLIC_API_PREFIX=http://localhost:5001/console/api
NEXT_PUBLIC_COOKIE_DOMAIN=
# The URL for Web APP, refers to the Web App base URL of WEB service if web app domain is different from
# console or api domain.
# example: http://udify.app/api
NEXT_PUBLIC_PUBLIC_API_PREFIX=http://localhost:5001/api
# SENTRY
NEXT_PUBLIC_SENTRY_DSN=
```
> [!IMPORTANT]
>
> 1. When the frontend and backend run on different subdomains, set NEXT_PUBLIC_COOKIE_DOMAIN=1. The frontend and backend must be under the same top-level domain in order to share authentication cookies.
@ -61,11 +47,16 @@ Finally, run the development server:
```bash
pnpm run dev
# or if you are using vinext which provides a better development experience
pnpm run dev:vinext
# (optional) start the dev proxy server so that you can use online API in development
pnpm run dev:proxy
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
Open <http://localhost:3000> with your browser to see the result.
You can start editing the file under folder `app`. The page auto-updates as you edit the file.
You can start editing the file under folder `app`.
The page auto-updates as you edit the file.
## Deploy
@ -91,7 +82,7 @@ pnpm run start --port=3001 --host=0.0.0.0
## Storybook
This project uses [Storybook](https://storybook.js.org/) for UI component development.
This project uses [Storybook] for UI component development.
To start the storybook server, run:
@ -99,19 +90,24 @@ To start the storybook server, run:
pnpm storybook
```
Open [http://localhost:6006](http://localhost:6006) with your browser to see the result.
Open <http://localhost:6006> with your browser to see the result.
## Lint Code
If your IDE is VSCode, rename `web/.vscode/settings.example.json` to `web/.vscode/settings.json` for lint code setting.
Then follow the [Lint Documentation](./docs/lint.md) to lint the code.
Then follow the [Lint Documentation] to lint the code.
## Test
We use [Vitest](https://vitest.dev/) and [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) for Unit Testing.
We use [Vitest] and [React Testing Library] for Unit Testing.
**📖 Complete Testing Guide**: See [web/testing/testing.md](./testing/testing.md) for detailed testing specifications, best practices, and examples.
**📖 Complete Testing Guide**: See [web/docs/test.md] for detailed testing specifications, best practices, and examples.
> [!IMPORTANT]
> As we are using Vite+, the `vitest` command is not available.
> Please make sure to run tests with `vp` commands.
> For example, use `npx vp test` instead of `npx vitest`.
Run test:
@ -119,12 +115,17 @@ Run test:
pnpm test
```
> [!NOTE]
> Our test is not fully stable yet, and we are actively working on improving it.
> If you encounter test failures only in CI but not locally, please feel free to ignore them and report the issue to us.
> You can try to re-run the test in CI, and it may pass successfully.
### Example Code
If you are not familiar with writing tests, refer to:
- [classnames.spec.ts](./utils/classnames.spec.ts) - Utility function test example
- [index.spec.tsx](./app/components/base/button/index.spec.tsx) - Component test example
- [classnames.spec.ts] - Utility function test example
- [index.spec.tsx] - Component test example
### Analyze Component Complexity
@ -134,7 +135,7 @@ Before writing tests, use the script to analyze component complexity:
pnpm analyze-component app/components/your-component/index.tsx
```
This will help you determine the testing strategy. See [web/testing/testing.md](./testing/testing.md) for details.
This will help you determine the testing strategy. See [web/testing/testing.md] for details.
## Documentation
@ -142,4 +143,19 @@ Visit <https://docs.dify.ai> to view the full documentation.
## Community
The Dify community can be found on [Discord community](https://discord.gg/5AEfbxcd9k), where you can ask questions, voice ideas, and share your projects.
The Dify community can be found on [Discord community], where you can ask questions, voice ideas, and share your projects.
[Corepack]: https://github.com/nodejs/corepack#readme
[Discord community]: https://discord.gg/5AEfbxcd9k
[Lint Documentation]: ./docs/lint.md
[Next.js]: https://nextjs.org
[Node.js]: https://nodejs.org
[React Testing Library]: https://testing-library.com/docs/react-testing-library/intro
[Storybook]: https://storybook.js.org
[Vite+]: https://viteplus.dev
[Vitest]: https://vitest.dev
[classnames.spec.ts]: ./utils/classnames.spec.ts
[index.spec.tsx]: ./app/components/base/button/index.spec.tsx
[pnpm]: https://pnpm.io
[vinext]: https://github.com/cloudflare/vinext
[web/docs/test.md]: ./docs/test.md

View File

@ -12,25 +12,44 @@ We use ESLint and Typescript to maintain code quality and consistency across the
pnpm eslint [options] file.js [file.js] [dir]
```
**`--cache`**: Caches lint results for faster subsequent runs. Keep this enabled by default; only disable when you encounter unexpected lint results.
**`--cache`**: Caches lint results for faster subsequent runs.
Keep this enabled by default; only disable when you encounter unexpected lint results.
**`--concurrency`**: Enables multi-threaded linting. Use `--concurrency=auto` or experiment with specific numbers to find the optimal setting for your machine. Keep this enabled when linting multiple files.
**`--concurrency`**: Enables multi-threaded linting.
Use `--concurrency=auto` or experiment with specific numbers to find the optimal setting for your machine.
Keep this enabled when linting multiple files.
- [ESLint multi-thread linting blog post](https://eslint.org/blog/2025/08/multithread-linting/)
- [ESLint multi-thread linting blog post]
**`--fix`**: Automatically fixes auto-fixable rule violations. Always review the diff before committing to ensure no unintended changes.
**`--fix`**: Automatically fixes auto-fixable rule violations.
Keep this enabled so that you do not have to care about auto-fixable errors (e.g., formatting issues) and can focus on more important errors.
Always review the diff before committing to ensure no unintended changes.
**`--quiet`**: Suppresses warnings and only shows errors. Useful when you want to reduce noise from existing issues.
**`--quiet`**: Suppresses warnings and only shows errors.
Useful when you want to reduce noise from existing warnings.
**`--suppress-all`**: Temporarily suppresses error-level violations and records them, allowing CI to pass. Treat this as an escape hatch—fix these errors when time permits.
**`--suppress-all`**: Temporarily suppresses error-level violations and records them, allowing CI to pass.
Treat this as an escape hatch—fix these errors when time permits.
**`--prune-suppressions`**: Removes outdated suppressions after you've fixed the underlying errors.
- [ESLint bulk suppressions blog post](https://eslint.org/blog/2025/04/introducing-bulk-suppressions/)
- [ESLint bulk suppressions blog post]
### The Auto-Fix Workflow and Suppression Strategy
To streamline your development process, we recommend configuring your editor to automatically fix lint errors on save.
As a fallback, any remaining autofixable errors will be corrected automatically when you commit.
To prevent workflow disruptions, these commit hooks are intentionally bypassed when you are merging branches, rebasing, or cherry-picking.
Additionally, we currently track many existing legacy errors in eslint-suppressions.json.
You do not need to spend time manually pruning these suppressions (we already append `--pass-on-unpruned-suppressions` in the commit hook);
once you open a Pull Request, the CI pipeline will automatically handle the cleanup for you.
### Type-Aware Linting
Some ESLint rules require type information, such as [no-leaked-conditional-rendering](https://www.eslint-react.xyz/docs/rules/no-leaked-conditional-rendering). However, [typed linting via typescript-eslint](https://typescript-eslint.io/getting-started/typed-linting) is too slow for practical use, so we use [TSSLint](https://github.com/johnsoncodehk/tsslint) instead.
Some ESLint rules require type information, such as [no-leaked-conditional-rendering].
However, [typed linting via typescript-eslint] is too slow for practical use.
So we use [TSSLint] instead.
```sh
pnpm lint:tss
@ -43,7 +62,7 @@ This command lints the entire project and is intended for final verification bef
If a new rule causes many existing code errors or automatic fixes generate too many diffs, do not use the `--fix` option for automatic fixes.
You can introduce the rule first, then use the `--suppress-all` option to temporarily suppress these errors, and gradually fix them in subsequent changes.
For overlay migration policy and cleanup phases, see [Overlay Migration Guide](./overlay-migration.md).
For overlay migration policy and cleanup phases, see [Overlay Migration Guide].
## Type Check
@ -55,4 +74,12 @@ However, it can be useful to run the TypeScript 7 command-line (tsgo) to type ch
pnpm type-check:tsgo
```
Prefer using `tsgo` for type checking as it is significantly faster than the standard TypeScript compiler. Only fall back to `pnpm type-check` (which uses `tsc`) if you encounter unexpected results.
Prefer using `tsgo` for type checking as it is significantly faster than the standard TypeScript compiler.
Only fall back to `pnpm type-check` (which uses `tsc`) if you encounter unexpected results.
[ESLint bulk suppressions blog post]: https://eslint.org/blog/2025/04/introducing-bulk-suppressions
[ESLint multi-thread linting blog post]: https://eslint.org/blog/2025/08/multithread-linting
[Overlay Migration Guide]: ./overlay-migration.md
[TSSLint]: https://github.com/johnsoncodehk/tsslint
[no-leaked-conditional-rendering]: https://www.eslint-react.xyz/docs/rules/no-leaked-conditional-rendering
[typed linting via typescript-eslint]: https://typescript-eslint.io/getting-started/typed-linting

View File

@ -23,7 +23,7 @@ This document tracks the migration away from legacy overlay APIs.
- `@/app/components/base/ui/alert-dialog`
- `@/app/components/base/ui/select`
- `@/app/components/base/ui/toast`
- Tracking issue: https://github.com/langgenius/dify/issues/32767
- Tracking issue: <https://github.com/langgenius/dify/issues/32767>
## ESLint policy
@ -72,14 +72,14 @@ All new overlay primitives in `base/ui/` share a single z-index value:
During the migration period, legacy and new overlays coexist. Legacy overlays
portal to `document.body` with explicit z-index values:
| Layer | z-index | Components |
|-------|---------|------------|
| Legacy Drawer | `z-[30]` | `base/drawer` |
| Legacy Modal | `z-[60]` | `base/modal` (default) |
| Legacy PortalToFollowElem callers | up to `z-[1001]` | various business components |
| **New UI primitives** | **`z-[1002]`** | `base/ui/*` (Popover, Dialog, Tooltip, etc.) |
| Legacy Modal (highPriority) | `z-[1100]` | `base/modal` (`highPriority={true}`) |
| Toast (legacy + new) | `z-[1101]` | `base/toast`, `base/ui/toast` |
| Layer | z-index | Components |
| --------------------------------- | ---------------- | -------------------------------------------- |
| Legacy Drawer | `z-[30]` | `base/drawer` |
| Legacy Modal | `z-[60]` | `base/modal` (default) |
| Legacy PortalToFollowElem callers | up to `z-[1001]` | various business components |
| **New UI primitives** | **`z-[1002]`** | `base/ui/*` (Popover, Dialog, Tooltip, etc.) |
| Legacy Modal (highPriority) | `z-[1100]` | `base/modal` (`highPriority={true}`) |
| Toast (legacy + new) | `z-[1101]` | `base/toast`, `base/ui/toast` |
`z-[1002]` sits above all common legacy overlays, so new primitives always
render on top without needing per-call-site z-index hacks. Among themselves,

View File

@ -119,13 +119,11 @@ When assigned to test a **directory/path** (not just a single file), follow thes
Choose based on directory complexity:
1. **Single spec file (Integration approach)** - Preferred for related components
- Minimize mocking - use real project components
- Test actual integration between components
- Only mock: API calls, complex context providers, third-party libs
1. **Multiple spec files (Unit approach)** - For complex directories
- One spec file per component/hook/utility
- More isolated testing
- Useful when components are independent
@ -139,7 +137,7 @@ When using a single spec file:
-**DO NOT mock** base components (`@/app/components/base/*`)
-**DO NOT mock** sibling/child components in the same directory
> See [Example Structure](#example-structure) for correct import/mock patterns.
> See [Example Structure] for correct import/mock patterns.
## Testing Components with Dedicated Dependencies
@ -185,8 +183,8 @@ Treat component state as part of the public behavior: confirm the initial render
- ✅ When creating lightweight provider stubs, mirror the real default values and surface helper builders (for example `createMockWorkflowContext`).
- ✅ Reset shared stores (React context, Zustand, TanStack Query cache) between tests to avoid leaking state. Prefer helper factory functions over module-level singletons in specs.
- ✅ For hooks that read from context, use `renderHook` with a custom wrapper that supplies required providers.
-**Use factory functions for mock data**: Import actual types and create factory functions with complete defaults (see [Test Data Builders](#9-test-data-builders-anti-hardcoding) section).
- ✅ If it's need to mock some common context provider used across many components (for example, `ProviderContext`), put it in __mocks__/context(for example, `__mocks__/context/provider-context`). To dynamically control the mock behavior (for example, toggling plan type), use module-level variables to track state and change them(for example, `context/provider-context-mock.spec.tsx`).
-**Use factory functions for mock data**: Import actual types and create factory functions with complete defaults (see [Test Data Builders] section).
- ✅ If it's need to mock some common context provider used across many components (for example, `ProviderContext`), put it in **mocks**/context(for example, `__mocks__/context/provider-context`). To dynamically control the mock behavior (for example, toggling plan type), use module-level variables to track state and change them(for example, `context/provider-context-mock.spec.tsx`).
- ✅ Use factory functions to create mock data with TypeScript types. This ensures type safety and makes tests more maintainable.
**Rules**:
@ -363,7 +361,6 @@ describe('ComponentName', () => {
1. **i18n**: Uses global mock in `web/vitest.setup.ts` (auto-loaded by Vitest setup)
The global mock provides:
- `useTranslation` - returns translation keys with namespace prefix
- `Trans` component - renders i18nKey and components
- `useMixedTranslation` (from `@/app/components/plugins/marketplace/hooks`)
@ -533,16 +530,25 @@ const element = await screen.findByText('Async Content')
Test examples in the project:
- [classnames.spec.ts](../utils/classnames.spec.ts) - Utility function tests
- [index.spec.tsx](../app/components/base/button/index.spec.tsx) - Component tests
- [classnames.spec.ts] - Utility function tests
- [index.spec.tsx] - Component tests
## Resources
- [Vitest Documentation](https://vitest.dev/guide/)
- [React Testing Library Documentation](https://testing-library.com/docs/react-testing-library/intro/)
- [Testing Library Best Practices](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library)
- [Vitest Mocking Guide](https://vitest.dev/guide/mocking.html)
- [Vitest Documentation]
- [React Testing Library Documentation]
- [Testing Library Best Practices]
- [Vitest Mocking Guide]
______________________________________________________________________
---
**Remember**: Writing tests is not just about coverage, but ensuring code quality and maintainability. Good tests should be clear, concise, and meaningful.
[Example Structure]: #example-structure
[React Testing Library Documentation]: https://testing-library.com/docs/react-testing-library/intro
[Test Data Builders]: #9-test-data-builders-anti-hardcoding
[Testing Library Best Practices]: https://kentcdodds.com/blog/common-mistakes-with-react-testing-library
[Vitest Documentation]: https://vitest.dev/guide
[Vitest Mocking Guide]: https://vitest.dev/guide/mocking.html
[classnames.spec.ts]: ../utils/classnames.spec.ts
[index.spec.tsx]: ../app/components/base/button/index.spec.tsx

View File

@ -1,8 +1,11 @@
// @ts-check
import antfu, { GLOB_TESTS, GLOB_TS, GLOB_TSX, isInEditorEnv, isInGitHooksOrLintStaged } from '@antfu/eslint-config'
import antfu, { GLOB_MARKDOWN, GLOB_TESTS, GLOB_TS, GLOB_TSX, isInEditorEnv, isInGitHooksOrLintStaged } from '@antfu/eslint-config'
import pluginQuery from '@tanstack/eslint-plugin-query'
import md from 'eslint-markdown'
import tailwindcss from 'eslint-plugin-better-tailwindcss'
import hyoban from 'eslint-plugin-hyoban'
import markdownPreferences from 'eslint-plugin-markdown-preferences'
import sonar from 'eslint-plugin-sonarjs'
import storybook from 'eslint-plugin-storybook'
import {
@ -56,6 +59,26 @@ export default antfu(
},
e18e: false,
},
markdownPreferences.configs.standard,
{
files: [GLOB_MARKDOWN],
plugins: { md },
rules: {
'md/no-url-trailing-slash': 'error',
'markdown-preferences/prefer-link-reference-definitions': [
'error',
{
minLinks: 1,
},
],
'markdown-preferences/ordered-list-marker-sequence': [
'error',
{ increment: 'never' },
],
'markdown-preferences/definitions-last': 'error',
'markdown-preferences/sort-definitions': 'error',
},
},
{
rules: {
'node/prefer-global/process': 'off',

View File

@ -41,7 +41,7 @@ cd web/i18n
cp -r en-US id-ID
```
2. Modify the translation `.json` files in the new folder. Keep keys flat (for example, `dialog.title`).
1. Modify the translation `.json` files in the new folder. Keep keys flat (for example, `dialog.title`).
1. Add the new language to the `languages.ts` file.
@ -143,10 +143,10 @@ export const languages = [
]
```
4. Don't forget to mark the supported field as `true` if the language is supported.
1. Don't forget to mark the supported field as `true` if the language is supported.
1. Sometimes you might need to do some changes in the server side. Please change this file as well. 👇
https://github.com/langgenius/dify/blob/61e4bbabaf2758354db4073cbea09fdd21a5bec1/api/constants/languages.py#L5
<https://github.com/langgenius/dify/blob/61e4bbabaf2758354db4073cbea09fdd21a5bec1/api/constants/languages.py#L5>
> Note: `I18nText` type is automatically derived from `LanguagesSupported`, so you don't need to manually add types.

View File

@ -216,8 +216,10 @@
"autoprefixer": "10.4.27",
"code-inspector-plugin": "1.4.4",
"eslint": "10.0.3",
"eslint-markdown": "0.6.0",
"eslint-plugin-better-tailwindcss": "4.3.2",
"eslint-plugin-hyoban": "0.14.1",
"eslint-plugin-markdown-preferences": "0.40.3",
"eslint-plugin-react-hooks": "7.0.1",
"eslint-plugin-react-refresh": "0.5.2",
"eslint-plugin-sonarjs": "4.0.2",

52
web/pnpm-lock.yaml generated
View File

@ -530,12 +530,18 @@ importers:
eslint:
specifier: 10.0.3
version: 10.0.3(jiti@1.21.7)
eslint-markdown:
specifier: 0.6.0
version: 0.6.0(eslint@10.0.3(jiti@1.21.7))
eslint-plugin-better-tailwindcss:
specifier: 4.3.2
version: 4.3.2(eslint@10.0.3(jiti@1.21.7))(oxlint@1.55.0(oxlint-tsgolint@0.17.0))(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2))(typescript@5.9.3)
eslint-plugin-hyoban:
specifier: 0.14.1
version: 0.14.1(eslint@10.0.3(jiti@1.21.7))
eslint-plugin-markdown-preferences:
specifier: 0.40.3
version: 0.40.3(@eslint/markdown@7.5.1)(eslint@10.0.3(jiti@1.21.7))
eslint-plugin-react-hooks:
specifier: 7.0.1
version: 7.0.1(eslint@10.0.3(jiti@1.21.7))
@ -4763,6 +4769,15 @@ packages:
'@eslint/json':
optional: true
eslint-markdown@0.6.0:
resolution: {integrity: sha512-NrgfiNto5IJrW1F/Akf2hJYoJTCbXoClOUvtUMDgoqmQNH0VRihNvFh+MFay4E0HV2eozfgxsLSGxnndtRJA8w==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0}
peerDependencies:
eslint: ^9.31.0 || ^10.0.0-rc.0
peerDependenciesMeta:
eslint:
optional: true
eslint-merge-processors@2.0.0:
resolution: {integrity: sha512-sUuhSf3IrJdGooquEUB5TNpGNpBoQccbnaLHsb1XkBLUPPqCNivCpY05ZcpCOiV9uHwO2yxXEWVczVclzMxYlA==}
peerDependencies:
@ -4828,6 +4843,13 @@ packages:
peerDependencies:
eslint: '>=9.38.0'
eslint-plugin-markdown-preferences@0.40.3:
resolution: {integrity: sha512-R3CCAEFwnnYXukTdtvdsamGjbTgVs9UZKqMKhNeWNXzFtOP1Frc89bgbd56lJUN7ASaxgvzc5fUpKvDCOTtDpg==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
peerDependencies:
'@eslint/markdown': ^7.4.0
eslint: '>=9.0.0'
eslint-plugin-n@17.24.0:
resolution: {integrity: sha512-/gC7/KAYmfNnPNOb3eu8vw+TdVnV0zhdQwexsw6FLXbhzroVj20vRn2qL8lDWDGnAQ2J8DhdfvXxX9EoxvERvw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@ -12142,6 +12164,16 @@ snapshots:
esquery: 1.7.0
jsonc-eslint-parser: 3.1.0
eslint-markdown@0.6.0(eslint@10.0.3(jiti@1.21.7)):
dependencies:
'@eslint/markdown': 7.5.1
micromark-util-normalize-identifier: 2.0.1
parse5: 8.0.0
optionalDependencies:
eslint: 10.0.3(jiti@1.21.7)
transitivePeerDependencies:
- supports-color
eslint-merge-processors@2.0.0(eslint@10.0.3(jiti@1.21.7)):
dependencies:
eslint: 10.0.3(jiti@1.21.7)
@ -12233,6 +12265,26 @@ snapshots:
transitivePeerDependencies:
- '@eslint/json'
eslint-plugin-markdown-preferences@0.40.3(@eslint/markdown@7.5.1)(eslint@10.0.3(jiti@1.21.7)):
dependencies:
'@eslint/markdown': 7.5.1
diff-sequences: 29.6.3
emoji-regex-xs: 2.0.1
eslint: 10.0.3(jiti@1.21.7)
mdast-util-from-markdown: 2.0.3
mdast-util-frontmatter: 2.0.1
mdast-util-gfm: 3.1.0
mdast-util-math: 3.0.0
micromark-extension-frontmatter: 2.0.0
micromark-extension-gfm: 3.0.0
micromark-extension-math: 3.1.0
micromark-factory-space: 2.0.1
micromark-util-character: 2.1.1
micromark-util-symbol: 2.0.1
string-width: 8.2.0
transitivePeerDependencies:
- supports-color
eslint-plugin-n@17.24.0(eslint@10.0.3(jiti@1.21.7))(typescript@5.9.3):
dependencies:
'@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@1.21.7))